COMMAND

    muh

SYSTEMS AFFECTED

    muh

PROBLEM

    Maxime Henrion found following.  muh is an IRC bouncer, a  program
    that will allow you to use any host you have a shell on as a relay
    between you and IRC.   Moreover, muh stays connected when  you are
    not, and can log any message you receive.

    The  latest  version,  2.05d  (and  probably other versions...) is
    vulnerable to a format  string bug which can  be used to make  muh
    crash and  probably to  gain the  privileges of  the user  running
    muh.

    Looking at the source code which display the message log in muh.c:

        irc_notice( &c_client, status.nickname, CLNT_MSGLOGSTART );

        s = ( char * )malloc( 1024 );
        while( fgets( s, 1023, messagelog ) ) {
	        if( s[ strlen( s ) - 1 ] == '\n' ) s[ strlen( s ) - 1 ] = 0;
	        irc_notice( &c_client, status.nickname, s );
        }
        FREESTRING( s );

        irc_notice( &c_client, status.nickname, CLNT_MSGLOGEND );

    The bad  thing is  "irc_notice( &c_client,  status.nickname, s );"
    because  if  you  look  at  the  declaration  of  the irc_notice()
    function  in  irc.c,  you  can  see  that the third parameter is a
    format string and so, user data  is supplied to the function as  a
    format string.

        void irc_notice( connection_type *connection, char nickname[], char *format, ... )

    You can so easily make muh crash by sending some "%s%s%s%d..."  to
    someone using muh but not connected right now.  When the user will
    reconnect to  muh and  execute /muh  read, it  will crash.   As  a
    temporary solution, you can disable logging.

SOLUTION

    Patch: replace the line:

        irc_notice( &c_client, status.nickname, s );

    by this one:

        irc_notice( &c_client, status.nickname, "%s", s );

    Actually there were a couple  of other bad-looking ones that  Kris
    from FreeBSD patched in FreeBSD:

    --- src/muh.c.orig	Sun Mar 19 04:08:27 2000
    +++ src/muh.c	Sat Sep  9 21:32:15 2000
    @@ -575,7 +575,7 @@
                     if( strcmp( param2 + 2, "USERINFO\1" ) == 0 )
                         irc_notice( &c_server, nick, USERINFOREPLY );
                     if( strncmp( param2 + 2, "PING", 4 ) == 0 ) {
    -                    if( strlen( param2 + 1 ) > 6 ) irc_notice( &c_server, nick, param2 + 1 );
    +                    if( strlen( param2 + 1 ) > 6 ) irc_notice( &c_server, nick, "%s", param2 + 1 );
                     }
                     if( strcmp( param2 + 2, "CLIENTINFO\1" ) == 0 )
                         irc_notice( &c_server, nick, CLIENTINFOREPLY );
    @@ -591,7 +591,7 @@
             }
             else { /* normale message/notice */
                 if( !is_ignore( hostname, IGNORE_MESSAGE ) && status.allowreply ) {
    -                if( cfg.awaynotice ) irc_notice( &c_server, nick, cfg.awaynotice );
    +                if( cfg.awaynotice ) irc_notice( &c_server, nick, "%s", cfg.awaynotice );
                     add_ignore( hostname, 120, IGNORE_MESSAGE );
                     status.allowreply = 0;
                     timers.reply = 0;
    @@ -841,7 +841,7 @@
                 s = ( char * )malloc( 1024 );
                 while( fgets( s, 1023, messagelog ) ) {
                     if( s[ strlen( s ) - 1 ] == '\n' ) s[ strlen( s ) - 1 ] = 0;
    -                irc_notice( &c_client, status.nickname, s );
    +                irc_notice( &c_client, status.nickname, "%s", s );
                 }
                 FREESTRING( s );

    Patches are:

        ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-3-stable/irc/muh-2.05c.tgz
        ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-4-stable/irc/muh-2.05c.tgz
        ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/alpha/packages-4-stable/irc/muh-2.05c.tgz
        ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-5-current/irc/muh-2.05c.tgz
        ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/alpha/packages-5-current/irc/muh-2.05c.tgz