Sploitus

Exploit for Out-of-bounds Write in Freebsd

githubexploit Β· 2026-08-04

Exploit Code

README102 lines
## https://sploitus.com/exploit?id=2D48CF48-2431-5D7F-9C50-4A5EEB275A49
# FreeBSD PF_KEY `sa_len` stack overflow

```
  _._     _,-""`-._
 (,-.`._,'(       |\`-/|
     `-.-' \ )-`( , o o)
           `-    \`_`"'-
  meow.  _SiCk // afflicted.sh
```

Sibling of **CVE-2026-3038** (rtsock `sa_len` overflow). Same mistake, different socket: PF_KEY's `key_updateaddresses()` copies an attacker-controlled `sa_len` into a stack-local `secasindex` without checking the destination size.

Target: **FreeBSD 15.1-RELEASE-p2** amd64 (offsets + gadgets are for that build).

## The bug

`SADB_UPDATE` can carry `SADB_X_EXT_NEW_ADDRESS_SRC` (and friends). The kernel pulls a `sockaddr` out of that extension and updates the SA address index.

Roughly:

```c
/* key_updateaddresses() - conceptual */
bcopy(newaddr, &saidx->src, newaddr->sa_len);
```

`saidx` lives on the stack inside `key_update()`. `newaddr->sa_len` is under your control (up to what fits in the PF_KEY message). There is no clamp to `sizeof(saidx->src)`.

So you get a classic stack smash: overwrite locals past `saidx->src`, then the saved frame / return address of `key_update()`.

This is the same class as the rtsock bug (trust `sa_len`, copy into a fixed buffer). Different subsystem, same bad habit.

## Why it matters

- Needs a **PF_KEY** socket (`socket(AF_KEY, SOCK_RAW, PF_KEY_V2)`), which needs **`PRIV_NET_RAW`** (root / suser).
- Once you hold the fd, FreeBSD does **not** revoke it on `setuid` drop. Open as root, drop to unpriv, still talk PF_KEY.
- Controlled stack overflow in kernel context β†’ ROP β†’ clear SMEP/SMAP β†’ userspace shellcode β†’ zero creds β†’ root shell.

So: not a pure "from unpriv open raw" bug. It is a **kernel LPE once you can open PF_KEY** (or inherit the fd). The PoC uses `mdo` only as a lab stool to get that socket + `/dev/mem` for leaks; the overflow itself runs after `setuid(1002)`.

## Exploit outline

1. Open PF_KEY as root, FLUSH, REGISTER, ADD an ESP SA.
2. Leave reply mbufs on `so_rcv` (don't drain). Walk own `kinfo_proc` / fd table via `kvm` + `/dev/mem` to leak:
   - `struct socket *` for the keysock
   - an `M_PKTHDR` mbuf on the receive chain
   - a quiet BSS page for a fake `sav` with refcnt 0
3. Drop to unprivileged uid.
4. Send `SADB_UPDATE` with `SADB_X_EXT_NEW_ADDRESS_SRC` and `sa_len = 255`.
5. Overflow plants:
   - fake `sav` (BSS - refcnt offset)
   - leaked `so`
   - real pkthdr `m`
   - ROP at saved RIP (`saidx->src + 152` on this kernel):
     - `pop rsi; ret`
     - CR4 with SMEP/SMAP cleared
     - `mov cr4, rsi; ret`
     - userspace shellcode
6. Shellcode zeros uid/gid on the cred, `swapgs; iretq` back into `got_root()` β†’ `/bin/sh`.

SIGSEGV handler is a backup if the iretq frame is wrong; creds may already be zeroed.

## Build / run

On the FreeBSD target:

```sh
cc -o pfkey_lpe pfkey_lpe.c -lkvm
# needs root for the socket + mem setup in this PoC
mdo ./pfkey_lpe
# or: su / doas / whatever gets you uid 0 for the open
```

Hardcoded for lab:

- drop target uid `1002` (testuser) - edit `real_uid` if yours differs
- CR4 safe value `0x506E0` (measured on the box; re-measure if CPU/features differ)
- ROP gadgets and struct offsets for **15.1-RELEASE-p2** only

Wrong kernel β†’ wrong offsets β†’ panic. Don't run this on a machine you care about.

## Files

| file | what |
|------|------|
| `pfkey_lpe.c` | full chain PoC |

## Notes / limits

- **Not** unprivileged-from-cold without another bug or a misconfig that hands you PF_KEY / root.
- `/dev/mem` + `kvm` are for leak and fake objects in this PoC; a pure-info-leak variant would drop that dependency.
- Gadgets and `OFF_*` need a retarget pass per kernel build.
- Related: CVE-2026-3038 (rtsock). Patch audits should cover every `sa_len` copy into fixed storage, not just routing sockets.

## Author

**_SiCk** / [0xdeadbeefnetwork](https://github.com/0xdeadbeefnetwork)  
afflicted.sh

```
meow.
```