📦 NFS

What is it?

  • Concept: NFS (Network File System) is the Unix world’s standard remote filesystem — a server exports a directory and clients mount it so that applications read and write over the network as if the files were local. Its defining property, and the source of every finding below, is that the protocol has no concept of a user session. There is no login. A client simply asserts a numeric UID/GID with each request, and the server decides based on the client’s network address whether to listen.
  • Impact: An over-broad export is unauthenticated data disclosure to anyone who can route to the port. Depending on the export options it also yields UID impersonation (read any file on the share) and, with no_root_squash, arbitrary root-owned file creation — a reliable local privilege-escalation primitive.

How it works

  1. rpcbind listens on 111 and acts as a directory: clients ask it which port a given RPC program number is on. 100003 is nfs, 100005 is mountd, 100021 is nlockmgr, 100024 is status.
  2. mountd owns the export list, read from /etc/exports. Each line is <path> <client>(<options>) — the middle field is a host specification, which is the entire access-control mechanism.
  3. nfsd serves the file operations on 2049. In NFSv4 the mount protocol is folded into this single port, which is why a v4-only server may not answer showmount at all.
  4. Identity on the wire is a bare UID/GID pair (AUTH_SYS). The server compares those integers against file ownership. Nothing verifies that the client is entitled to claim them.
  5. root_squash — on by default — remaps incoming UID 0 to nobody. It is a mapping rule layered on top of the trust model, not a replacement for it.

Port / Program Reference

ProgramNumberPortRole
rpcbind100000111Port directory for every other RPC service
nfs1000032049The file operations themselves
mountd100005dynamicServes the export list and grants mount handles
nlockmgr100021dynamicNFSv3 file locking
status100024dynamicLock-recovery notification

The dynamic ports are why rpcbind on 111 matters so much on a scan — without it the rest is unfindable.

Security Quirks & Niche Facts

  • * in the client column is the whole vulnerability. It reads as an innocuous wildcard in a config file and means “the internet”. See NFS - Anonymous Share Mounting.
  • UID collision is a feature of AUTH_SYS, not a bug you exploit. Creating a local user with a matching UID is the intended way the protocol establishes identity; there is simply nothing preventing an attacker from doing it too.
  • root_squash protects UID 0 and nothing else. A file owned by UID 1004 is fully reachable by anyone willing to useradd -u 1004, and no squash option in common use prevents that.
  • NFSv4 idmapping silently hides ownership. When client and server disagree on the NFSv4 domain, every file shows as nobody:nobody — this looks like a permissions failure but is a naming artefact. Mounting -o vers=3 sidesteps it during enumeration.
  • showmount returning nothing is not proof of nothing. mountd sits on a dynamic port that is frequently firewalled while 2049 stays open; a known or guessed export path can still be mounted directly.
  • Exports outlive their purpose. They are stood up for a one-off task — an onboarding pack, a migration, a backup target — and then never removed, so their contents skew heavily towards documents nobody remembers publishing.
  • ls -l lies on an NFS mount. Usernames are resolved from the client’s /etc/passwd, so always read ownership numerically with ls -lan.

Notes

  • Fast triage from a scan: an rpcinfo block naming 100003 and 100005 means showmount -e is the immediate next command, before any web enumeration.
  • mount needs root on the attacking box; there is no unprivileged fallback short of a userspace NFS client.
  • Always umount before moving on. A stale mount pointing at a retired lab machine will hang shell tab-completion and df for minutes.

Mitigation

  • Fix: Scope every export to explicit hosts or subnets — never * — and firewall 111 and 2049 so the host-based rule cannot simply be reached from elsewhere.
  • Keep root_squash; add all_squash with a dedicated anonuid/anongid for anything intentionally shared, and mount data-only exports noexec,nosuid.
  • Move to NFSv4 with sec=krb5p, which replaces asserted UIDs with Kerberos authentication and encrypts traffic in transit.
  • Audit exports on a schedule and treat their contents as published: no credentials, no key material, no HR or onboarding documents.
FileCreated
HTB Machine - EnigmaSeptember 07, 2026

References: