Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
В этой статье я расскажу о сканировании API веб‑приложений с помощью утилиты Nuclei. Для демонстрации мы будем атаковать заведомо уязвимое приложение, использующее OpenAPI. По дороге научимся писать кастомные шаблоны для Nuclei, которые помогут искать уязвимости на автомате.
Динамическое сканирование (DAST) — один из важных этапов анализа защищенности приложения. Будь то пентест или процессы application security, в любом случае мы запускаем сканер уязвимостей, который отправляет к приложению множество запросов и пытается выявить проблемы безопасности.
Однако DAST не лишен недостатков.
Во‑первых, настройки сканеров по умолчанию не всегда позволяют пройти валидацию, так как не учитываются особенности конкретных запросов к API, например, что в одном из параметров должен быть UUID.
Во‑вторых, сканер по умолчанию ничего не знает про аутентификацию. Если его запросы не содержат bearer-токен или cookie, то мы просто получим ошибку, не дойдя до проблемы.
В‑третьих, это отчет, в котором может быть отмечено множество незначительных недостатков безопасности, что мешает заметить реально важные уязвимости и уделить им время.
В этой статье я покажу, как улучшить DAST, настроив динамическое сканирование под конкретное приложение с помощью аутентификации и фаззинга OpenAPI, на примере сканера уязвимостей Nuclei. Также напишем три кастомных шаблона для нахождения уязвимостей:
В качестве подопытного возьмем VAmPI — специальное уязвимое приложение для тестирования защищенности API. У него есть поддержка OpenAPI и показательные примеры небезопасной реализации. Чтобы его установить, достаточно клонировать репозиторий и запустить docker compose
:
git clone https://github.com/erev0s/VAmPI cd VAmPI docker compose up
Также необходимо инициализировать базу данных, отправив GET-запрос:
curl http://127.0.0.1:5002/createdb
{ «message»: «Database populated.» }
Для начала запустим Nuclei с настройками по умолчанию (достаточно передать цель для сканирования):
nuclei -u http://127.0.0.1:5002
При таком запуске Nuclei использует встроенные шаблоны. В результате видим ложноположительные результаты и информационные замечания, которые могут быть полезны только на этапе сбора информации при пентесте.
Наша цель — найти реальные проблемы, поэтому мы напишем кастомные шаблоны для сканирования известного REST API на уязвимости, наличие которых мы можем предполагать из понимания реализации. В этом нам помогут возможности, которые появились в Nuclei версии 3.2.
Если у приложения много эндпоинтов HTTP, каждый из которых может обрабатывать множество параметров, проверка становится утомительной.
Автоматизировать анализ защищенности крупных API помогает фаззинг — техника, которая последовательно применяет набор проверок ко всем возможным вариациям запросов к приложению.
Мы можем передать реальные запросы из дампа трафика других инструментов, логов или спецификации OpenAPI в Nuclei. Остановимся на OpenAPI, так как ее поддержка есть у многих современных веб‑приложений и в отличие от сбора трафика такой метод не требует активных действий.
Передать OpenAPI в Nuclei можно следующим образом:
nuclei -l openapi.json -im openapi -t templates
Пример шаблона для фаззинга:
http: # filter checks if the template should be executed on a given request - pre-condition: - type: dsl dsl: - method == POST - len(body) > 0 condition: and # payloads that will be used in fuzzing payloads: injection: # Variable name for payload - "'" - """ - ";" # fuzzing rules fuzzing: - part: body # This rule will be applied to the Body type: postfix # postfix type of rule (i.e., payload will be added at the end of exiting value) mode: single # single mode (i.e., existing values will be replaced one at a time) fuzz: # format of payload to be injected - '{{injection}}' # here, we are directly using the value of the injection variable
В шаблоне выше секция pre-condition
фильтрует и запускает проверку только POST-запросов с непустым телом.
- pre-condition: - type: dsl dsl: - method == POST - len(body) > 0 condition: and
Вот какие части HTTP-запроса может фаззить Nuclei:
part: query
— параметры запроса; part: path
— путь; part: header
— заголовок; part: cookie
— cookie; part: body
— тело запроса. Это далеко не все настройки фаззинга Nuclei, но для наших целей достаточно.
Если запросы сканера не проходят дальше авторизации приложения, то от него может быть мало пользы, так как многие уязвимости скрываются гораздо глубже — в слоях с бизнес‑логикой и в репозитории.
Источник: xakep.ru