
Структурно-ориентированный фаззер JSON

jdam — это инструмент, вдохновлённый Radamsa, для фаззинга произвольных JSON-объектов с учётом структуры, что гарантирует, что результаты фаззинга всегда будут корректным JSON.
Многие существующие инструменты фаззинга слепо изменяют входные данные и часто приводят к получению некорректного JSON. Это означает, что фазз-тестирование будет задействовать только JSON-парсер целевого приложения, а тестирование никогда не достигнет основного кода приложения, потому что запросы невалидны. Jdam — попытка решить эту проблему.
jdam содержит несколько модулей мутации, каждый из которых нацелен на выявление потенциальных проблем и уязвимостей в системах, обрабатывающих фаззированные данные. Некоторые модули выполняют случайные изменения, такие как удаление, замена, перестановка и повторение случайных байтов, инвертирование булевых значений и отрицание чисел, в то время как другие модули заменяют значения полезными нагрузками, которые пытаются вызвать определённые типы уязвимостей, такие как:
Чтобы увидеть полный список доступных мутаторов, используйте jdam -list.
jdam всё ещё довольно сырой, и следует ожидать ошибок. Тем не менее, он достаточно стабилен для выпуска для самых смелых пользователей, но пока относитесь к нему как к альфа-программному обеспечению!
Загрузите предварительно собранный релиз для вашей операционной системы или клонируйте репозиторий и скомпилируйте с помощью 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 работает путём передачи в него корректного JSON-объекта ({...}) через конвейер. По умолчанию jdam выполняет одну случайную перестановку на случайном поле и выводит результирующий JSON-объект:
$ echo '{"hello":"world"}' | jdam
{"hello":{"id":1}}
Исходный JSON может быть мутирован несколько раз с помощью флага -rounds, но имейте в виду, что предыдущие полезные нагрузки фаззинга также могут быть мутированы:
$ echo '{"hello":"world"}' | jdam -rounds 10
{"hello":{"_constructor":"${42*444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444442}"}}
Несколько фаззированных объектов можно сгенерировать с помощью флага -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 может записывать результаты фаззинга в отдельные файлы, если вы хотите подготовить тестовые файлы вместо использования STDOUT команды:
$ echo '{"hello":"world"}' | jdam -count 10 -output "/tmp/jdam-%d.json"
Приведённая выше команда создаст 10 файлов в /tmp от jdam-1.json до jdam-10.json. Специальный спецификатор %d будет автоматически заменён на порядковый номер, чтобы результаты можно было записывать в отдельные файлы.
Если вы хотите, чтобы jdam никогда не мутировал определённые поля в исходном JSON-объекте, вы можете указать jdam игнорировать их с помощью флага -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 — это отличный веб-фаззер, и jdam легко может использоваться в качестве входных данных для фаззинга:
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
Приведённая выше команда укажет ffuf получать свои входные данные для фаззинга от jdam и отправлять их в теле запроса к PUT /api/todos/1. Детали запроса и ответа будут записаны в tmp/ffuf_test/, если ответом является 500 Internal Server Error или тело ответа содержит определённые интересные строки.
Если вы знаете Go и вам нужен очень специализированный фаззинг, вы можете использовать jdam в своём собственном коде на Go. Примеры использования см. в папке examples/.
Фаззинг полезен только в том случае, если вы можете обнаружить, что конкретная мутация вызвала проблему или спровоцировала уязвимость. Эти признаки будут различаться в зависимости от целевой системы и окружения, но вот несколько хороших общих моментов, на которые стоит обратить внимание:
sleep.error, failure, failed и т. д./etc/passwd, чтобы иметь предсказуемое содержимое. Так что любой ответ, содержащий root:, очень интересен!42*42, что равно 1.764. Если это число когда-либо встретится в ответе, велика вероятность, что система уязвима к инъекции шаблонов.0x, за которым следует длинная шестнадцатеричная строка или длинная числовая строка, это может быть признаком того, что полезная нагрузка вызвала уязвимость форматной строки./tmp системы с именем jdam.<number>.fail. Число будет случайным пятизначным числом, чтобы было легче идентифицировать ответственную полезную нагрузку.jdam всё ещё очень новый инструмент, поэтому пока не обнаружил каких-либо серьёзных ошибок. Я был бы рад узнать от вас, если jdam помог вам получить CVE или хороший баг-баунти, и я с удовольствием размещу ссылку на ваш отчёт здесь. :)
Я хотел бы выразить признательность и поблагодарить несколько других проектов:
Удачного фаззинга!