9.3 Network File System (NFS) & RPC Services Assessment
Key Takeaways
- ONC RPC relies on the portmapper (rpcbind) on TCP/UDP port 111 to dynamically assign and publish listening ports for RPC-based daemons such as mountd, nfs, and status.
- Network File System (NFS) exports defined in /etc/exports and enumerated via showmount -e expose file systems across the network, relying by default in NFSv2/v3 on AUTH_SYS client-asserted UIDs with zero cryptographic verification.
- The no_root_squash configuration option is a critical misconfiguration that allows a client connecting with local root (UID 0) to retain superuser authority on the server, directly enabling SUID binary injection and local privilege escalation.
- Modern NFSv4 consolidates communication onto standard TCP port 2049, eliminates reliance on the portmapper, and supports cryptographically strong authentication and integrity via RPCSEC_GSS and Kerberos.
9.3 Network File System (NFS) & RPC Services Assessment
The Network File System (NFS), originally developed by Sun Microsystems in 1984, remains a foundational distributed file system protocol in Unix and Linux enterprise networks. Designed to enable transparent access to remote files over local area networks, NFS operates upon the Open Network Computing Remote Procedure Call (ONC RPC) framework. In penetration testing, NFS and its associated RPC daemons represent a frequent vector for data exfiltration, user impersonation, and root privilege escalation due to legacy trust models and permissive export configurations.
ONC RPC Architecture & The Portmapper
Open Network Computing Remote Procedure Call (ONC RPC, standardized in RFC 1831 and RFC 5531) is a message-passing architecture that enables an application to execute subroutines on a remote host as if they were local procedure calls.
Client Application Server Host
| |
|--- 1. Query Portmapper (TCP/UDP 111) --------->| (rpcbind)
|<-- 2. Returns dynamic port for mountd (45123) -|
|
|--- 3. Interrogate mountd (Port 45123) -------->| (Validates export)
|<-- 4. Returns File Handle ---------------------|
|
|--- 5. Read/Write Data via nfsd (Port 2049) --->| (File Operations)
|<-- 6. Returns Data Blocks ---------------------|
The RPC Identification Triad
Every RPC-compliant service is registered and addressed via three identifiers:
- Program Number: A unique 32-bit integer assigned to the service (e.g.,
100000for Portmapper,100003for NFS,100005formountd). - Version Number: Indicates protocol version support (e.g., NFS versions 2, 3, or 4).
- Procedure Number: Designates the specific functional operation requested (e.g.,
NFSPROC3_GETATTR,NFSPROC3_LOOKUP).
The Portmapper (rpcbind / portmap, TCP/UDP Port 111)
Because the underlying operating system cannot dedicate fixed, well-known port numbers to every possible RPC daemon, helper services (such as mountd, statd, and nlockmgr) bind to dynamically allocated ephemeral ports upon startup.
The Portmapper (listening on TCP/UDP port 111) serves as the centralized directory service. When an RPC daemon initializes, it registers its program number, supported version, transport protocol, and assigned port number with the Portmapper. When an RPC client requires communication with a service, it first queries port 111 to obtain the listening port of the destination daemon.
RPC Enumeration with rpcinfo
Penetration testers interrogate the Portmapper using the rpcinfo utility to enumerate all active RPC services, exposing potential attack surfaces:
rpcinfo -p 192.168.1.50
program vers proto port service
100000 4 tcp 111 portmapper
100000 3 udp 111 portmapper
100024 1 udp 38452 status
100024 1 tcp 52145 status
100005 1 udp 40123 mountd
100005 3 tcp 40123 mountd
100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100021 4 udp 48921 nlockmgr
100004 2 udp 785 ypserv
Common High-Value RPC Programs:
100003(nfs): Network File System service.100005(mountd): Processes incoming mount requests and validates filesystem export permissions.100004(ypserv/ NIS): Network Information Service (Yellow Pages). If exposed, unauthenticated NIS queries (ypwhich,ypcat -d <domain> passwd.byname) can dump internal user account databases and password hashes.100024(status/rpc.statd): Implements the Network Status Monitor (NSM) protocol. Older implementations contain notorious remote format string vulnerabilities (e.g., CVE-2000-0666).
Network File System (NFS) Architecture & Versions
NFS has evolved across multiple standard specifications:
| NFS Version | RFC Standard | Transport Protocols | Port Requirements | State Model & Locking |
|---|---|---|---|---|
| NFSv2 | RFC 1094 | UDP primarily (TCP optional) | Port 2049 + dynamic helper ports | Stateless; external lock manager (nlmsvc) |
| NFSv3 | RFC 1813 | TCP and UDP | Port 2049 + dynamic helper ports | Stateless; 64-bit file sizes, safe asynchronous writes |
| NFSv4 | RFC 7530 | TCP exclusively | Port 2049 strictly | Stateful; integrated compound RPC calls, no portmapper required |
NFSv4 Architectural Overhaul
Unlike legacy NFSv2 and NFSv3—which rely heavily on the Portmapper and dynamic ports for mountd and lockd—NFSv4 operates entirely over a single well-known port: TCP port 2049. It eliminates the necessity of exposing port 111, simplifies perimeter firewall traversal, and embeds file locking, mounting, and access control directly into the core NFS protocol.
Share Enumeration and Export Configuration
On the NFS server, exported filesystems and access control policies are defined in /etc/exports and drop-in configurations within /etc/exports.d/.
Server Configuration Syntax (/etc/exports)
/export/path client_specification(options)
# World-accessible read-write export with dangerous root mapping
/srv/shared *(rw,sync,no_root_squash,no_subtree_check)
# Subnet-restricted export with standard root squashing
/opt/backups 192.168.1.0/24(ro,sync,root_squash)
# Development export squashing all users to an anonymous UID
/var/www/html 10.10.50.15(rw,sync,all_squash,anonuid=1001,anongid=1001)
Remote Enumeration with showmount
Penetration testers probe target hosts for exported filesystems using showmount:
# Enumerate exported shares and permitted client ACLs
showmount -e 192.168.1.50
# Export list for 192.168.1.50:
# /srv/shared *
# /opt/backups 192.168.1.0/24
# Enumerate active client mount associations
showmount -a 192.168.1.50
Mounting an NFS Export
Once an export is identified, the client mounts the remote filesystem to a local mount point:
mkdir -p /mnt/nfs_target
mount -t nfs 192.168.1.50:/srv/shared /mnt/nfs_target -o nolock,vers=3
The -o nolock option disables file locking via nlockmgr, which is essential if intermediate firewalls block ephemeral RPC ports.
NFS Security Options & Privilege Escalation
The security of an NFS export is dictated by the export options configured in /etc/exports. Misconfigurations in these options frequently provide direct paths to root compromise.
Attacker (Root on Client, UID 0) ---> Mounts Share with 'no_root_squash'
|
v
Copies /bin/bash to NFS Share
|
v
chmod 4755 /mnt/nfs/rootbash
(Sets SUID bit, Owned by Server Root, UID 0)
|
v
Target Host (Unprivileged User Account)
|
v
Executes /srv/shared/rootbash -p
|
v
Interactive Root Shell (#)
1. root_squash vs no_root_squash
root_squash(Default Secure Behavior): When a remote client connects to the share using local UID 0 (root), the NFS server's kernel automatically maps (squashes) the request to an unprivileged anonymous identity—typicallynobodyornfsnobody(UID 65534). This prevents remote administrators from modifying sensitive root-owned files or injecting administrative configurations.no_root_squash(CRITICAL Vulnerability): When specified, the NFS server disables squashing. The server blindly trusts incoming requests from client UID 0 and executes them with full superuser privileges (UID 0) on the server's local filesystem.
The SUID Privilege Escalation Workflow:
- An attacker obtains an unprivileged shell on a target Unix system and discovers via
/etc/exportsorshowmountthat/srv/sharedis exported withno_root_squash. - On the attacker's own machine (where the attacker possesses full local root authority), the attacker mounts the share:
mount -t nfs 10.10.10.50:/srv/shared /mnt/nfs - Operating as root on the attacker machine, the attacker copies an executable shell into the mount point and sets the SUID permission bit:
cp /bin/bash /mnt/nfs/rootbash chown root:root /mnt/nfs/rootbash chmod 4755 /mnt/nfs/rootbash - Returning to the unprivileged shell on the target system, the attacker navigates to the local directory
/srv/sharedand executes the newly created binary:/srv/shared/rootbash -p - Because the file is owned by root and possesses the SUID bit, the unprivileged user receives an interactive shell with effective UID 0.
2. Host-Based Access Control Vulnerabilities
Exports frequently rely on hostname or IP address specifications:
- Wildcard Access (
*): Allows any host on any reachable network to mount the export. - Permissive Subnets (
192.168.0.0/16): Permitted access across expansive internal networks. - IP Spoofing over UDP (NFSv2/v3): When NFS operates over UDP, the stateless transport mechanism lacks connection handshakes. An attacker capable of injecting packets can forge the source IP address to bypass simple IP-based export restrictions.
3. Additional Key Export Directives
all_squash: Forces all connecting UIDs and GIDs (not just root) to be mapped to the anonymous user (anonuid/anongid). This is effective for public, non-administrative shares.ro/rw: Enforces read-only or read-write access at the filesystem layer.sync/async: Forces the server to commit writes to disk before acknowledging the RPC request (sync), or acknowledge immediately to improve performance at the expense of data integrity (async).
NFS Authentication Models: From AUTH_SYS to Kerberos
A critical vulnerability across legacy NFS installations is the fundamental absence of cryptographic client authentication.
1. AUTH_NONE (RPC Authentication Flavor 0)
No authentication parameters are transmitted in the RPC call. Any client request is processed anonymously.
2. AUTH_SYS / AUTH_UNIX (RPC Authentication Flavor 1)
AUTH_SYS is the default authentication mechanism across NFSv2 and NFSv3:
- How It Works: When a client issues a filesystem read or write RPC call, the client kernel includes the numeric UID and primary/supplementary GIDs of the local user initiating the command inside the RPC message header.
- The Security Flaw: The NFS server performs zero cryptographic verification of the asserted UID/GID. It assumes the client machine is a trusted Unix workstation that accurately reports its users.
- Exploitation Vector: If a file on an NFS share is restricted to UID 1005 (
finance), an attacker who mounts the share simply creates a local account on their own machine with UID 1005:useradd -u 1005 attacker su attacker # The attacker can now read and write to finance files with zero restrictions!
3. RPCSEC_GSS and NFSv4 Kerberos Authentication
To remediate the vulnerabilities of AUTH_SYS, NFSv4 utilizes the Generic Security Services API (GSS-API) via RPCSEC_GSS (RFC 2203), integrating Kerberos (v5) authentication flavors:
sec=krb5(Authentication): Enforces cryptographic mutual authentication between client and server using Kerberos tickets. Prevents unauthorized clients from mounting shares or claiming arbitrary UIDs.sec=krb5i(Integrity): Adds cryptographic checksums to every RPC message payload, protecting data in transit from tampering and Man-in-the-Middle (MitM) packet modification.sec=krb5p(Privacy): Enforces full end-to-end payload encryption across all RPC communications, mitigating network sniffing and eavesdropping.
A penetration tester identifies an NFS export /var/data configured in /etc/exports as *(rw,sync,no_root_squash). The tester mounts the share on their personal Linux attacking laptop. Which series of commands allows the tester to exploit this share to achieve root privileges on the server hosting the export?
During an infrastructure assessment, an analyst encounters TCP port 111 open on a target Linux server. Which utility and command-line flag should the analyst execute to enumerate the registered RPC programs, protocol versions, and dynamic ports listening on the target?
An NFS share is mounted using default NFSv3 AUTH_SYS (also known as AUTH_UNIX) authentication. How does the NFS server verify the authorization of incoming read and write requests from client users?
Which of the following describes a key architectural difference between legacy NFSv3 and modern NFSv4?