Skip to content

F-1.3: Auxiliary Group Injection

Classification

  • Severity: Critical
  • CVSS Vector: Network / Low Complexity / No Auth Required
  • Affected Versions: NFSv2, NFSv3, NFSv4 with AUTH_SYS
  • RFC Reference: RFC 1057 §9.2
  • Prerequisite: Files protected by group permissions (e.g., /etc/shadow with group shadow)

Summary

The AUTH_SYS credential includes a gids<16> array — up to 16 auxiliary group IDs, all client-asserted and unverified. An attacker can inject any GIDs into this array to gain group-level access to files. The most impactful target is the shadow group (GID 42 on Debian/Ubuntu, GID 15 on SUSE), which grants read access to /etc/shadow.

Technical detail

AUTH_SYS group array

Per RFC 1057 §9.2:

struct authsys_parms {
    unsigned int stamp;
    string machinename<255>;
    unsigned int uid;
    unsigned int gid;
    unsigned int gids<16>;     ← up to 16 attacker-controlled GIDs
};

The server checks file group permissions against both the primary gid and all entries in gids. No verification occurs.

The /etc/shadow attack

On Debian-based systems:

-rw-r----- 1 root shadow /etc/shadow

The file is group-readable by GID 42 (shadow). Combined with export escape (F-2.1):

# Set aux GIDs to include shadow group
credential = AUTH_SYS(0, "host", 65534, 65534, [42])
# Now read /etc/shadow through escaped handle
data = await client.read(shadow_fh, 0, 65536)

This works even with root_squash because neither the UID nor the primary GID is 0.

Well-known target GIDs

GID Group Distribution Access Granted
42 shadow Debian/Ubuntu /etc/shadow
15 shadow SUSE /etc/shadow
33 www-data Debian/Ubuntu Web roots
100 users Various Shared directories
27 sudo Debian/Ubuntu Sudoers info

Impact

  • Read /etc/shadow for offline password cracking (Debian/SUSE)
  • Access group-protected files without knowing any passwords
  • Bypass file permissions that rely on group membership
  • Up to 16 groups can be injected simultaneously per request

Remediation

  1. Use Kerberos — verifies actual group memberships
  2. Set /etc/shadow to root:root ownership (as RHEL does) instead of root:shadow
  3. Use all_squash to eliminate group trust
  4. Place exports on dedicated filesystems to prevent escape to /etc/shadow