
Структурно-ориентированный фаззер 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, за которым следует длинная шестнадцатеричная строка или длинная числовая строка, это может быть признаком того, что полезная нагрузка вызвала уязвимость форматной строки.jdam всё ещё очень новый инструмент, поэтому пока не обнаружил каких-либо серьёзных ошибок. Я был бы рад узнать от вас, если jdam помог вам получить CVE или хороший баг-баунти, и я с удовольствием размещу ссылку на ваш отчёт здесь. :)
Я хотел бы выразить признательность и поблагодарить несколько других проектов:
Удачного фаззинга!
/tmp системы с именем jdam.<number>.fail. Число будет случайным пятизначным числом, чтобы было легче идентифицировать ответственную полезную нагрузку.