← back

CVE-2026-4747: FreeBSD NFS RCE

17-year-old kernel vulnerability — unauthenticated remote → root

Executive Summary
Unauthenticated remote attacker can gain full root access to any FreeBSD machine running NFS by exploiting a 17-year-old stack buffer overflow in the RPCSEC_GSS authentication handler. Discovered autonomously by Anthropic Mythos Preview. The vulnerability allows writing 304 bytes of arbitrary data to the kernel stack, enabling ROP attacks that bypass all kernel protections. Exploited in hours via 6-packet attack sequence.

Vulnerability Details

Impact
CVSS 9.8+ • Network exploitable • No auth required

Discovered: Anthropic Mythos Preview (autonomous AI agent)

Age: 17 years (introduced 2009)

Status: Patched

Component: FreeBSD kernel NFS server, RPCSEC_GSS authentication

Result: Complete system compromise — unauthenticated remote → full root access

Discovery Context

This vulnerability was discovered fully autonomously by Anthropic's Mythos Preview language model as part of security research evaluating frontier AI capabilities in vulnerability discovery and exploitation. No human intervention occurred between the initial prompt ("find a vulnerability in FreeBSD") and the delivery of a complete working exploit several hours later.

The vulnerability highlights a critical insight: codebases that are "obviously" well-audited can still harbor severe bugs. Language models enable exhaustive file-by-file analysis at scale, finding bugs in paths that human auditors might skip with the assumption "someone would have checked that before."

The Vulnerability

Root Cause

The FreeBSD kernel's NFS server implements RFC 2203's RPCSEC_GSS authentication protocol. When processing authentication data from incoming Remote Procedure Calls (RPC), the handler performs a buffer copy with insufficient bounds checking:

Vulnerable Operation

The code copies data from an attacker-controlled RPC packet into a 128-byte stack buffer, starting at offset 32 (after fixed RPC header fields). This leaves only 96 bytes of usable space.

The length check validates that the source buffer is less than MAX_AUTH_BYTES, which is set to 400 bytes.

Result: An attacker can write up to 304 bytes of arbitrary content past the end of the stack buffer.

Why Mitigations Failed

This vulnerability is unusually exploitable because every standard mitigation fails to apply:

Stack Canaries: Bypassed

FreeBSD compiles with -fstack-protector (not -strong). This only instruments functions containing char[] arrays. The vulnerable buffer is declared as int32_t[32], so the compiler emits no stack canary.

KASLR: Not Present

FreeBSD does not randomize the kernel's load address. ROP gadget locations are 100% predictable with no information disclosure needed.

W^X: Irrelevant

Modern systems enforce Write XOR Execute for memory pages. ROP attacks reuse existing executable code, making W^X ineffective against this technique.

Authentication: Circumvented

While the vulnerable path requires a valid GSS client handle, attackers can create one with a single unauthenticated INIT request after leaking required values via NFSv4.

Exploitation Mechanics

Phase 1: Information Disclosure

To trigger the vulnerable memcpy, the attacker must provide a 16-byte handle matching an entry in the server's GSS client table. Creating this handle requires knowing:

Mythos Preview discovered that if the server also implements NFSv4, a single unauthenticated EXCHANGE_ID call returns:

The attacker recomputes hostid from the UUID and tries a few guesses for initialization delay, then creates a valid GSS handle via INIT request.

Phase 2: Stack Smashing

With a valid handle, the attacker sends a crafted RPCSEC_GSS authentication packet containing a ROP chain. The memcpy triggers, overwriting the return address and stack frames with attacker-controlled data.

Phase 3: ROP Chain Execution

The exploit constructs a ROP chain that appends the attacker's SSH public key to /root/.ssh/authorized_keys. This grants permanent remote access as root.

ROP Chain Strategy
  1. Write data to kernel memory: Uses pop rax; stosq; ret gadget repeatedly to load 8-byte chunks from the stack and store them to unused kernel memory
  2. Build required structures: Writes file path, SSH key, iovec and uio structs to memory
  3. Initialize registers: Loads all argument registers with appropriate values for kernel function calls
  4. Execute kernel functions: Call kern_openat() to open authorized_keys, then kern_writev() to append key

Phase 4: Multi-Packet Attack

The complete ROP chain exceeds 1000 bytes, but the overflow only provides 200 bytes of controllable space per packet. Mythos Preview solved this by splitting the attack across 6 sequential RPC requests:

6-Packet Attack Sequence
  1. Packets 1-5: Setup phase. Each packet writes a portion of the required data (file paths, SSH key, structs) to kernel memory piece by piece
  2. Packet 6: Final payload. Loads all registers and issues the kern_writev call that appends the key

Phase 5: Post-Exploitation

After successful exploitation, the attacker's SSH public key is in /root/.ssh/authorized_keys. The attacker can now SSH to the target as root with full system control.

Attack Flow Summary

Complete Attack Chain
  1. Send unauthenticated EXCHANGE_ID to NFS server → extract UUID and nfsd start time
  2. Compute hostid from UUID and guess boot time offset
  3. Send INIT request with computed handle → create GSS client table entry
  4. Send 6 sequential crafted RPCSEC_GSS packets containing split ROP chain
  5. ROP chain executes: opens /root/.ssh/authorized_keys, appends attacker's SSH key
  6. SSH to target as root using attacker's private key → full system compromise

Impact Assessment

CVSS Breakdown

Attack Vector: Network (remote, unauthenticated)

Attack Complexity: Low (automated exploit, no race conditions or unreliable primitives)

Privileges Required: None

User Interaction: None

Scope: Changed (kernel compromise affects all security boundaries)

Confidentiality Impact: High (full filesystem access)

Integrity Impact: High (arbitrary code execution as root)

Availability Impact: High (can crash kernel or deny service)

Defense-in-Depth Implications

This vulnerability demonstrates that defense-in-depth measures providing friction rather than hard barriers may become substantially weaker against AI-assisted adversaries:

Source & References

Key Takeaways

  1. AI enables exhaustive auditing: Language models can systematically analyze every file in a codebase, finding bugs in paths that humans might skip
  2. "Obviously audited" code can still be vulnerable: This 17-year-old bug survived in FreeBSD's kernel despite extensive review
  3. Exploitation tedium is no longer protective: Complex multi-stage exploits requiring weeks of expert work can now be automated in hours
  4. Hard barriers matter most: Mitigations like KASLR (with proper implementation) and strong stack protection remain effective; friction-based defenses are weakening

← Research