
Un fuzzer multipiattaforma per testare binari in spazio utente, client e server di rete
Un fuzzer multi-piattaforma per sondare binari userland, client e server.
Ha trovato bug in 50+ app e librerie di grandi aziende e open source.
Configurazione semplice per iniziare il fuzzing su Linux, Mac e Windows.
Litefuzz ha lo scopo di servire uno scopo: fare fuzz e triage su tutte le principali piattaforme, supportare sia app CLI/GUI che client e server di rete, al fine di trovare bug relativi alla sicurezza.
Semplifica il processo e rende facile scoprire bug di sicurezza in molti target diversi, su più piattaforme, facendo solo pochi onesti compromessi.
Non è costruito per velocità, scalabilità o per vincere premi accademici. Applica tecniche semplici da diverse angolazioni per ottenere risultati. Per il fuzzing di file basato su console, probabilmente dovresti usare AFL. Ha prestazioni superiori, capacità di strumentazione (ed esecuzioni non strumentate più veloci), scalabilità e può creare dei dannati jpeg dal nulla. Per il fuzzing di rete, anche il mutiny fuzzer funziona bene se hai PCAP da riprodurre e frizzer sembra promettente. Ma se vuoi provare questo, può fare fuzzing su quei tipi di target su più piattaforme con un solo strumento.
./ e dai al tuo target... un lite fuzz.``` $ sudo apt install -y latex2rtf
$ ./litefuzz.py -l -c "latex2rtf FUZZ" -i input/tex -o crashes/latex2rtf -n 1000 -z --========================-- --======| litefuzz |======-- --========================--
[STATS] run id: 3516 cmdline: latex2rtf FUZZ crash dir: crashes/latex2rtf input dir: input/tex inputs: 1 iterations: 1000 mutator: random(mutators)
@ 1000/1000 (3 crashes, 127 duplicates, ~0:00:00 remaining)
[RESULTS]
completed (1000) iterations with (3) unique crashes and 127 dups
check crashes/latex2rtf for more details
Questo è un semplice target locale che AFL++ è perfettamente in grado di gestire ed è fornito solo come esempio rapido. Litefuzz è stato progettato per fare molto di più in termini di fuzzing di rete e GUI, come vedrai una volta che approfondirai.
## Perché
Sì, un altro fuzzer e uno che non segue perfettamente le tendenze e le convenzioni attuali. Sono stati fatti dei compromessi per soddisfare determinati requisiti. Questi requisiti sono: un fuzzer che funzioni per impostazione predefinita su più piattaforme, che fuzzifichi target sia locali che di rete e che sia molto facile da usare. Non stiamo cercando di convincere nessuno di niente, ma forniamo un po' di contesto. Alcuni target richiedono molto sforzo per integrare fuzzer come AFL nella catena di compilazione. Questo non è un problema perché questo fuzzer non richiede strumentazione, sacrificando la copertura precisa ottenuta dalla strumentazione per facilità d'uso e portabilità. AFL inoltre non supporta il fuzzing di rete nativamente, e sebbene esistano progetti basati su di esso che lo fanno, sono tutt'altro che semplici da usare e di solito richiedono più modifiche al codice e harness per funzionare (storia simile con [Libfuzzer](https://llvm.org/docs/LibFuzzer.html)).
Non esegue fuzzing parallelo, né supporta nulla di simile ai miglioramenti di velocità fulminei che la [modalità persistente](https://lcamtuf.blogspot.com/2015/06/new-in-afl-persistent-mode.html) può offrire, quindi non può scalare nemmeno lontanamente come i fuzzer con tali capacità. Ancora una volta, questo non è un fuzzer all'avanguardia. Ma non richiede codice sorgente, configurare correttamente una build o alcune funzionalità del sistema operativo. Può persino fuzzare alcune GUI di client di rete e app interattive. Vive di risorse locali in molti modi e molte delle funzionalità come i mutatori e la minimizzazione sono state scritte da zero.
È stato progettato per "funzionare e basta" e sono stati dedicati sforzi per automatizzare la configurazione e l'installazione delle poche dipendenze di cui necessita. Questo fuzzer è stato scritto per servire uno scopo, per fornire valore in molti scenari e ambienti target diversi e, cosa più importante e per cui tutti i fuzzer dovrebbero essere giudicati: la capacità di trovare bug. E **trova** [bug](https://github.com/sec-tools/beta/blob/main/README.md#trophies). Non presume che esista il codice sorgente del target, quindi può coprire abbastanza bene il software closed source. Può funzionare come parte di automazione con poche modifiche, ma è orientato ad essere divertente da usare per i ricercatori di vulnerabilità. Tuttavia, è più utile pensarlo come un progetto di R&S piuttosto che un prodotto completo. Inoltre, non c'è una configurazione complicata in cui è leggermente rotto all'inizio o richiede ulteriore lavoro per farlo funzionare su sistemi operativi moderni.
È stato testato su Ubuntu Linux, Mac e Windows e viene fornito con script completamente funzionali che fanno praticamente tutto per te per configurare un ambiente pronto per il fuzzing.
**Una volta completato lo script di configurazione, bastano pochi minuti per iniziare a fuzzare un sacco di target diversi.**
## Come funziona
**Litefuzz supporta tre modalità diverse: locale, client e server.**
Locale significa targeting di binari locali, che su Linux/Mac vengono lanciati tramite subprocess con supporto automatico di triage GDB e LLDB rispettivamente sui crash e tramite [WinAppDbg](https://github.com/MarioVilas/winappdbg) su Windows. I crash vengono scritti in una directory locale dei crash e ordinati per tipo di errore, come read/write AV o SIGABRT/SIGSEGV insieme agli hash dei file. Tutti i crash unici vengono triati mentre fuzza e questi dati insieme all'output del target (se disponibile) vengono anche catturati e inseriti come artefatti nella stessa directory. È anche possibile riprodurre i crash con `--replay` e fornendo il file che causa il crash. In modalità client `local`, la directory di input deve contenere un saluto del server, una risposta o altri dati che un client si aspetterebbe quando si connette a un server.
Al momento è implementato solo un "shot" per il fuzzing di rete senza supporto per sessioni complesse. Il client viene lanciato tramite riga di comando e debuggato come nel caso del fuzzing di file. Un listener viene configurato per supportare questo scenario, sì, è lento e quasi lavoro manuale, ma funziona. Se viene rilevato un crash, viene riprodotto in gdb per ottenere i dettagli del triage. In modalità client `remote`, funziona allo stesso modo tranne che per l'assenza di debug locale / triage dei crash. In modalità server *local*, è simile alla modalità client locale e per la modalità server `remote` si connette semplicemente a un target specificato e invia dati client mutati dall'input fornito dall'utente, ma viene fornito solo un semplice triage: "possiamo ancora connetterci? Se no, probabilmente è crashato sull'ultimo".
Ci sono alcune funzioni di mutazione scritte da zero che fanno per lo più mutazioni casuali con una selezione casuale di input specificati dal flag `-i`. Per il fuzzing di file, basta selezionare la modalità locale e passare la riga di comando del target con FUZZ che indica dove l'app si aspetta il nome del file da analizzare, ad es. `tcpdump -r FUZZ` insieme a una directory di input di "file buoni" da mutare. Per il fuzzing di client di rete, è simile al fuzzing locale, ma bisogna anche fornire i dettagli di connessione tramite `-a`. E se vuoi fuzzare server, usa la modalità server e fornisci un `protocol://address:port` proprio come per i client.
Fuzza alla velocità con cui il target può consumare i dati e uscire, come nel caso della maggior parte delle applicazioni CLI, o per tutto il tempo che hai determinato sia necessario prima che l'esecuzione locale o la connessione di rete scada, il che può essere molto più lento. Niente trucchi di exec o kernel qui. Ma ovviamente, se si scrive un harness che analizza l'input ed esce rapidamente, coprendo una parte specifica del target, questo aiuta. Ma a questo punto, se puoi avvicinarti così tanto al target, probabilmente è meglio usare la [modalità persistente](https://lcamtuf.blogspot.com/2015/06/new-in-afl-persistent-mode.html) o funzionalità simili che altri fuzzer possono offrire.
In breve...
### Cosa fa
- esegue su linux, windows e mac e supporta py2/py3
- fuzza binari CLI/GUI che leggono da file/stdin
- fuzza client e server di rete, open source o proprietari, disponibili per debug locale o remoto
- diff, minimizzazione, replay, ordinamento e triage automatico dei crash
- varie cose come supporto TLS, fuzzing di binari golang e alcuni extra per Mac
- muta l'input con vari mutatori integrati + pyradamsa (Linux)
### Cosa non fa
- strumentazione nativa
- scalare con lavori concorrenti
- fuzzing di sessioni complesse
- monitoraggio remoto di client e server (solo controlli di base, es. connessione)
## Supporto
Testato principalmente su **Ubuntu Linux 20.04** (22.04 e 21.04 testati leggermente), **Windows 10** e **Mac OS 11** (12 testato leggermente). Il fuzzer e gli script di configurazione potrebbero funzionare anche su versioni leggermente più vecchie o più nuove di questi sistemi operativi, ma la maggior parte della ricerca, dei test e dello sviluppo è avvenuta in questi ambienti. Python3 è supportato ed è stato fatto uno sforzo per rendere il codice compatibile anche con Python2, poiché è necessario per il fuzzing su Windows tramite [WinAppDbg](https://github.com/MarioVilas/winappdbg).
I test di piattaforma sono avvenuti principalmente su hardware Intel, ma le cose sembrano funzionare per lo più anche sulla piattaforma M1 di Apple (eccezioni notevoli: su Linux il plugin exploitable per GDB probabilmente non è supportato, così come Pyradamsa). Ci sono anche script di configurazione in setup/ per automatizzare la maggior parte o tutte le attività e l'installazione delle dipendenze. Può generalmente fuzzare binari nativi su ciascuna piattaforma, che sono spesso compilati in C/C++, ma cattura anche crash per binari Golang (sperimentale).
### Versioni di Python
Python3 è supportato per Linux e Mac mentre Python2 è richiesto per Windows.
Perché Py3 per Linux e Mac? Pyautogui, Pyradamsa (solo Linux), miglior supporto socket su Mac.
Perché Py2 per Windows? Winappdbg richiede Py2.
### Linux
GDB per il debug e [exploitable](https://github.com/jfoote/exploitable) per il triage dei crash. Se è OSS, puoi compilare e strumentare il target con [sanitizer](https://fuzzing-project.org/tutorial2.html) e simili, altrimenti ci sono alcuni [debugger di memoria](https://en.wikibooks.org/wiki/Linux_Applications_Debugging_Techniques/Heap_corruption) che possiamo semplicemente caricare a runtime.
Questa installazione insieme alle dipendenze python e altre cose utili è stata automatizzata con [setup/linux.sh](https://github.com/sec-tools/litefuzz/blob/HEAD/setup/linux.sh). Il sistema operativo consigliato è Ubuntu 20.04 poiché è dove è avvenuta la maggior parte dei test.
### Mac
Invece di gdb, usiamo lldb per il debug su OS X poiché è incluso negli strumenti da riga di comando di XCode. Essere amministratore o nel gruppo sviluppatori dovrebbe permetterti di usare lldb, ma questo comportamento può differire tra ambienti e versioni e potresti aver bisogno di eseguirlo con privilegi sudo se tutto il resto fallisce.
L'unica cosa che dovrai fare manualmente è disattivare SIP (in recovery, tramite cmd+R o usando trucchi vmware fusion). Altrimenti, il triage automatico fallirà quando si fuzza sul sistema operativo di Tim Apple.
Quasi tutta la configurazione è stata automatizzata con lo script [setup/mac.sh](https://github.com/sec-tools/litefuzz/blob/HEAD/setup/mac.sh), quindi puoi semplicemente eseguirlo per un avvio rapido.
### Windows
[WinAppDbg](https://github.com/MarioVilas/winappdbg) viene utilizzato per il debug su Windows con la piccola avvertenza che il fuzzing su stdin non è supportato.
Come le configurazioni automatizzate per gli altri sistemi operativi, chocolatey aiuta ad automatizzare l'installazione dei pacchetti su Windows. Esegui [setup/windows.bat](https://github.com/sec-tools/litefuzz/blob/HEAD/setup/windows.bat) nella directory principale di litefuzz come Amministratore per automatizzare le installazioni. Installerà strumenti di debug e altre dipendenze per far funzionare tutto senza intoppi.
### Target
Questa è una lista dei tipi di target che sono stati testati e generalmente supportati.
* App CLI/GUI locali che analizzano formati di file o stdin
- supporto debug
* Client di rete CLI/GUI locale che analizza risposte del server
- supporto debug per CLI
- supporto debug limitato per GUI
* Server di rete CLI locale che analizza richieste client
- supporto debug (avvertenza: deve poter essere eseguito come eseguibile standalone, altrimenti può essere trattato come *remoto*)
* Server di rete GUI locale che analizza richieste client
- teoricamente supportato, non testato
* Client di rete CLI/GUI remoto che analizza risposte del server
- nessun supporto debug
* Server di rete CLI/GUI remoto che analizza richieste client
- nessun supporto debug
- eccezione su Mac e utilizzando le funzionalità `attach` o `reportcrash`
Ancora, il fuzzer può funzionare e supportare app locali, client e server su Linux, Mac e Windows e naturalmente può fuzzare cose remote indipendentemente dalla piattaforma del target.
### Triage
* App CLI/GUI locali che analizzano formati di file o stdin
- esegui app, cattura segnali, riproduci eseguendola di nuovo in un debugger con il crashante
* Client di rete CLI/GUI locale che analizza risposte del server
- esegui app, cattura segnali, riproduci eseguendola di nuovo in un debugger con il crashante
* Server di rete GUI/CLI locale che analizza richieste client
- esegui app in debugger, cattura segnali, riproduci eseguendola di nuovo in un debugger con il crashante
* Client di rete CLI/GUI remoto che analizza risposte del server
- nessuna visibilità, raccogli crash dal lato remoto
- può scrivere manualmente script di supporto per aiutare nel triage
* Server di rete CLI/GUI remoto che analizza richieste client
- nessuna visibilità, raccogli crash dal lato remoto
- può scrivere manualmente script di supporto per aiutare nel triage
- eccezione su Mac sono le opzioni `attach` e `reportcrash`, che possono essere utilizzate per abilitare alcune capacità di triage
## Per iniziare
La maggior parte della configurazione su tutte le piattaforme è stata automatizzata con gli script nella directory [setup](https://github.com/sec-tools/litefuzz/blob/main/README.md#setup).
Basta eseguirli dalla directory principale di litefuzz e ti farà risparmiare molto tempo e aiuterà ad abilitare parte di ciò che è necessario per distribuzioni automatizzate. È utile usare una VM per impostare un sistema operativo pulito e un ambiente di fuzzing, poiché tra le altre cose le sue capacità di snapshot sono utili.
Vedi [INSTALL.md](https://github.com/sec-tools/litefuzz/blob/main/INSTALL.md) per i dettagli.
**Dopo l'installazione, fai riferimento all'esempio di fuzzing di latex2rtf nella sezione iniziale per un'esecuzione rapida o approfondisci tutte le opzioni della riga di comando e ulteriori esempi dettagliati in questo README.**
### Docker
Puoi eseguire litefuzz usando Docker con il `Dockerfile` senza installare dipendenze localmente. Questo è particolarmente utile per test rapidi o se vuoi evitare di installare dipendenze sul tuo sistema.
Il Dockerfile funziona in entrambi i modi:
- **Dall'interno del repo** - Usa file locali (più veloce, include modifiche locali)
- **Standalone** - Può essere costruito da qualsiasi directory (clona da GitHub)```bash
# Build the Docker image (from any directory with Dockerfile)
docker build -t litefuzz:latest .
# Run litefuzz
docker run --rm litefuzz:latest python3 litefuzz.py --help
L'input integrato dal repository è disponibile in /litefuzz/input/tex - non è necessario montare l'input:```bash
mkdir -p crashes
docker run --rm
-v $(pwd)/crashes:/tmp/crashes
litefuzz:latest
python3 litefuzz.py -l -c "latex2rtf FUZZ" -i /litefuzz/input/tex -o /tmp/crashes -n 1000 -z
Questo farà:
- Esegui fuzzing su latex2rtf con 1000 iterazioni
- Utilizza il debug dell'heap (flag `-z`)
- Salva i crash nella directory `./crashes` sul tuo host
- Utilizza i file di input predefiniti dal repository in `/litefuzz/input/tex`
Se desideri utilizzare i tuoi file di input dall'host:```bash
# Create input directory with your test files
mkdir -p input/tex crashes
# Add your test files to input/tex/
cp your-test.tex input/tex/
# Run fuzzing with your input files
docker run --rm \
-v $(pwd)/input:/litefuzz/input \
-v $(pwd)/crashes:/tmp/crashes \
litefuzz:latest \
python3 litefuzz.py -l -c "latex2rtf FUZZ" -i /litefuzz/input/tex -o /tmp/crashes -n 1000 -z
Importante: Monta l'input solo se hai file da usare. Montare una directory input/ vuota sovrascriverà l'input integrato e causerà errori.
/litefuzz/input/tex (nessun mount necessario)-v per persistere gli output di crash e accedere ai file di input--network host per il fuzzing di rete per accedere ai servizi localhost--cap-add=SYS_PTRACECi sono alcuni semplici test unitari e funzionali per ottenere una certa copertura per Litefuzz, ma non sono pensati per essere completi.``` py2> pytest py3> python3 -m pytest
Questo eseguirà pytest per `test_litefuzz.py` nella directory principale e fornirà risultati PASS/FAIL una volta terminata l'esecuzione del test.
#### test di app che crashano
Alcuni esempi di app buggate per testare le capacità di crash e triage sulle diverse piattaforme si trovano nella cartella `test`.
- (a) dereferenza di puntatore nullo
- (b) divisione per zero
- (c) overflow dello heap
- (d-gui) bug di stringa di formato in una GUI
- (e) overflow del buffer nel client
- (f) overflow del buffer nel server
Vengono automaticamente compilati durante l'installazione e puoi eseguirli da riga di comando, in un debugger o usarli per testare come target di fuzzing.
**Se esegui su riga di comando Windows, controlla `Visualizzatore eventi -> Log di Windows -> Applicazione` per vedere i crash.**
## opzioni
Ci sono moltissime opzioni e funzionalità diverse per sfruttare vari scenari di target. Quella che segue è una breve spiegazione e alcuni esempi per aiutare a capire come usarle.
### directory dei crash
`-o` ti permette di specificare una directory dei crash diversa da quella predefinita, che è `crashes/` nel percorso locale. Si può usare per gestire le cartelle dei crash per diverse esecuzioni di fuzzing concorrenti per app diverse contemporaneamente.
### modalità isolamento
`-u` isola l'applicazione target dal normale processo di fuzzing, ad es. esecuzioni o invio di pacchetti ripetutamente e controllo dei crash. Invece, questa modalità è stata creata per applicazioni client interattive, ad es. Postman dove puoi scrivere script all'interno dell'applicazione per ripetere le connessioni per il fuzzing lato client. Il target viene eseguito all'interno di un debugger, il fuzzer viene messo in pausa per dare all'utente il tempo di cliccare alcuni pulsanti o impostare la configurazione del target per farlo eseguire automaticamente, l'utente riprende e ora stai eseguendo il fuzzing di client di rete interattivi.
`litefuzz -lk -c "/snap/postman/140/usr/share/Postman/_Postman" -i input/http_responses -a tcp://localhost:8080 -u -n 100000 -z`
La modalità isolamento + refresh può essere usata per client interattivi, ad es. esegui FileZilla in un debugger, ma continua a premere F5 per farlo riconnettere al server per ogni nuova iterazione. Inoltre, i server locali CLI/GUI vengono avviati ed eseguiti una sola volta all'interno di un debugger per rendere il processo un po' più efficiente.
`--key` ti permette anche di inviare tasti mentre si esegue il fuzzing di target interattivi, come il fuzzing del parsing delle risposte del server FTP di FileZilla inviando "refresh connection" con F5.
`litefuzz -lk -c "filezilla" -a tcp://localhost:2121 -i input/ftp/filezilla -u -pp --key "F5" -n 100 -z glibc`
nota: la modalità isolamento è stata testata solo su Linux e non è supportata su Windows.
### timeout
`-x secs` ti permette di specificare un timeout. In pratica, è più simile a "quanto tempo circa tra le iterazioni" per target CLI e un timeout effettivo per GUI.
### mutatori
`--mutator N` specifica quale mutatore usare per il fuzzing. Se l'opzione non viene fornita, viene scelta una scelta casuale dall'elenco dei mutatori disponibili per ogni iterazione di fuzzing.
Questi mutatori sono stati scritti da zero (con l'eccezione di Radamsa ovviamente). E sebbene siano stati ampiamente testati e abbiano retto abbastanza bene durante milioni di iterazioni, possono avere bug sottili di tanto in tanto, ma generalmente ciò non dovrebbe influire sulla funzionalità.```
FLIP_MUTATOR = 1
HIGHLOW_MUTATOR = 2
INSERT_MUTATOR = 3
REMOVE_MUTATOR = 4
CARVE_MUTATOR = 5
OVERWRITE_MUTATOR = 6
RADAMSA_MUTATOR = 7
nota: il mutatore Radamsa è disponibile solo su Linux (+ Py3).
--reportcrash è specifico per Mac. Invece di utilizzare il sistema di triage predefinito, istruisce il fuzzatore a monitorare la directory ReportCrash alla ricerca di log di crash per il processo target. ReportCrash deve essere abilitato su OS X (abilitato per impostazione predefinita, ma di solito disabilitato per il fuzzing normale). Questa funzionalità è utile in scenari in cui non possiamo eseguire il target in un debugger per generare e gestire i nostri log di crash, ma possiamo sfruttare questa funzionalità principale del sistema operativo per ottenere visibilità.
nota: considerare questa funzionalità sperimentale, poiché ci affidiamo a diverse parti mobili e componenti che non controlliamo direttamente all'interno del sistema MacOS di base. ReportCrash potrebbe eventualmente smettere di funzionare correttamente e di rispondere dopo un po' di fuzzing, anche dopo aver tentato di scaricarlo e ricaricarlo, quindi si può provare a riavviare la macchina o resettare lo snapshot per riportarlo in buono stato.``` sudo launchctl unload -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist sudo launchctl load -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist
### pausa
Premere ctrl+c per mettere in pausa il processo di fuzzing. Per riprendere, scegliere `y` o `n` per interrompere. Questa funzionalità funziona bene su diverse piattaforme, ma potrebbe essere meno affidabile durante il fuzzing di app GUI.
### riutilizzo dei crash per la ricerca di varianti
`-e` abilita la modalità di riutilizzo. Ciò significa che se vengono trovati dei crash durante l'esecuzione del fuzzing, verranno utilizzati come input per un secondo ciclo di fuzzing, che può aiutare a scovare ancora più bug. Combinalo con `-z` per ottenere bug `-ez`! Da-duph.
L'esempio seguente esegue il fuzzing di antiword con 100000 iterazioni e poi avvia un'altra esecuzione con lo stesso numero di iterazioni e opzioni per riutilizzare i crash come input e cercare di estrarre ancora più bug.
`litefuzz -l -c "antiword FUZZ" -i docs -n 100000 -ez`
(oppure si possono copiare manualmente i crash in una directory di input per controllare direttamente le iterazioni per l'esecuzione di riutilizzo)
`litefuzz -l -c "antiword FUZZ" -i docs-crashes -n 500000 -z`
nota: questa modalità è supportata solo per app locali.
### helper per il debugging della memoria
`-z` abilita Electric Fence (o glib malloc debugging come fallback) su Linux, Guard Malloc su Mac e PageHeap su Windows. Inoltre, `-zz` può essere usato per disabilitare PageHeap dopo averlo abilitato per un'applicazione. Se si vuole semplicemente attivarlo/disattivarlo senza avviare il fuzzer, basta omettere il flag `-i`. Durante l'installazione su Windows, [gsudo](https://github.com/gerardog/gsudo) viene installato e può essere usato per eseguire comandi elevati nella riga di comando, ad esempio per attivare PageHeap per i target.
`sudo litefuzz -l -c "notepad FUZZ" -i texts/files -z`
`sudo litefuzz -l -c "notepad FUZZ" -zz`
Su Linux è possibile scegliere helper specifici. Ad esempio, invece di usare semplicemente glib malloc come fallback, può essere selezionato esplicitamente.
`litefuzz -l -c "geany FUZZ" -i texts/codes -z glibc`
Il debugger di default Electric Fence malloc è ottimo, ma non funziona con tutti i target. Puoi testare il target con EF e, se crasha, selezionare invece l'helper glibc.
### controllo dell'output live del target
Se si esegue il fuzzing di app locali su Linux o Mac, puoi eseguire `cat /tmp/litefuzz/RUN_ID/fuzz.out` per controllare l'ultimo stdout prodotto dal target. `RUN_ID` viene mostrato nell'area STATS quando il fuzzing inizia. In caso di crash, lo stdout viene anche catturato nella directory dei crash come file `.out`. Anche stdout/stderr globali vengono inviati a `/tmp/litefuzz/out` a scopo di debug per tutti i target di fuzzing, ad eccezione delle modalità insulated o local server, per le quali l'output del debugger va a `/tmp/litefuzz/RUN_ID/out`.
Winappdbg non supporta nativamente la cattura dello stdout dei target (AFAIK), quindi questo artefatto non è disponibile su Windows.
### modalità client e server
Se il server può essere eseguito localmente semplicemente lanciando il binario (con o senza alcuni flag e configurazioni), puoi passare la sua riga di comando con `-c` e verrà avviato, sottoposto a fuzzing e terminato con una nuova esecuzione a ogni iterazione. L'idea è di scambiare velocità con la capacità di evitare quei fastidiosi bug che si attivano solo quando la memoria del target si trova in un "certo stato", i quali possono portare a falsi positivi. Stesso discorso per il fuzzing locale di client di rete. Supporta anche connessioni TLS, generando certificati al volo (permettere all'utente di fornire un certificato client durante il fuzzing di un server che lo richiede e il fuzzing dei certificati stessi sono altre idee qui).
Il supporto al debugging non è fornito da Litefuzz quando si esegue il fuzzing di client e server remoti, quindi la configurazione sul lato remoto è a carico dell'utente. Per i server, controlliamo semplicemente se il server ha smesso di rispondere e annotiamo il payload precedente come il crash. Questo funziona bene per connessioni TCP, ma non abbiamo questa comodità per i servizi UDP, quindi il monitoraggio del server remoto è lasciato alla funzionalità ReportCrash (disponibile su Mac), all'esecuzione del target in un debugger (tramite modalità server locale o manualmente) o alla creazione di script di supporto personalizzati. Inoltre, alcuni server possono riavviarsi automaticamente o altrimenti riprendersi dopo un crash, ma potrebbero esserci segni di ciò nei log o in altri artefatti sul filesystem che possono essere analizzati da script di supporto scritti per un target specifico.
### esempi di rete locale
`litefuzz -lk -c "wget http://localhost:8080" -a tcp://localhost:8080 -i input/http -z`
`litefuzz -lk -c "curl -k https://localhost:8080" -a tcp://localhost:8080 -i input/http -z`
`litefuzz -lk -c "curl -k https://localhost:8080" -a tcp://localhost:8080 -i input/http -o crashes/curl --tls -n 100000 -z`
(apri Wireshark e cattura la risposta da un
d, fai clic destro su Simple Network Management Protocol -> Export Packet Bytes -> resp.bin)
`litefuzz -lk -c "snmpwalk -v 2c -c public localhost:1616 1.3.6.1.2.1.1.1" -a udp://localhost:1616 -i input/snmp/resp.bin -n 1 -d -x 3`
`litefuzz -ls -c "./sc_serv shoutcast.conf" -a localhost:8000 -i input/shouts -z`
`litefuzz -ls -c "snmpd" -i input/snmp -a udp://localhost:161 -z`
**note rapide**
- I socket UDP possono comportarsi in modo strano su Mac + Py2, quindi solo Mac + Py3 è stato testato e supportato
- Il fuzzing di client di rete locale su Windows può essere instabile e va considerato sperimentale al momento
### esempi di rete remota
Il fuzzing di client e server remoti è un po' più impegnativo: non abbiamo debugging locale e ci affidiamo alla rilevazione di un'interruzione nell'interazione tra le due parti sulla rete per catturare i crash. Inoltre, poiché presumibilmente siamo ciechi su ciò che accade dall'altra parte, il fuzzing termina quando il client o il server smette di rispondere e deve essere riavviato manualmente dopo che il client o il server è stato ripristinato a uno stato normale (non crashato), a meno che l'utente non abbia configurato script sul lato remoto per gestire questo processo.
UDP complica ulteriormente la cosa. Anche l'invio di un pacchetto di prova per verificare se esiste un servizio in ascolto su una porta UDP non garantisce una risposta. Quindi è possibile eseguire il fuzzing remoto di client e server di rete, ma c'è un compromesso sulla visibilità.
#### client
`while :; do echo "user test\rpass test\rls\rbye\r" | ftp localhost 2121; sleep 1; done`
`litefuzz -k -i input/ftp/test -a tcp://localhost:2121 -pp -n 100`
La modalità client qui è più delicata perché è difficile capire se un client è effettivamente crashato e quindi non si riconnette, o se la danza di invio/ricezione è semplicemente fuori sincrono, dato che diversi client possono gestire le connessioni a modo loro. Nota anche che questo è solo un esempio e che il fuzzing remoto di client per sua natura è complesso e va considerato un po' sperimentale.
#### server
I pro e i contro del fuzzing di un server localmente o remotamente possono aiutarti a decidere come approcciare un target quando entrambe le opzioni sono disponibili.
In pratica, il fuzzing con il server in un debugger sarà più lento ma potrai ottenere log di crash con il triage automatico, mentre il fuzzing del server in modalità remota (anche puntandolo a localhost) sarà mediamente molto più veloce, ma perdi l'elevata visibilità e le capacità di triage basate sul debugger, ma ti dà tempo per riavviare manualmente il server dopo ogni crash per continuare prima che esca (solo per server TCP, la funzionalità non supporta server basati su UDP).
**Shoutcast**
`./sc_serv ...`
`litefuzz -s -a localhost:8000 -i input/shouts -n 10000`
**SSHesame**
`sshesame`
`litefuzz -s -a tcp://target:2022 -i input/ssh-server -p -n 1000000 -x 0.05`
**FTP**
`litefuzz -s -a tcp://target:21 -i input/ftp/req.txt -pp -n 1000`
**DNS**
`coredns -dns.port 10000`
`litefuzz -ls -c "coredns -dns.port 10000" -a udp://localhost:10000 -i dns-req/1.bin -o crashes/coredns -n 10000`
oppure
`litefuzz -s -a udp://localhost:10000 -i dns-req/1.bin -o crashes/coredns -n 10000`
##### TLS
`litefuzz -s -a tcp://hostname:8080 -i input/http --tls -n 10000````
...
@ 48/10000 (1 crashes, 0 duplicates, ~7:13:18 remaining)
[!] check target, sleeping for 60 seconds before attempting to continue fuzzing...
nota: i ritardi predefiniti della modalità server remoto tra le iterazioni di fuzzing possono rendere le sessioni di fuzzing affidabili, ma sono piuttosto lenti; questa è l'impostazione predefinita sicura, ma è possibile usare -x per impostare timeout molto rapidi tra le sessioni (come mostrato sopra) se il target è in grado di analizzare i pacchetti molto rapidamente, soprannominata ufficiosamente modalità "2fast2furious"
Per ulteriori informazioni sui protocolli basati su sessioni (come FTP o SSH), consultare le modalità Multiple.
-p è per la modalità di dati binari multipli, che consente di fornire input sequenziali, ad esempio la directory input/ssh contenente file denominati "1", "2", "3", ecc. per ogni pacchetto nella sessione da fuzzare. Questo è pensato per consentire il fuzzing di implementazioni di protocolli basati su binari, come il client SSH.
ls input/ssh
1 2 3 4
`xxd input/ssh/2 | head```` 00000000: 0000 041c 0a14 56ff 1297 dcf4 672d d5c9 ......V.....g-.. 00000010: d0ab a781 dfcb 0000 00e6 6375 7276 6532 ..........curve2 00000020: 3535 3139 2d73 6861 3235 362c 6375 7276 5519-sha256,curv 00000030: 6532 3535 3139 2d73 6861 3235 3640 6c69 e25519-sha256@li 00000040: 6273 7368 2e6f 7267 2c65 6364 682d 7368 bssh.org,ecdh-sh 00000050: 6132 2d6e 6973 7470 3235 362c 6563 6468 a2-nistp256,ecdh 00000060: 2d73 6861 322d 6e69 7374 7033 3834 2c65 -sha2-nistp384,e 00000070: 6364 682d 7368 6132 2d6e 6973 7470 3532 cdh-sha2-nistp52 00000080: 312c 6469 6666 6965 2d68 656c 6c6d 616e 1,diffie-hellman 00000090: 2d67 726f 7570 2d65 7863 6861 6e67 652d -group-exchange-
Ogni pacchetto viene inserito in un array, un indice casuale viene mutato e riprodotto per fare fuzzing sul target.
`litefuzz -lk -c "ssh -T test@localhost -p 2222" -a tcp://localhost:2222 -i input/ssh -o crashes/ssh -p -n 250000 -z glibc`
E puoi controllare l'output del target per l'iterazione più recente.```
cat /tmp/litefuzz/out
kex_input_kexinit: discard proposal: string is too large
ssh_dispatch_run_fatal: Connection to 127.0.0.1 port 2222: string is too large
... and others like
ssh_dispatch_run_fatal: Connection to 127.0.0.1 port 2222: unknown or unsupported key type
ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory
Host key verification failed.
Bad packet length 1869636974.
ssh_dispatch_run_fatal: Connection to 127.0.0.1 port 2222: message authentication code incorrect
-pp chiede al fuzzer di controllare gli input per individuare interruzioni di riga e, se rilevate, di trattarli come richieste/risposte multiple. Ciò è utile per il fuzzing di semplici protocolli di rete per implementazioni prevalentemente basate su stringhe, ad esempio client ftp.```
cat input/ftp/test
220 ProFTPD Server (Debian) [::ffff:localhost]
331 Password required for user
230 User user logged in
215 UNIX Type: L8
221 Goodbye
Il fuzzer suddivide ogni linea nella propria risposta FTP per tentare di testare la gestione di una sessione da parte di un client. Non c'è alcuna garanzia, tuttavia, che un client si "comporti" o agisca in modi che non consentano a una sessione di completarsi correttamente, quindi un po' di tentativi ed errori + messa a punto per i casi di test della sessione durante l'esecuzione di Wireshark può essere utile per comprendere le differenze nell'interazione tra i target.
`litefuzz -lk -c "ftp localhost 2121" -a tcp://localhost:2121 -i input/ftp -o crashes/ftp -n 100000 -pp -z`
Questo può anche essere combinato con *-u* per isolare target di rete GUI come FileZilla.
`litefuzz -lk -c "filezilla" -a tcp://localhost:2121 -i input/ftp.resp -n 100000 -u -pp -z glibc`
### collegamento a un processo
Se il target genera un nuovo processo alla connessione, è possibile specificare il nome di un processo (o pid) a cui collegarsi dopo che una connessione è stata stabilita con il server. Ciò è utile in casi in cui, ad esempio, launchd è in ascolto su una porta e avvia il processo di gestione solo quando un client è connesso. Questa è una caratteristica che in qualche modo sfuma la linea tra fuzzing locale e remoto, poiché tecnicamente il fuzzer è in modalità remota, ma specifichiamo l'indirizzo del target come localhost e gli chiediamo di collegarsi a un processo.
`./litefuzz.py -s -a tcp://localhost:8080 -i input/shareserv -p --attach ShareServ -x 1 -n 100000`
nota: attualmente questa funzionalità è supportata solo su Mac (LLDB) e per il fuzzing di rete, anche se se implementata dovrebbe funzionare bene anche su Linux (GDB).
### artefatti di crash
Quando si verifica un crash durante il fuzzing, viene riprodotto in un debugger per produrre artefatti di debug e informazioni di raggruppamento. Le informazioni variano da piattaforma a piattaforma, ma generalmente viene prodotto un file di testo con un backtrace, informazioni sui registri, cose del tipo `!exploitable` (dove disponibile) e altre informazioni di base.
**Dump di memoria** possono essere abilitati su Windows passando `--memdump` o disabilitati con `--nomemdump` in modo simile a come i debugger malloc sono controllati rispettivamente con `-z` e `-zz`. Se abilitato, il dump verrà anche caricato nel debugger console (cdbg) e l'output dell'analisi del crash `!analyze -v` viene catturato all'interno di un log di analisi del crash del dump di memoria aggiuntivo. Winappdbg ha già un'analisi di tipo !exploitable che otteniamo nell'analisi del crash iniziale, quindi qui facciamo solo !analyze.
`litefuzz -l -c "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" --memdump`
o per disabilitare i dump di memoria per un'applicazione
`litefuzz -l -c "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" --nomemdump`
Oltre al triage automatico dei crash, vengono prodotti anche diff binari/di stringa (come appropriato) e stdout del target (dipendente dalla piattaforma/target) e ovviamente i file di riproduzione.
Per il fuzzing locale, gli artefatti generalmente includono diff, stdout (solo linux/mac), file di riproduzione e il log del crash e il file informativo.```
$ ls crashes/latex
PROBABLY_EXPLOITABLE_SIGSEGV_XXXX5556XXXX_YYYYa39f3fd719e170234435a1185ee9e596c54e79092c72ef241eb7a41cYYYY.diff
PROBABLY_EXPLOITABLE_SIGSEGV_XXXX5556XXXX_YYYYa39f3fd719e170234435a1185ee9e596c54e79092c72ef241eb7a41cYYYY.diffs
PROBABLY_EXPLOITABLE_SIGSEGV_XXXX5556XXXX_YYYYa39f3fd719e170234435a1185ee9e596c54e79092c72ef241eb7a41cYYYY.out
PROBABLY_EXPLOITABLE_SIGSEGV_XXXX5556XXXX_YYYYa39f3fd719e170234435a1185ee9e596c54e79092c72ef241eb7a41cYYYY.tex
PROBABLY_EXPLOITABLE_SIGSEGV_XXXX5556XXXX_YYYYa39f3fd719e170234435a1185ee9e596c54e79092c72ef241eb7a41cYYYY.txt
Su Windows, se i dump della memoria sono abilitati, verrà generato un file di dump e ulteriori informazioni di triage verranno scritte in un ulteriore registro di analisi degli arresti.``` C:\litefuzz\crashes> dir app.exe.14299_YYYYa39f3fd719e170234435a1185ee9e596c54e79092c72ef241eb7a41cYYYY.dmp app.exe.14299_YYYYa39f3fd719e170234435a1185ee9e596c54e79092c72ef241eb7a41cYYYY.log ....
Per il fuzzing remoto, gli artefatti possono variare a seconda delle opzioni scelte, ma spesso includono diff, file di repro e/o directory di repro file (se l'input è una sessione con più pacchetti), repro dell'iterazione di fuzzing precedente (per evitare di perdere un bug nel caso sia effettivamente il crash, poiché il fuzzing remoto ha le sue sfide) e log di crash o file di informazioni brevi.```
ls crashes/serverd
REMOTE_SERVER_testbox.1_NNNN_XXXX9c3f3660aaa76f70515f120298f581adfa9caa8dcaba0f25a2bc0b78YYYY
REMOTE_SERVER_testbox.1_NNNN_PREV_XXXX9c3f3660aaa76f70515f120298f581adfa9caa8dcaba0f25a2bc0b78YYYY
UNKNOWN_XXXX2040YYYY_XXXX9c3f3660aaa76f70515f120298f581adfa9caa8dcaba0f25a2bc0b78YYYY.diff
UNKNOWN_XXXX2040YYYY_XXXX9c3f3660aaa76f70515f120298f581adfa9caa8dcaba0f25a2bc0b78YYYY.diffs
UNKNOWN_XXXX2040YYYY_XXXX9c3f3660aaa76f70515f120298f581adfa9caa8dcaba0f25a2bc0b78YYYY.txt
UNKNOWN_XXXX2040YYYY_XXXX9c3f3660aaa76f70515f120298f581adfa9caa8dcaba0f25a2bc0b78YYYY.zz
ls crashes/serverd/REMOTE_SERVER_localhost_NNNN_XXXX9c3f3660aaa76f70515f120298f581adfa9caa8dcaba0f25a2bc0b78YYYY
REMOTE_SERVER_testbox.1_NNNN_1.zz REMOTE_SERVER_localhost_NNNN_2.zz
REMOTE_SERVER_testbox.1_NNNN_3.zz REMOTE_SERVER_localhost_NNNN_4.zz
A quanto pare, quando i binari Golang vanno in crash, potrebbero non arrestarsi effettivamente con un tradizionale SIGSEGV, anche se è quello che indicano nelle informazioni di panico (testato su Linux). Potrebbero invece arrestarsi con codice di uscita 2. Quindi immagino che sia quello che useremo :)
Sono certo che esista una spiegazione migliore su come funziona e sui casi limite, ma si può usare --golang per provare a intercettare i crash nei binari Golang su Linux.
litefuzz -l -c "evernote2md FUZZ" -i input/enex -o crashes/evernote2md --golang -n 100000
I file che causano il crash vengono conservati nella directory crashes/ (o in quella specificata con l'opzione -o) insieme ai diff e alle informazioni sul crash.
-r e il passaggio di un file di riproduzione (o una directory) con la riga di comando/indirizzo del target appropriato tenterà di riprodurre il crash localmente o in remoto.
esempio locale
litefuzz -l -c "latex2rtf FUZZ" -r crashes/latex2rtf/test.tex -z
esempio di rete locale
./litefuzz -ls -c "./sc_serv shoutcast.conf" -a tcp://localhost:8000 -r crashes/crash.raw
esempio di rete remota
litefuzz -s -a tcp://host:8000 -r crashes/crash.raw
esempio di rete remota (pacchetti multipli)
litefuzz -s -a tcp://localhost:22 -r repro/dir/here
Alcuni target richiedono una posizione statica per il file di output come parte della riga di comando e potrebbero generare un errore se quel file esiste già. --rmfile è un'opzione per aggirare questo problema durante il fuzzing: dopo ogni iterazione di fuzzing, rimuoverà il file generato come parte del funzionamento del target.
litefuzz -l -c "hdiutil makehybrid -o /tmp/test.iso -joliet -iso FUZZ" -i input/dmg --rmfile /tmp/test.iso -n 500000 -ez
Minimizzare i file che causano crash è un'attività interessante. Puoi persino dedurre come un target sta analizzando i dati confrontando un file di riproduzione con una versione minimizzata.
-m e il passaggio di un file di riproduzione con la riga di comando o l'indirizzo del target tenterà di generare una versione minimizzata della riproduzione che continua a far crashare il target, ma più piccola e senza byte potenzialmente non necessari. Durante questo percorso di minimizzazione, potrebbe persino trovare nuovi crash.
Sono supportate solo modalità locali, ma questo include ancora le modalità client locale e server locale, quindi puoi minimizzare crash di rete purché possiamo eseguirne il debug localmente.
Ad esempio, questa richiesta è il file di riproduzione originale.``` GET /admin.cgi?pass=changeme&mode=debug&option=donotcrash HTTP/1.1 Host: localhost:8000 Connection: keep-alive Authorization: Basic YWRtaW46Y2hhbmdlbWU= Referer: http://localhost:8000/admin.cgi?mode=debug
Dai un'occhiata alla sua versione minimizzata.```
GET /admin.cgi?mode=debug&option=a
Authorization:s YWRtaW46Y2hhbmdlbWU
Referer:admin.cgi
Ora possiamo fare alcune ipotesi su cosa sta cercando il target e persino sulla causa principale del crash.
Qualcos'altro? Ecco un bonus: non è necessario passare una password valida se le credenziali Authorization sono corrette, e viceversa. Poiché la minimizzazione è lineare e inizia all'inizio del file e prosegue fino alla fine, produrremmo solo una riproduzione che autentica in questo modo, scoprendo comunque che ci sono effettivamente due opzioni!
-mm abilita la modalità supermin. È più lenta, ma proverà a minimizzare più e più volte finché non ci saranno più byte superflui da rimuovere.
Per divertimento, possiamo modificare la riproduzione ed eseguirla tramite supermin per ottenere la versione massimamente minimizzata.```
GET /admin.cgi?pass=changeme&mode=debug&option=a
Referer:admin.cgi
**esempi di minimizzazione**
`litefuzz -l -c "latex2rtf FUZZ" -m test.tex -z`
`litefuzz -ls -c "./sc_serv shoutcast.conf" -a "tcp://localhost:8000" -m repro.http`
**esempio supermin**```
litefuzz -l -c "latex2rtf FUZZ" -mm crashes/latex2rtf/test.tex -z
...
[+] starting minimization
@ 582/582 (1 new crashes, 1145 -> 582 bytes, ~0:00:00 remaining)
[+] reduced crash @ pc=55555556c141 -> pc=55555557c57d to 582 bytes
[+] supermin activated, continuing...
@ 299/299 (1 new crashes, 582 -> 300 bytes, ~0:00:00 remaining)
[+] reduced crash @ pc=55555557c57d to 300 bytes
...
[+] reduced crash @ pc=555555562170 to 17 bytes
@ 17/17 (2 new crashes, 17 -> 17 bytes, ~0:00:00 remaining)
[+] achieved maximum minimization @ 17 bytes (test.min.tex)
[RESULTS]
completed (17) iterations with 2 new crashes found
--cmd permette all'utente di specificare un comando da eseguire dopo ogni iterazione. Può essere utilizzato per pulire determinate operazioni che altrimenti occuperebbero risorse sul sistema.
litefuzz -l -c "/System/Library/CoreServices/DiskImageMounter.app/Contents/MacOS/DiskImageMounter FUZZ" -i input/dmg --cmd "umount /Volumes/test.dir" --click -x 5 -n 100000 -ez
litefuzz -l -c "latex2rtf FUZZ" -i input/tex -o crashes/latex2rtf -x 1 -n 100 --========================-- --======| litefuzz |======-- --========================--
[STATS] run id: 3516 cmdline: latex2rtf FUZZ crash dir: crashes/latex2rtf input dir: input/tex inputs: 4 iterations: 100 mutator: random(mutators)
@ 100/100 (1 crashes, 4 duplicates, ~0:00:00 remaining)
[RESULTS]
completed (100) iterations with (1) unique crashes and 4 dups
check crashes/latex2rtf dir for more details
#### enumerazione dei gestori di file su Ubuntu```
$ cat /usr/share/applications/defaults.list
[Default Applications]
application/csv=libreoffice-calc.desktop
application/excel=libreoffice-calc.desktop
application/msexcel=libreoffice-calc.desktop
application/msword=libreoffice-writer.desktop
application/ogg=rhythmbox.desktop
application/oxps=org.gnome.Evince.desktop
application/postscript=org.gnome.Evince.desktop
....
fuzz il parsing pcap di tcpdump locale (Linux)
litefuzz -l -c "tcpdump -r FUZZ" -i test-pcaps
fuzz il lettore di documenti Evince (Linux GUI)
litefuzz -l -c "evince FUZZ" -i input/oxps -x 1 -n 10000
fuzz antiword (vecchio ma buon test app :) (Linux)
litefuzz -l -c "antiword FUZZ" -i input/doc -ez
nota: puoi (e probabilmente dovresti) passare -z per abilitare Electric Fence (o in alternativa la funzionalità di glibc) per il controllo degli errori di heap
swda può enumerare i gestori di file su Mac.``` $ ./swda getUTIs | grep -Ev "No application set" com.adobe.encapsulated-postscript /System/Applications/Preview.app com.adobe.flash.video /System/Applications/QuickTime Player.app com.adobe.pdf /System/Applications/Preview.app com.adobe.photoshop-image /System/Applications/Preview.app ....
**fuzz decrittografia gpg tramite stdin con controllo errori heap** (Mac)
`litefuzz -l -c "gpg --decrypt" -i test-gpg -o crashes-gpg -z`
**fuzz app Books** (Interfaccia grafica Mac)
`litefuzz -l -c "/System/Applications/Books.app/Contents/MacOS/Books FUZZ" -i test-epub -t "/Users/test/Library/Containers/com.apple.iBooksX/Data" -x 8 -n 100000 -z`
nota: `-z` qui abilita il [Guard Malloc](https://www.manpagez.com/man/3/libgmalloc/) controllo errori heap per rilevare bug di corruzione heap sottili
**nota per Mac**
Alcuni target GUI potrebbero non essere terminati dopo il timeout di ogni iterazione e diventare non reattivi. Per mitigare questo problema, puoi eseguire uno script simile a questo in un altro terminale per terminarli periodicamente in batch, riducendo lo sforzo manuale e il monitoraggio, altrimenti il processo di fuzzing potrebbe essere influenzato.```
#!/bin/bash
ps -Af | grep -ie "$1" | awk '{print $2}' | xargs kill -9
[!NOTE] Questo progetto è stato sviluppato come parte di un corso universitario. È destinato esclusivamente a scopi educativi e di ricerca. L'autore non è responsabile per eventuali abusi.``` $ while :; do ./pkill.sh "Process Name /Users/test"; sleep 360; done
*/Users/test* (esempio per la prima parte del percorso in cui i file temporanei vengono passati all'app GUI locale, FUZZ diventa un percorso durante l'esecuzione) è stato scelto perché è necessaria una stringa univoca per terminare i processi; e se si utilizza solo il nome del processo, verrà terminato anche il processo di fuzzing poiché contiene anch'esso il nome del processo.
**enumerazione dei gestori di file su Windows**
Utilizzando lo script [AssocQueryString](https://github.com/sec-tools/WindowsFileHandlerEnumeration/) con il comando *assoc* è possibile mappare le estensioni dei file alle applicazioni predefinite.```
C:\> .\AssocQueryString.ps1
...
.hlp :: C:\Windows\winhlp32.exe
.hta :: C:\Windows\SysWOW64\mshta.exe
.htm :: C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
.html :: C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
.icc :: C:\Windows\system32\colorcpl.exe
.icm :: C:\Windows\system32\colorcpl.exe
.imesx :: C:\Windows\system32\IME\SHARED\imesearch.exe
.img :: C:\Windows\Explorer.exe
.inf :: C:\Windows\system32\NOTEPAD.EXE
.ini :: C:\Windows\system32\NOTEPAD.EXE
.iso :: C:\Windows\Explorer.exe
Quando si esegue il fuzzing su Windows, potrebbe essere utile abilitare PageHeap e i Memory Dump per un'esperienza di fuzzing migliore (a meno che il tuo target non li gradisca) prima di avviare una nuova sessione di fuzzing.
sudo litefuzz -l -c "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" -z
sudo litefuzz -l -c "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" --memdump
Sì, esegui questi comandi usando (g)sudo su Windows per elevare facilmente i permessi ad Admin dalla console e apportare le modifiche al registro necessarie per abilitare le funzionalità.
Questo illustra anche un'altra sfumatura per abilitare i malloc debugger per i target: su Linux e Mac, stiamo usando flag di ambiente runtime che devono essere passati ogni volta per abilitare questa funzionalità. Per Windows, stiamo modificando il registro, quindi una volta passato la prima volta, non è necessario passare -z o --memdump nella riga di comando del fuzzing di nuovo (a meno che non si vogliano disabilitare o riabilitare).
fuzz PuTTY (puttygen) (Windows)
litefuzz -l -c "C:\Program Files (x86)\WinSCP\PuTTY\puttygen.exe FUZZ" -i input\ppk -x 0.5 -n 100000 -z
fuzz Adobe Reader come ai vecchi tempi (GUI Windows)
litefuzz -l -c "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe FUZZ" -i pdfs -x 3 -n 100000 -z
(WinAppDbg supporta solo python 2, quindi su Windows bisogna usare py2)
nota: promemoria che è possibile abilitare PageHeap per l'applicazione target tramite -z in un prompt con privilegi elevati o usando il pacchetto sudo installato per gsudo win32 che è stato installato durante la configurazione
litefuzz -l -c "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe FUZZ" -z
litefuzz -lk -c "ssh -T test@localhost -p 2222" -a tcp://localhost:2222 -i input/ssh-cli -o crashes/ssh -p -n 250000 -z glibc --========================-- --======| litefuzz |======-- --========================--
[STATS] run id: 9404 cmdline: ssh -T test@localhost -p 2222 address: tcp://localhost:2222 crash dir: crashes/ssh input dir: input/ssh-cli inputs: 4 iterations: 250000 mutator: random(mutators)
@ 73/250000 (0 crashes, 0 duplicates, ~1 day, 0:21:01 remaining)^C
resume? (y/n)> n Terminated ...
cat /tmp/litefuzz/out padding error: need 57895 block 8 mod 7 ssh_dispatch_run_fatal: Connection to 127.0.0.1 port 2222: message authentication code incorrect
#### client locale
**fuzz del client SNMP sul localhost (Linux)**
`litefuzz -lk -c "snmpwalk -v 2c -c public localhost:1616 1.3.6.1.2.1.1.1" -a udp://localhost:1616 -i input/snmp/resp.bin -n 1 -d -x 3`
#### client remoto
**fuzz di un client FTP remoto (Linux)**
`while :; do echo "user test\rpass test\rls\rbye\r" | ftp localhost 2121; sleep 1; done`
`litefuzz -k -i input/ftp/test -a tcp://localhost:2121 -n 100`
nota: a seconda del target, il fuzzing del client potrebbe richiedere l'ascolto su una porta privilegiata (1-1024). In questo caso, su Linux puoi eseguire `setcap cap_net_bind_service=+ep` sull'interprete Python oppure usare sudo durante l'esecuzione del fuzzatore; su Mac basta usare sudo, e su Windows puoi eseguire il fuzzatore come Amministratore per evitare errori di autorizzazione (Permission Denied).
### server
#### colpo d'occhio```
litefuzz -ls -c "./sc_serv shoutcast.conf" -a tcp://localhost:8000 -i input/shoutcast -o crashes/shoutcast -n 1000 -z
--========================--
--======| litefuzz |======--
--========================--
[STATS]
run id: 4001
cmdline: ./sc_serv shoutcast.conf
address: tcp://localhost:8000
crash dir: crashes/shoutcast
input dir: input/shoutcast
inputs: 3
iterations: 1000
mutator: random(mutators)
@ 1000/1000 (1 crashes, 7 duplicates, ~0:00:00 remaining)
[RESULTS]
> completed (1000) iterations with (1) unique crashes and 7 dups
>> check crashes/shoutcast for more details
fuzz di un server Shoutcast locale
litefuzz -ls -c "./sc_serv shoutcast.conf" -a tcp://localhost:8000 -i input/shoutcast -o crashes/shoutcast -n 1000 -z
fuzz di un server SMTP remoto
litefuzz -s -a tcp://10.0.0.11:25 -i input/smtp-req -pp -n 10000
usage: litefuzz.py [-h] [-l] [-k] [-s] [-c CMDLINE] [-i INPUTS] [-n ITERATIONS] [-x MAXTIME] [--mutator MUTATOR] [-a ADDRESS] [-o CRASHDIR] [-t TEMPDIR] [-f FUZZFILE] [-m MINFILE] [-mm SUPERMIN] [-r REPROFILE] [-e] [-p] [-pp] [-u] [--nofuzz] [--key KEY] [--click] [--tls] [--golang] [--attach ATTACH] [--cmd CMD] [--rmfile RMFILE] [--reportcrash REPORTCRASH] [--memdump] [--nomemdump] [-z [MALLOC]] [-zz] [-d]
optional arguments: -h, --help show this help message and exit -l, --local target will be executed locally -k, --client target a network client -s, --server target a network server -c CMDLINE, --cmdline CMDLINE target command line -i INPUTS, --inputs INPUTS input directory or file -n ITERATIONS, --iterations ITERATIONS number of fuzzing iterations (default: 1) -x MAXTIME, --maxtime MAXTIME timeout for the run (default: 1) --mutator MUTATOR, --mutator MUTATOR timeout for the run (default: 0=random) -a ADDRESS, --address ADDRESS server address in the ip:port format -o CRASHDIR, --crashdir CRASHDIR specify the directory to output crashes (default: crashes) -t TEMPDIR, --tempdir TEMPDIR specify the directory to output runtime fuzzing artifacts (default: OS tmp + run dir) -f FUZZFILE, --fuzzfile FUZZFILE specify the path and filename to place the fuzzed file (default: OS tmp + run dir + fuzz_random.ext) -m MINFILE, --minfile MINFILE specify a crashing file to generate a minimized version of it (bonus: may also find variant bugs) -mm SUPERMIN, --supermin SUPERMIN loops minimize to grind on until no more bytes can be removed -r REPROFILE, --reprofile REPROFILE specify a crashing file or directory to replay on the target -e, --reuse enable second round fuzzing where any crashes found are reused as inputs -p, --multibin use multiple requests or responses as inputs for fuzzing simple binary network sessions -pp, --multistr use multiple requests or responses within input for fuzzing simple string-based network sessions -u, --insulate only execute the target once and inside a debugger (eg. interactive clients) --nofuzz, --nofuzz send input as-is without mutation (useful for debugging) --key KEY, --key KEY send a particular key every iteration for interactive targets (eg. F5 for refresh) --click, --click click the mouse (eg. position the cursor over target button to click beforehand) --tls, --tls enable TLS for network fuzzing --golang, --golang enable fuzzing of Golang binaries --attach ATTACH, --attach ATTACH attach to a local server process name (mac only) --cmd CMD, --cmd CMD execute this command after each fuzzing iteration (eg. umount /Volumes/test.dir) --rmfile RMFILE, --rmfile RMFILE remove this file after every fuzzing iteration (eg. target won't overwrite output file) --reportcrash REPORTCRASH, --reportcrash REPORTCRASH use ReportCrash to help catch crashes for a specified process name (mac only) --memdump, --memdump enable memory dumps (win32) --nomemdump, --nomemdump disable memory dumps (win32) -z [MALLOC], --malloc [MALLOC] enable malloc debug helpers (free bugs, but perf cost) -zz, --nomalloc disable malloc debug helpers (eg. pageheap) -d, --debug Turn on debug statements
# trofei
Litefuzz ha trovato crash in vari pacchetti software come...
* antiword
* AppleScript (OS X)
* ArangoDB VelocyPack
* Avast authenticode-parser
* Avast RetDec
* BBC Audio Waveform
* ColorSync (OS X)
* Dynamsoft BarcodeReader
* eot2ttf
* evernote2md
* faad2
* Facebook's Origami Studio
* FontForge
* ForestDB
* Gifsicle
* GPUJPEG
* GPAC Multimedia Framework
* Google Draco
* Google Quipper
* GoPro GPR
* GtkRadiant
* IIPImage Server
* John The Ripper
* Kyoto Cabinet
* latex2rtf
* libMeshb
* libembroidery
* libsndfile
* Lion Vector Graphics (lvg)
* L-SMASH
* mp3-decoder
* MindNode
* minimp4
* MiniWeb Server
* MLpack
* Nvidia Data Center GPU Manager
* Numbers (OS X)
* OpenJPEG
* OpenOrienteering Mapper
* OSM Express
* Pages (OS X)
* PBRT-Parser
* Pixar USD
* Remote Apple Events (OS X)
* Samsung rlottie
* Samsung ThorVG
* Shoutcast Server
* Silo
* syslog (OS X)
* Tencent NCNN
* TinyXML2
* UEFITool
* Ulfius Web Framework
* zlib
# FAQ
## come è nato questo progetto?
Il fuzzing è divertente! Ed è bello realizzare progetti che adottano un punto di vista anticonformista, secondo cui i fuzzer non devono sempre seguire gli approcci moderni o popolari per raggiungere l'obiettivo finale di trovare bug. Che tu sia vicino al bare metal, che ottenga copertura del codice su tutti i percorsi o che punti semplicemente all'ottimizzazione rapida e flessibile, al modo fondamentale di "invalidare le assunzioni" di fare le cose, ecc. Comunque si manifesti, goditelo.
## questo progetto è mantenuto attivamente?
Non aspettarti supporto o manutenzione attiva sul progetto. Sentiti libero di forkarlo per aggiungere nuove funzionalità o correggere bug, ecc. Magari fai anche una PR per cose più piccole, anche se non aspettarti risposte o risoluzione di problemi. Non è previsto che lo sviluppo su questo repository sia attivo.
## come fai a sapere che il fuzzer funziona bene e l'hai confrontato con altri?
Lo scopo di Litefuzz è trovare bug su diverse piattaforme. E lo fa. Quindi, onestamente, la possibilità di confrontarlo con fuzzerX o fuzzerY non ha superato la selezione. Sono stati fatti alcuni compromessi, riconosciuti fin dall'inizio; vedi la [#intro](https://github.com/sec-tools/litefuzz/blob/HEAD/README.md#intro) per maggiori dettagli.
## cosa cambieresti se lo riscrivessi oggi?
Funziona piuttosto bene così com'è ed è stato testato su tantissimi target e scenari diversi. Tuttavia, potrebbe trarre beneficio da una standardizzazione su un sistema più modulare e basato su plugin, dove il passaggio tra target e piattaforme non richiedesse tanti controlli aggiuntivi nella parte operativa del codice, ecc. Ovviamente, avere test più formali e un sistema di distribuzione che lo testi sui sistemi operativi supportati creerebbe un ambiente più facile su cui lavorare quando si apportano modifiche alle funzioni principali. È cresciuto da un progetto piccolo ma ambizioso a qualcosa di un po' più grande piuttosto rapidamente.
## quanto è stabile litefuzz?
La riga di comando, la GUI, il fuzzing di rete (principalmente su Linux e Mac), la minimizzazione, ecc. sono stati testati abbastanza approfonditamente e dovrebbero essere piuttosto solidi nel complesso. Alcune funzionalità più esotiche come il fuzzing di rete isolato con GUI, il supporto ReportCrash per Mac e altre caratteristiche di nicchia dovrebbero essere considerate sperimentali.
## ci sono scenari non supportati per litefuzz?
Alcuni, sì. Ma la maggior parte sono scenari poco comuni, buggati, che richiedono più tempo e ricerca per "essere corretti" o semplicemente non funzionano bene per ragioni legate alla piattaforma. Molti di essi escono esplicitamente con un messaggio "non supportato" quando provi ad eseguirlo con tali opzioni, e alcune avvertenze sono state menzionate nelle sezioni precedenti quando si descrivevano varie funzionalità. Tra quelli più complessi, la modalità di riproduzione su app *isolate* non è supportata, e inoltre i test sulle app Mac che utilizzano la funzione di isolamento sono limitati. Pyautogui sembra funzionare bene su Linux e Windows, ma su Mac non si è rivelato molto affidabile, quindi consideralo funzionalmente non supportato; inoltre il fuzzing client su Windows può essere un po' meno affidabile rispetto ad altre modalità su altre piattaforme.
Potrebbero esserci alcuni casi limite, ma gli scenari più comuni di fuzzing locale e di rete sono stati testati e funzionano. Ah, queste sono le gioie di scrivere strumenti multipiattaforma: gratificanti, ma è difficile far funzionare tutto alla perfezione sempre. Nel complesso, il fuzzing su Linux/Mac sembra essere più stabile e supportare più funzionalità, soprattutto perché ha ricevuto molti più test di fuzzing di rete rispetto alla piattaforma Windows, ma è stato fatto uno sforzo affinché almeno le basi fossero disponibili su Win32 con un paio di extra.
Sentiti libero di forkare questo fuzzer e apportare tali miglioramenti, supportare ciò che attualmente non è supportato, ecc., o fare PR per cose minori ma utili.
## che garanzie vengono fornite per questo progetto o il suo codice?
Assolutamente nessuna. Ma è piuttosto divertente fare fuzzing e vedere come ti fornisce bug.
## autore / riferimenti
- [Jeremy Brown](https://github.com/sec-tools/litefuzz/blob/HEAD/jbrown3264%5BNOSPAM%5Dgmail)
- [Slide deck per il fuzzing su macOS](https://www.slideshare.net/JeremyBrown37/summer-of-fuzz-macos)