
Un fuzzer JSON consapevole della struttura

jdam è uno strumento ispirato a [Radamsa] per il fuzzing di oggetti JSON arbitrari in modo strutturato, il che garantisce che i risultati del fuzzing siano sempre JSON validi.
Molti strumenti di fuzzing esistenti alterano ciecamente l'input e spesso portano a un risultato JSON non valido. Ciò significa che il fuzz testing eserciterà solo il parser JSON dell'applicazione target e non raggiungerà mai il codice sottostante dell'applicazione perché le richieste non sono valide. Jdam è un tentativo di risolvere questo problema.
jdam include diversi moduli di mutazione che mirano a scoprire potenziali problemi e vulnerabilità nei sistemi che elaborano i dati fuzzati. Alcuni moduli eseguono modifiche casuali come l'eliminazione, la sostituzione, lo scambio e la ripetizione di byte casuali, l'inversione di valori booleani e la negazione di numeri, mentre altri moduli sostituiscono i valori con payload che tentano di innescare specifici tipi di vulnerabilità come:
Per vedere l'elenco completo dei mutator disponibili, usa jdam -list.
jdam è ancora piuttosto grezzo e ci si devono aspettare errori. È comunque abbastanza stabile per essere rilasciato per gli avventurosi là fuori, ma per ora trattalo come software alpha!
Scarica un [release] precompilato per il tuo sistema operativo o clona il repository e compila con go build -o jdam cmd/jdam/*.
Usage of jdam:
-count int
Number of fuzzed objects to generate (default 1)
-ignore string
Comma-separated list of fields to exclude from fuzzing
-list
List available mutators
-max-depth int
Maximum object depth to fuzz (default 100)
-mutators string
Comma-separated list of mutator IDs to use (default: all)
-nil-chance float
Probability of value being set to nil (between 0 (no nils) and 1 (all nils)) (default 0.75)
-output string
Output file pattern to use for results (e.g. /tmp/jdam-%d.json)
-rounds int
Number of times to fuzz object (default 1)
-seed int
Seed to use for pseudo-random number generator (default: current UNIX timestamp)
-verbose
Print activity information
-version
Print current jdam version
jdam funziona inserendo un oggetto JSON valido ({...}) tramite pipe. Di default, jdam esegue una permutazione casuale su un campo casuale e stampa l'oggetto JSON risultante:
$ echo '{"hello":"world"}' | jdam
{"hello":{"id":1}}
L'oggetto JSON può essere mutato più volte con il flag -rounds, ma tieni presente che anche i payload di fuzzing precedenti possono essere mutati:
$ echo '{"hello":"world"}' | jdam -rounds 10
{"hello":{"_constructor":"${42*444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444442}"}}
Possono essere generati più oggetti fuzzati con il flag -count:
$ echo '{"hello":"world"}' | jdam -count 10
{"hello":"sorld"}
{"hello":"../../../../../../../../../../../../../../../../../../../../etc/passwd"}
{"hello":"{{42*42}}"}
{"hello":null}
{"hello":"' \u0026\u0026 this.password.match(/.*/)//+\u0000"}
{"hello":{"$where":"1"}}
{"hello":"null"}
{"hello":"\";touch /tmp/jdam.70797.fail'"}
{"hello":null}
{"hello":"|| 1==1"}
jdam può scrivere i risultati del fuzzing in file individuali se vuoi preparare file di test invece di usare STDOUT del comando:
$ echo '{"hello":"world"}' | jdam -count 10 -output "/tmp/jdam-%d.json"
Il comando sopra genererà 10 file in /tmp da jdam-1.json a jdam-10.json. Il verbo speciale %d verrà automaticamente sostituito con un numero progressivo in modo che i risultati possano essere scritti in file individuali.
Se vuoi assicurarti che jdam non muti mai campi specifici nell'oggetto JSON di partenza, puoi dirgli di ignorarli con il flag -ignore:
$ echo '{"id":13,"articleId":37,"comment":"Hello"}' | ./jdam -count 10 -ignore id,articleId
{"id":13,"articleId":37,"comment":"%x%x%x%x"}
{"id":13,"articleId":37,"comment":"search=')] | //user/*[contains(*,'"}
{"id":13,"articleId":37,"comment":"' and count(/comment())=1 and '1'='1"}
{"id":13,"articleId":37,"comment":"\u0016ello"}
{"id":13,"articleId":37,"comment":"/"}
{"id":13,"articleId":37,"comment":null}
{"id":13,"articleId":37,"comment":"{{{42*42}}}"}
{"id":13,"articleId":37,"comment":"@*"}
{"id":13,"articleId":37,"comment":"Helloooooooooooooooo"}
{"id":13,"articleId":37,"comment":"//*"}
[ffuf] è un fantastico web fuzzer e jdam può essere facilmente utilizzato come input per il fuzzing:
ffuf -input-cmd 'cat subject.json | jdam -rounds 3' -d FUZZ -u http://localhost/api/todos/1 -X PUT -v -mc 500 -mr 'error|failed|failure|fault|abort|root:|1764|0x|\d{20}' -od /tmp/ffuf_test
Il comando sopra istruisce ffuf a ricevere il suo input di fuzzing da jdam e a inviarlo come corpo della richiesta a PUT /api/todos/1. I dettagli della richiesta e della risposta verranno scritti in tmp/ffuf_test/ se la risposta è 500 Internal Server Error o se il corpo della risposta contiene determinate stringhe interessanti.
Se conosci [Go] e hai bisogno di fuzzing molto specializzato, puoi utilizzare jdam all'interno del tuo codice Go. Vedi la cartella examples/ per esempi di utilizzo.
Il fuzzing è utile solo se puoi rilevare che una particolare mutazione ha causato un problema o innescato una vulnerabilità. Questi segnali varieranno a seconda del sistema target e dell'ambiente, ma ecco alcune buone cose generali da tenere d'occhio:
sleep.error, failure, failed, ecc./etc/passwd per avere un contenuto prevedibile. Quindi qualsiasi risposta che contiene root: è molto interessante!42*42 ai motori di template vulnerabili, che equivale a 1.764. Se questo numero compare mai in una risposta, è molto probabile che il sistema sia vulnerabile a template injection.0x seguito da una lunga stringa esadecimale o una lunga stringa numerica, potrebbe essere un'indicazione che un payload ha innescato una vulnerabilità di formato stringa./tmp del sistema con il nome jdam.<numero>.fail. Il numero sarà un numero casuale di cinque cifre per facilitare l'identificazione del payload responsabile.