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