F-5.15: rquotad Exposes UID Activity via Quota Queries¶
Classification¶
- Severity: Medium (Information Disclosure / Credential Discovery)
- CVSS Vector: Network / Low Complexity / No Auth Required
- Affected Versions: Any NFS server co-hosting rquotad (program 100011)
- Service: rquotad (program 100011, version 1, procedure GETQUOTA)
- Prerequisite: rquotad reachable via portmapper (port resolved via GETPORT on port 111)
Summary¶
rquotad (program 100011) is a Sun-originated RPC service that returns per-UID disk usage without authentication. A GETQUOTA call for a specific UID reveals whether that UID has disk activity on the queried export -- non-zero curblocks or curfiles confirms the UID exists and has consumed storage. This turns rquotad into a UID existence oracle. Additionally, the bsize field in every quota response leaks the filesystem block size, which fingerprints the filesystem type (ext4=4096, XFS=512, ZFS=1024) and narrows the escape strategy before any NFS operation is attempted. Active UIDs discovered through rquotad feed the credential ladder for targeted AUTH_SYS spoofing.
Technical detail¶
GETQUOTA wire format¶
rquotad uses a de facto standard wire format from Sun's rquota.x (no RFC exists):
GETQUOTA v1 (procedure 1):
Input: export_path (XDR string) + uid (u32)
Output: status (Q_OK=1 / Q_NOQUOTA=2 / Q_EPERM=3) + rquota struct
The rquota struct (returned on Q_OK):
| Field | Size | Meaning |
|---|---|---|
bsize |
u32 | Filesystem block size in bytes |
active |
bool | Whether quota enforcement is active |
bhardlimit |
u32 | Hard block limit |
bsoftlimit |
u32 | Soft block limit |
curblocks |
u32 | Current blocks used by this UID |
fhardlimit |
u32 | Hard file (inode) limit |
fsoftlimit |
u32 | Soft file (inode) limit |
curfiles |
u32 | Current files owned by this UID |
btimeleft |
u32 | Seconds until soft block limit enforced |
ftimeleft |
u32 | Seconds until soft file limit enforced |
UID existence oracle¶
The critical observation: Q_OK with non-zero curblocks or curfiles means the UID has consumed disk resources on this export. Q_NOQUOTA means either the UID does not exist, has no quota record, or has no disk activity. The distinction is useful even without quotas enabled -- many Linux systems return Q_OK with zero limits (no enforcement) but accurate usage counts.
GETQUOTA(uid=0) -> Q_OK, curblocks=15234, curfiles=892 # root is active
GETQUOTA(uid=1000) -> Q_OK, curblocks=4521, curfiles=127 # user 1000 exists and is active
GETQUOTA(uid=1001) -> Q_NOQUOTA # no activity for uid 1001
GETQUOTA(uid=65534) -> Q_OK, curblocks=0, curfiles=3 # nobody has 3 files
Filesystem fingerprinting via bsize¶
The bsize field is set by the kernel's sb_dqopt() path and reflects the filesystem's native block size:
| bsize Value | Filesystem | Notes |
|---|---|---|
| 4096 | ext4 | Default block size for ext4 |
| 512 | XFS | XFS reports sector size as bsize |
| 1024 | ZFS | ZFS default record size |
| 4096 | btrfs | Matches page size |
| 1024 | ext2/ext3 | Small-filesystem default |
This fingerprint is available before any NFS operation. Combined with file handle analysis (F-2.1), it confirms the filesystem type and narrows escape candidate selection.
No authentication required¶
rquotad performs no authentication check on GETQUOTA requests. The service accepts queries from any source IP that can reach its port. The port is dynamically assigned and discoverable via portmapper GETPORT (program 100011, version 1, protocol TCP).
Exploitation¶
Automated (nfswolf)¶
# The analyzer probes rquotad during analysis:
nfswolf analyze target:/export
# Output when active UIDs are found:
# [MEDIUM] F-5.15: rquotad exposes UID activity via quota queries
# Evidence: block_size=4096; active_uids: uid=0 blocks=15234 files=892,
# uid=1000 blocks=4521 files=127
Manual UID sweep¶
#!/usr/bin/env bash
set -euo pipefail
TARGET="${1:?Usage: $0 <target>}"
EXPORT="${2:-/}"
# Resolve rquotad port
PORT=$(rpcinfo -p "$TARGET" | awk '/100011.*tcp/ {print $4; exit}')
if [[ -z "$PORT" ]]; then
echo "rquotad not registered"
exit 1
fi
# Sweep common UIDs
for uid in 0 $(seq 500 520) $(seq 1000 1020) 65534; do
result=$(rquota -p "$EXPORT" -u "$uid" "$TARGET" 2>/dev/null) || continue
echo "uid=$uid: $result"
done
Credential ladder integration¶
Active UIDs discovered via rquotad are injected into the credential ladder as high-confidence targets. Their disk activity confirms they are real accounts with file ownership on the export, making them better candidates than blind UID brute-force.
Impact¶
- UID existence confirmation: Identifies which UIDs have disk activity on the export without authentication
- Filesystem fingerprinting: The
bsizefield reveals the filesystem type before any NFS operation - Credential ladder acceleration: Active UIDs are high-confidence targets for AUTH_SYS spoofing (F-1.1), bypassing brute-force enumeration
- Quota limit disclosure: Hard and soft limits reveal the server's resource allocation policy
- Activity profiling:
curblocksandcurfilesreveal the relative disk footprint of each user
Limitations¶
- rquotad is not universally deployed -- many modern systems do not run it
- Some distributions restrict rquotad to localhost or require
tcp_wrappersauthorization Q_NOQUOTAdoes not definitively prove the UID does not exist -- it may exist with no disk activity- The service must be resolvable via portmapper (port 111); if portmapper is firewalled, rquotad is unreachable
Detection (nfswolf)¶
The analyzer resolves rquotad via portmapper GETPORT (program 100011, version 1, TCP), then issues GETQUOTA for UIDs 0, 1000, and 65534. If any query returns Q_OK with non-zero curblocks or curfiles, or if any response includes a non-zero bsize, the finding fires at Medium severity. The evidence lists the block size and all active UIDs with their usage counts.
Remediation¶
-
Disable rquotad if remote quota queries are not needed:
-
Firewall rquotad -- restrict access to the rquotad port from untrusted networks:
-
Use tcp_wrappers if the rquotad build supports it:
-
Migrate to NFSv4 -- NFSv4 does not use rquotad; quota information is accessed via the GETATTR operation with the
quota_avail_hard/quota_avail_soft/quota_usedattributes, which are subject to the export'ssec=enforcement
Related findings¶
| Finding | Relationship |
|---|---|
| F-1.1: UID/GID Spoofing | Active UIDs from rquotad are spoofed via AUTH_SYS |
| F-5.4: RPC Service Enumeration | Portmapper DUMP reveals rquotad registration |
| F-5.14: POSIX ACL Entries | Both findings feed the credential ladder with targeted UIDs/GIDs |