Timeline:
2026-03-26: FreeBSD published an advisory for CVE-2026-4747, crediting “Nicholas Carlini using Claude, Anthropic” for a remote kernel code execution.
9:45AM PDT 2026-03-29: We asked Claude to develop an exploit.
5:00PM PDT 2026-03-29: Claude delivered a working exploit that drops a root shell.
Total time: ~8 hours wall clock. The human was AFK for much of it; Claude’s actual working time was ~4 hours.
Claude actually wrote two exploits using two different strategies. Both worked on the first try. Here’s what it looks like:
Check out the full exploit and the write-up. Claude wrote everything itself. Here are the prompts we used (excuse the typos):
Going from a vulnerability advisory to a working remote root shell required Claude to solve six distinct problems. It’s worth noting that FreeBSD made this easier than it would be on a modern Linux kernel: FreeBSD 14.x has no KASLR (kernel addresses are fixed and predictable) and no stack canaries for integer arrays (the overflowed buffer is int32_t[]).
Lab setup: Stand up a FreeBSD VM with NFS, Kerberos, and the vulnerable kernel module, all configured so the overflow is reachable over the network. Claude knew the VM needed 2+ CPUs because FreeBSD spawns 8 NFS threads per CPU, and the exploit kills one thread per round. This included setting up remote debugging so Claude could read kernel crash dumps.
Multi-packet delivery: The shellcode doesn’t fit in one packet. Claude devised a 15-round strategy: make kernel memory executable, then write shellcode 32 bytes at a time across 14 packets. In another exploit privately shared with us, Claude used a different strategy: writing a public key to
.ssh/authorized_keysinstead of a reverse shell, which shortened the exploit to 6 rounds.Clean thread exit: Each overflow hijacks an NFS kernel thread. Claude used kthread_exit() to terminate each thread cleanly, keeping the server alive for the next round.
Offset debugging: The initial stack offsets from disassembly were wrong. Claude sent De Bruijn patterns (a common technique, but a term we hadn't heard of before reading the writeup), read the crash dumps, and corrected the offsets.
Kernel-to-userland transition: NFS threads can’t run userland programs. Claude created a new process via
kproc_create(), usedkern_execve()to replace it with/bin/sh, and cleared theP_KPROCflag so the process could transition to user mode.Hardware breakpoint bug: The child process kept crashing with a debug exception. Claude traced this to stale debug registers inherited from DDB and fixed it by clearing DR7 before forking.
Computers have always been able to find bugs in software. Fuzzers like AFL and syzkaller have been discovering kernel vulnerabilities for over a decade. But finding a bug and exploiting it are very different things. Exploit development requires understanding OS internals, crafting ROP chains, managing memory layouts, debugging crashes, and adapting when things go wrong. This has long been considered the frontier that only humans can cross.
Each new AI capability is usually met with “AI can do Y, but only humans can do X.” Well, for X = exploit development, that line just moved.