
Un fuzzer JSON consciente de la estructura

jdam es una herramienta inspirada en Radamsa para fuzzear objetos JSON arbitrarios de manera consciente de la estructura, lo que garantiza que los resultados del fuzzing siempre sean JSON válido.
Muchas herramientas de fuzzing existentes alteran ciegamente la entrada y a menudo provocan que el resultado sea JSON inválido. Esto significa que las pruebas de fuzzing solo ejercitarán el analizador JSON de la aplicación objetivo y nunca alcanzarán el código subyacente de la aplicación porque las solicitudes son inválidas. Jdam es un intento de resolver este problema.
jdam viene con varios módulos de mutación que tienen como objetivo descubrir posibles problemas y vulnerabilidades en los sistemas que procesan los datos fuzzeados. Algunos módulos realizan cambios aleatorios, como eliminar, reemplazar, intercambiar y repetir bytes aleatorios, invertir valores booleanos y negar números, mientras que otros módulos reemplazan valores con cargas útiles que intentan desencadenar tipos específicos de vulnerabilidades como:
Para ver una lista completa de mutadores disponibles, usa jdam -list.
jdam es todavía bastante rudimentario y se deben esperar errores. Sin embargo, es lo suficientemente estable como para ser publicado para las personas aventureras, ¡pero trátalo como software alfa por ahora!
Descarga un release precompilado para tu sistema operativo o clona el repositorio y compílalo 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 funciona canalizando un objeto JSON válido ({...}) hacia él. Por defecto, jdam realizará una permutación aleatoria en un campo aleatorio e imprimirá el objeto JSON resultante:
$ echo '{"hello":"world"}' | jdam
{"hello":{"id":1}}
El JSON de entrada se puede mutar varias veces con la bandera -rounds, pero ten en cuenta que las cargas de fuzzing anteriores también pueden mutarse:
$ echo '{"hello":"world"}' | jdam -rounds 10
{"hello":{"_constructor":"${42*444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444442}"}}
Se pueden generar múltiples objetos fuzzeados con la bandera -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 puede escribir los resultados del fuzzing en archivos individuales si deseas preparar archivos de prueba en lugar de usar la salida estándar del comando:
$ echo '{"hello":"world"}' | jdam -count 10 -output "/tmp/jdam-%d.json"
El comando anterior generará 10 archivos en /tmp desde jdam-1.json hasta jdam-10.json. El verbo especial %d se reemplazará automáticamente con un número secuencial para que los resultados se puedan escribir en archivos individuales.
Si deseas asegurarte de que jdam nunca mute campos específicos en el objeto JSON de entrada, puedes indicarle que los ignore con la bandera -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 es un fantástico fuzzer web y jdam se puede usar fácilmente 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
El comando anterior instruirá a ffuf para que obtenga su entrada de fuzzing de jdam y la envíe como cuerpo de la solicitud a PUT /api/todos/1. Los detalles de la solicitud y respuesta se escribirán en tmp/ffuf_test/ si la respuesta es 500 Internal Server Error o si el cuerpo de la respuesta contiene ciertas cadenas interesantes.
Si conoces Go y necesitas un fuzzing muy especializado, puedes usar jdam dentro de tu propio código Go. Consulta la carpeta examples/ para ver ejemplos de uso.
El fuzzing solo es útil si puedes detectar que una mutación en particular causó un problema o desencadenó una vulnerabilidad. Estas señales variarán según el sistema objetivo y el entorno, pero aquí hay algunas cosas generales buenas a tener en cuenta:
sleep.error, failure, failed, etc./etc/passwd para tener un contenido predecible. Por lo tanto, cualquier respuesta que contenga root: es muy interesante.42*42, que es igual a 1764. Si este número aparece alguna vez en una respuesta, hay una alta probabilidad de que el sistema sea vulnerable a la inyección de plantillas.jdam sigue siendo una herramienta muy nueva, por lo que aún no ha descubierto errores importantes. Me encantaría saber de ti si jdam te ha ayudado a conseguir un CVE o una buena recompensa por errores, y con gusto enlazaré aquí tu informe o artículo. :)
Me gustaría dar crédito y agradecer a otros proyectos:
¡Feliz Fuzzing!
0x/tmp del sistema con el nombre jdam.<número>.fail. El número será un número aleatorio de cinco dígitos para facilitar la identificación de la carga útil responsable.