Titolo del Progetto
Generatore di exploit per CVE-2021-3156 sudo
Installazione
- Installa le dipendenze ./install.sh
- Esegui il generatore di exploit: ./run.sh
- Se la versione di sudo del sistema è vulnerabile, viene generato un exploit per la versione installata
- L'exploit viene generato in exploit.c e nel binario ./exploit
Requisiti
- gdb gcc make python3 python3-distro
- glibc con tcache
- Attualmente sistemi operativi Ubuntu, Debian.
Testato
- Ubuntu 20.04.1
- Ubuntu 20.04.2
- Ubuntu 20.10
- Ubuntu 18.04.5
- Debian 10.7.0
Autore
Vulnerabilità
- sudo esegue l'escaping dei metacaratteri nella funzione parse_args in main
- Successivamente, in set_cmnd, vengono rimossi i caratteri di escape non seguiti da spazio
- sudo assume che parse_args sia una precondizione di set_cmnd.
- Il problema è che le condizioni sono diverse in ciascun parser. Il primo viene eseguito se la modalità è (MODE_RUN && MODE_SHELL). Il secondo viene eseguito se la modalità è (MODE_RUN | MODE_EDIT | MODE_CHECK) e (MODE_SHELL|MODE_LOGIN_SHELL)
- Esiste un modo per non eseguire il primo parser ma il secondo: sudoedit -s
- set_cmnd calcola la dimensione degli argomenti e crea un chunk nell'heap per concatenarli. Poi copia ogni argomento finché non trova un byte nullo e continua con il successivo. Se l'argomento di input termina con una '\', set_cmnd salta il carattere di escape, copia il byte nullo ma continua a copiare l'argomento successivo come se fosse lo stesso. Questo produce un overflow del buffer nell'heap.
- Pertanto, se l'ultimo argomento termina con '\', set_cmnd fa overflow del buffer con il contenuto della prima variabile d'ambiente. Se questa variabile d'ambiente termina con '\', continuerà a copiare la successiva.
Generatore Exploit
- Si usa il metodo 2 descritto in (https://packetstormsecurity.com/files/161160/Sudo-Heap-Based-Buffer-Overflow.html)
- sudo usa glibc nsswitch per leggere il database group dopo l'overflow.
- nsswitch crea una struttura dati service_table nell'heap con tutti i database e i servizi di nsswitch.conf.
- I servizi di group hanno il tipo struct service_user.
- La struttura ha un campo name con il nome del servizio
- nsswitch carica dinamicamente una libreria libnss_[nome_servizio]_.so.2 in base alla configurazione di /etc/nsswitch.conf per ogni servizio del database group.
- Il puntatore library deve essere sovrascritto con NULL per evitare un crash. Inoltre questo fa sì che la libreria venga ricaricata in memoria, questa volta una libreria locale con la shellcode.
- Si usa la tecnica heap grooming o feng shui. Vengono create variabili d'ambiente "locali" di dimensione variabile per generare un layout nell'heap che permetta di avvicinare il chunk in cui set_cmnd copia gli argomenti all'obiettivo, che è la struttura service_user di group.
- Subito prima di eseguire la malloc di set_cmnd, si osserva la tcache dell'heap per vedere i primi chunk che verranno riciclati e le loro dimensioni.
- I chunk che formano i database e i servizi di nsswitch vengono ordinati. Vengono attraversati in modo ordinato. Vengono memorizzati l'indirizzo di memoria del chunk obiettivo e quello precedente.
- Si cerca un chunk nella tcache bin all'interno di quel range.
- Una volta nota la posizione del chunk e la sua dimensione, viene generato l'exploit.
- Si usa un argomento terminato con '\' e un byte nullo della dimensione precisa affinché quel chunk venga riciclato.
- Vengono create le precise variabili d'ambiente 'locali' per creare il layout adeguato.
- Prima di queste variabili 'locali', viene generata una variabile d'ambiente della dimensione necessaria per raggiungere la struttura obiettivo.
- La struttura obiettivo viene sovrascritta con byte nulli usando array di stringhe con il carattere di escape '\'; questo fa sì che in set_cmnd venga scritto un byte nullo.
- Il campo name di service_user viene sovrascritto con 'x/x' in modo che successivamente venga caricata la libreria 'libnss_x/x.so.2'
- Nella libreria viene creato un constructor che esegue una shellcode.
- Poiché sudo viene eseguito con il bit suid, la shell appartiene a root.
Licenza
Questo progetto è sotto la licenza GNU GPL.