
Um fuzzer JSON consciente de estrutura

jdam é uma ferramenta inspirada no Radamsa para fuzzing de objetos JSON arbitrários de forma consciente da estrutura, o que garante que os resultados do fuzzing serão sempre JSON válido.
Muitas ferramentas de fuzzing existentes alteram cegamente a entrada e frequentemente fazem com que o resultado seja JSON inválido. Isso significa que o teste de fuzzing exercitará apenas o parser JSON da aplicação alvo e nunca alcançará o código subjacente da aplicação, pois as requisições são inválidas. Jdam é uma tentativa de resolver esse problema.
jdam vem com vários módulos de mutação que visam descobrir possíveis problemas e vulnerabilidades nos sistemas que processam os dados fuzzados. Alguns módulos realizam alterações aleatórias, como descartar, substituir, trocar e repetir bytes aleatórios, inverter valores booleanos e negar números, enquanto outros módulos substituem valores por payloads que tentam acionar tipos específicos de vulnerabilidade, como:
Para ver a lista completa de mutadores disponíveis, use jdam -list.
jdam ainda é bastante preliminar e erros devem ser esperados. No entanto, é estável o suficiente para ser lançado para os aventureiros de plantão, mas trate-o como software alfa por enquanto!
Baixe um release pré-compilado para seu sistema operacional ou clone o repositório e compile com .
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 funciona canalizando um objeto JSON válido ({...}) para ele. Por padrão, jdam realizará uma permutação aleatória em um campo aleatório e exibirá o objeto JSON resultante:
$ echo '{"hello":"world"}' | jdam
{"hello":{"id":1}}
O JSON de entrada pode ser mutado várias vezes com a flag -rounds, mas lembre-se de que payloads de fuzzing anteriores também podem ser mutados:
$ echo '{"hello":"world"}' | jdam -rounds 10
{"hello":{"_constructor":"${42*444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444442}"}}
Vários objetos fuzzados podem ser gerados com a 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 pode escrever resultados de fuzzing em arquivos individuais se você quiser preparar arquivos de teste em vez de usar o STDOUT do comando:
$ echo '{"hello":"world"}' | jdam -count 10 -output "/tmp/jdam-%d.json"
O comando acima gerará 10 arquivos em /tmp de jdam-1.json a jdam-10.json. O verbo especial %d será substituído automaticamente por um número sequencial para que os resultados possam ser escritos em arquivos individuais.
Se você quiser garantir que jdam nunca mute campos específicos no objeto JSON de entrada, você pode informar ao jdam para ignorá-los com a 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 é um fuzzer web fantástico e jdam pode ser facilmente usado como entrada para 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
O comando acima instruirá o ffuf a obter sua entrada de fuzzing do jdam e enviá-la como corpo da requisição para PUT /api/todos/1. Detalhes da requisição e resposta serão escritos em tmp/ffuf_test/ se a resposta for 500 Internal Server Error ou se o corpo da resposta contiver certas strings interessantes.
Se você conhece Go e precisa de fuzzing muito especializado, pode usar jdam no seu próprio código Go. Veja a pasta examples/ para exemplos de uso.
Fuzzing só é útil se você puder detectar que uma mutação específica causou um problema ou acionou uma vulnerabilidade. Esses sinais variam dependendo do sistema alvo e do ambiente, mas aqui estão algumas boas coisas gerais para observar:
sleep.error, failure, failed, etc./etc/passwd para ter conteúdo previsível. Portanto, qualquer resposta que contenha root: é muito interessante!42*42, que é igual a 1.764. Se esse número aparecer em uma resposta, há uma grande chance de que o sistema seja vulnerável a injeção de template.0x seguido por uma longa string hexadecimal ou uma longa string numérica, pode ser um indício de que um payload acionou uma vulnerabilidade de string de formatação./tmp do sistema com o nome jdam.<número>.fail. O número será um número aleatório de cinco dígitos para facilitar a identificação do payload responsável.jdam ainda é uma ferramenta muito nova, então ainda não descobriu nenhum bug relevante. Eu adoraria saber se jdam ajudou você a conseguir um CVE ou um bom bug bounty e terei prazer em linkar seu artigo ou relatório aqui. :)
Gostaria de dar créditos e agradecer a alguns outros projetos:
Feliz Fuzzing!