
Il fuzzatore del processore x86
: il fuzzer per processori x86
Il sandsifter controlla i processori x86 alla ricerca di istruzioni nascoste e bug hardware, generando sistematicamente codice macchina per esplorare il set di istruzioni di un processore e monitorando l'esecuzione per individuare anomalie. Sandsifter ha scoperto istruzioni segrete del processore da ogni grande produttore; diffusi bug software in disassemblatori, assemblatori ed emulatori; vulnerabilità in hypervisor aziendali; e bug hardware sia benigni che critici per la sicurezza nei chip x86.
Con la moltitudine di processori x86 esistenti, l'obiettivo dello strumento è consentire agli utenti di controllare i propri sistemi per istruzioni nascoste e bug.
Per eseguire un controllo di base sul tuo processore:
sudo ./sifter.py --unk --dis --len --sync --tick -- -P1 -t

Il computer viene scansionato sistematicamente per istruzioni anomale. Nella metà superiore, puoi visualizzare le istruzioni che il sandsifter sta attualmente testando sul processore. Nella metà inferiore, il sandsifter riporta le anomalie che trova.
La ricerca richiederà da alcune ore ad alcuni giorni, a seconda della velocità e della complessità del tuo processore. Quando è completa, riassumi i risultati:
./summarize.py data/log

Tipicamente, verranno trovate diverse milioni di istruzioni non documentate sul tuo processore, ma queste generalmente rientrano in un piccolo numero di gruppi diversi. Dopo aver raggruppato le anomalie, lo strumento di riepilogo tenta di assegnare ogni istruzione a una categoria di problema:
Premi 'Q' per uscire e ottenere un riepilogo testuale della scansione del sistema:
I risultati di una scansione possono talvolta essere difficili da classificare automaticamente per gli strumenti e potrebbero richiedere un'analisi manuale. Per assistenza nell'analisi dei risultati, sentiti libero di inviare il file ./data/log a [email protected]. Nessuna informazione personale, oltre al produttore, modello e revisione del processore (da /proc/cpuinfo) è inclusa in questo log.
La scansione con il sandsifter ha scoperto caratteristiche del processore non documentate in dozzine di categorie di opcode, vulnerabilità in hypervisor aziendali, bug in quasi tutti i principali strumenti di disassemblaggio ed emulazione, e bug hardware critici che aprono vulnerabilità di sicurezza nel processore stesso.
I dettagli dei risultati si trovano nel whitepaper del progetto.
(TODO: enumerazione dettagliata dei risultati qui)
Sandsifter richiede prima l'installazione del disassemblatore Capstone: http://www.capstone-engine.org/. Capstone può essere tipicamente installato con:
sudo apt-get install libcapstone3 libcapstone-dev
sudo pip install capstone
Sandsifter può essere compilato con:
make
e viene poi eseguito con
sudo ./sifter.py --unk --dis --len --sync --tick -- -P1 -t
I flag vengono passati al sifter con --flag, e all'injector con -- -f.
Esempio:
sudo ./sifter.py --unk --dis --len --sync --tick -- -P1 -t
Flag del sifter:
--len
cerca differenze di lunghezza in tutte le istruzioni (istruzioni che
sono state eseguite diversamente da quanto il disassemblatore si
aspettava, o che non esistevano quando il disassemblatore se le
aspettava
--dis
cerca differenze di lunghezza in istruzioni valide (istruzioni che
sono state eseguite diversamente da quanto il disassemblatore si
aspettava)
--unk
cerca istruzioni sconosciute (istruzioni che il disassemblatore non
conosce ma che vengono eseguite con successo)
--ill
l'inverso di --unk, cerca disassemblaggi non validi (istruzioni che
non vengono eseguite con successo ma che il disassemblatore riconosce)
--tick
scrive periodicamente l'istruzione corrente su disco
--save
salva lo stato di avanzamento della ricerca all'uscita
--resume
riprende la ricerca dall'ultimo stato salvato
--sync
scrive i risultati della ricerca su disco man mano che vengono trovati
--low-mem
non memorizzare i risultati in memoria
Flag dell'injector:
-b
modalità: brute force
-r
modalità: fuzzing randomizzato
-t
modalità: fuzzing a tunnel
-d
modalità: fuzzing diretto esternamente
-R
modalità di output raw
-T
modalità di output testo
-x
scrive l'avanzamento periodico su stderr
-0
consenti dereferenziazione nulla (richiede sudo)
-D
consenti prefissi duplicati
-N
nessun supporto per il bit NX
-s seed
nella ricerca random, valore del seed
-B brute_depth
nella ricerca brute, profondità massima di ricerca
-P max_prefix
numero massimo di prefissi da cercare
-i instruction
istruzione da cui iniziare la ricerca (inclusiva)
-e instruction
istruzione in cui terminare la ricerca (esclusiva)
-c core
core su cui eseguire la ricerca
-X blacklist
blacklist l'istruzione specificata
-j jobs
numero di job simultanei da eseguire
-l range_bytes
numero di byte di istruzione base in ogni sottointervallo
m: Mode - cambia la modalità di ricerca (brute force, random o tunnel) per il sifter
q: Quit - esci dal sifter
p: Pause - metti in pausa o riprendi la ricerca
La scansione supporta quattro diversi algoritmi di ricerca, che possono essere impostati dalla riga di comando o ciclati tramite hotkey.
sudo
Per ottenere i migliori risultati, lo strumento dovrebbe essere eseguito come utente root. Ciò è necessario affinché il processo possa mappare in memoria una pagina all'indirizzo 0, che richiede permessi di root. Questa pagina impedisce a molte istruzioni di causare seg-fault sugli accessi alla memoria, consentendo un'analisi dei guasti più accurata.
Prefissi
La limitazione principale per la profondità di una ricerca di istruzioni è il numero di byte di prefisso da esplorare, con ogni byte di prefisso aggiuntivo che aumenta lo spazio di ricerca di circa un fattore 10. Limita i byte di prefisso con il flag -P.
Colori
L'interfaccia del sifter è progettata per un terminale a 256 colori. Sebbene i dettagli varino notevolmente a seconda del terminale, questo può essere approssimativamente realizzato con:
export TERM='xterm-256color'
GUI
L'interfaccia presuppone che il terminale abbia almeno una certa dimensione; se l'interfaccia non viene renderizzata correttamente, prova ad aumentare la dimensione del terminale; questo può spesso essere realizzato diminuendo la dimensione del carattere del terminale.
In alcuni casi, potrebbe essere desiderabile o necessario eseguire lo strumento senza l'interfaccia grafica. Questo può essere fatto eseguendo direttamente l'injector:
sudo ./injector -P1 -t -0
Per filtrare i risultati di un'invocazione diretta dell'injector, è possibile usare grep. Per esempio,
sudo ./injector -P1 -r -0 | grep '\.r' | grep -v sigill
cerca istruzioni per le quali il processore e il disassemblatore non concordavano sulla lunghezza dell'istruzione (grep '.r'), ma l'istruzione è stata eseguita con successo (grep -v sigill).
Fuzzing mirato
In molti casi, è utile dirigere il fuzzer verso un bersaglio specifico. Per esempio, se sospetti che un emulatore abbia difetti riguardo ai prefissi 'lock' ripetuti (0xf0), potresti dirigere il fuzzer a cercare in questa regione dello spazio delle istruzioni con i flag -i e -e:
sudo ./sifter.py --unk --dis --len --sync --tick -- -t -i f0f0 -e f0f1 -D -P15
Sistemi legacy
Per la scansione di sistemi molto più vecchi (processori di classe i586, sistemi con poca memoria), passa il flag --low-mem al sifter e il flag -N all'injector:
sudo ./sifter.py --unk --dis --len --sync --tick --low-mem -- -P1 -t -N
Se osservi che le tue scansioni si completano troppo rapidamente (ad esempio, una scansione si completa in secondi), è tipicamente perché questi flag sono richiesti per il processore che stai scandendo.
32 vs. 64 bit
Per impostazione predefinita, sandsifter è compilato per la bitness del sistema operativo host. Tuttavia, alcune istruzioni hanno comportamenti diversi quando eseguite in un processo a 32 bit rispetto a quando eseguite in un processo a 64 bit. Per esplorare questi scenari, a volte è utile eseguire un sandsifter a 32 bit su un sistema a 64 bit.
Per compilare un sandsifter a 32 bit su un sistema a 64 bit, Capstone deve essere installato come 32 bit; le istruzioni per questo si trovano su http://www.capstone-engine.org/.
Quindi sandsifter deve essere compilato per un'architettura a 32 bit:
make CFLAGS=-m32
Con questo, lo spazio delle istruzioni a 32 bit può essere esplorato su un sistema a 64 bit.
sandsifter è uno sforzo di ricerca di Christopher Domas (@xoreaxeaxeax).