
# Caso di studio educativo e guida allo sviluppo di exploit per CVE-2022-0185, un overflow del buffer heap del kernel Linux che consente l'escalation dei privilegi locali. Include POC, debug con QEMU ed exploit per Ubuntu con analisi tecnica dettagliata.
Questo case study è il risultato di un compito del corso ECE 9069: Introduction to Hacking : https://whisperlab.org/introduction-to-hacking/
CVE-2022-0185 è un difetto di overflow del buffer basato su heap trovato nel modo in cui la funzione legacy_parse_param nella funzionalità Filesystem Context del kernel Linux verificava la lunghezza dei parametri forniti. Un utente locale non privilegiato (nel caso in cui gli user namespaces non privilegiati siano abilitati, altrimenti è necessario il privilegio CAP_SYS_ADMIN all'interno del namespace) in grado di aprire un filesystem che non supporta l'API Filesystem Context (e che quindi ripiega sulla gestione legacy) potrebbe usare questo difetto per aumentare i propri privilegi sul sistema. [1]
Dopo che questa vulnerabilità è stata segnalata, è stata rilasciata una patch per correggere il bug:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=722d94847de2
https://ubuntu.com/security/CVE-2022-0185#impact-score
C'è un writeup dettagliato dell'esploratore: https://www.hackthebox.com/blog/CVE-2022-0185:_A_case_study
In questo repository spiegherò i passaggi di base e le informazioni di contesto correlate per riprodurre questa vulnerabilità. Inoltre, se c'è qualcosa che non ti è chiaro, puoi inviarmi una email: [email protected]. Sarò molto felice di rispondere alle domande.
La vulnerabilità CVE-2022-0185 è stata pubblicata il 02/11/2022, con un punteggio base CVSS 3.x di 8.4 (Alto).[1] Questa vulnerabilità è un overflow del buffer basato su heap, causato da un underflow di un intero senza segno.
La vulnerabilità è stata introdotta nel kernel Linux v5.1, interessando tutte le distribuzioni Linux con versioni del kernel superiori alla 5.1. Per esempio, Ubuntu 20.04 LTS (focal) era vulnerabile a questo bug. Tuttavia, una patch è stata rilasciata ed è disponibile dalla versione 5.4.0-96.109 .[3]
Lo sfruttamento di questa vulnerabilità consente a un utente locale non privilegiato di aumentare i propri privilegi sul sistema, compromettendo potenzialmente l'intero sistema.[1] [2] Ecco un'analisi dettagliata del punteggio CVSS: Punteggio Base: 8.4, che indica un rischio di sicurezza significativo che richiede attenzione immediata. Punteggio di Impatto: 5.9, che suggerisce un potenziale danno sostanziale se sfruttata. I valori elevati di riservatezza, integrità e disponibilità contribuiscono a questo punteggio. Punteggio di Sfruttabilità: 2.5, che suggerisce una sfruttabilità relativamente alta. Il vettore di attacco locale, l'elevata integrità e l'elevata disponibilità contribuiscono a questo punteggio.
La Tabella 1.1 e la Tabella 1.2 forniscono maggiori informazioni su questi punteggi e sui loro componenti.
| Gravità CVSS v3.1 | Valore |
|---|---|
| Punteggio Base | 8.4 ALTO |
| Punteggio di Impatto | 5.9 |
| Punteggio di Sfruttabilità | 2.5 |
Tabella 1.1 Punteggi di gravità CVSS[1]
| Metriche CVSS v3.1 | Valore |
|---|---|
| Vettore di attacco (AV) | Locale |
| Privilegi richiesti (PR) | Nessuno |
| Interazione utente (UI) | Nessuna |
| Riservatezza (C) | Alta |
| Integrità (I) | Alta |
| Disponibilità (A) | Alta |
Tabella 1.2 Vettore CVSS[1]
Nei computer moderni esistono due tipi di interi: con segno e senza segno. La rappresentazione dei numeri con segno coinvolge generalmente un'operazione chiamata complemento a due.[4] “Il complemento a due usa la cifra binaria con il maggior valore posizionale come segno per indicare se il numero binario è positivo o negativo”[4]
L'introduzione del complemento a due converte il calcolo della sottrazione in addizione, semplificando quindi la progettazione e l'implementazione della CPU. La generazione del complemento a due di un intero coinvolge tre passaggi:[4]
La Fig 2.1.1.1 mostra il processo di conversione in un diagramma con un esempio reale di conversione di “-6” nel suo formato in complemento a due.

Fig 2.1.1.2 Addizione usando il complemento a due
La Figura 2.1.1.2 mostra il processo di addizione del complemento a due di '-6' a '+6'. Questo dimostra come l'uso del complemento a due consenta di utilizzare l'addizione come sostituto della sottrazione.

Fig 2.1.1.2 Addizione usando il complemento a due
Dalla Sezione 2.1.1, abbiamo già capito cos'è il complemento a due. Ora diamo un'occhiata allo scenario dell'underflow dei numeri senza segno nei computer. Nei computer moderni, quando si usano numeri senza segno, il bit più significativo non viene trattato come bit di segno; invece, fa parte del numero senza segno stesso. Questa situazione significa che quando si esegue una sottrazione con un numero senza segno, bisogna essere cauti, poiché può portare a una condizione nota come underflow dei numeri senza segno.[5]
La Fig 2.1.2.1 illustra la situazione della sottrazione di 6 da 5 per un numero senza segno a 8 bit. Il risultato finale è 255 a causa dell'avvolgimento del numero senza segno. Quando questo underflow si verifica in un'istruzione condizionale, ha il potenziale di interrompere la funzionalità dell'istruzione stessa.

Fig 2.1.2.1 Underflow di un numero senza segno
Nel kernel Linux, l'allocatore Slab è un meccanismo di gestione della memoria utilizzato per l'allocazione e la deallocazione efficiente di piccoli blocchi di memoria. Offre prestazioni mantenendo diverse cache di Slab, ciascuna contenente blocchi di memoria di dimensione fissa. Tipicamente, kmalloc-32 alloca 32 byte di memoria ed è uno slab kmalloc-32, mentre kmalloc-4k alloca 4096 byte di memoria ed è uno slab kmalloc-4k.[6]
Inoltre, l'allocazione a slab nel kernel Linux comporta tipicamente l'allocazione di memoria da uno spazio di indirizzi contiguo all'interno della regione di memoria heap del kernel. Questo indirizzo contiguo è gestito dal kernel e viene utilizzato per allocare memoria per vari oggetti e strutture dati del kernel. La Fig 2.2.1.1 mostra la disposizione degli slab nella memoria del kernel Linux.

Fig 2.2.1.1 Allocatore Slab in Linux [7] (L'autore di questa figura è https://leviathan.vip/)
Se vuoi riprodurre il processo con un kernel Linux compilato da te, leggi i seguenti file markdown per ottenere le informazioni di contesto:
Nota: