РАЗБОР На проверке

Bug Bounty методология: от сканера к мышлению

Сергей Попов
Сергей Попов Red Team · 6,5 тыс. сообщений
Подписаться
34
[ обложка статьи ]
Режим чтения
Макросъёмка экрана ноутбука на тёмном коврике: вкладка Burp Suite Repeater с запросом DELETE к paymentmethodid, подсвеченным янтарным, и пометкой IDOR цианом. Резкий блик пурпурного света на алюмин...


Три месяца на HackerOne - двенадцать репортов, одиннадцать дубликатов. Сценарий один и тот же: Nuclei с дефолтными шаблонами по всему скоупу, reflected XSS на забытом поддомене, аккуратный отчёт - через пару часов ответ «Duplicate». Знакомо?

Перелом случился на финтех-программе. Сканер выдал ноль критичных находок. Вместо того чтобы переключиться на следующую цель, я залогинился как обычный пользователь, прошёл весь flow оформления подписки через Burp Suite и за два часа нашёл IDOR в API управления платёжными методами. Четырёхзначная выплата - а нашёлся баг не сканером, а вопросом: «что будет, если подставить чужой payment_method_id в DELETE-запрос?»

Bug hunting мышление: почему сканер создаёт иллюзию результата​

Новичок в Bug Bounty запускает Nuclei, получает десяток findings - и чувствует, что работает. На деле он делает ровно то же, что и ещё сотни хантеров на том же скоупе. Дефолтные шаблоны Vulnerability Scanning (T1595.002, фаза Reconnaissance по MITRE ATT&CK) одинаковы у всех. Кто первым отправил репорт - получил награду. Остальные - дубликат. Арифметика простая.

Но проблема глубже скорости. Сканеры работают по сигнатурам: известный CVE, известный паттерн ответа, известный путь. Контекст приложения им недоступен. По данным OWASP Top 10 (2021), Broken Access Control (A01:2021) стоит на первом месте - 94% протестированных приложений содержат проблемы контроля доступа. При этом автоматический сканер не проверит, должен ли пользователь с ролью «viewer» видеть эндпоинт /api/admin/export-users. Для этого нужно понимать бизнес-логику - а сканер её не читает.

Конкретный пример: Nuclei проверяет, отвечает ли /actuator/health статусом 200 с данными Spring Boot. Разработчики переименовали endpoint в /internal/status - сканер прошёл мимо. Человек, потративший десять минут на чтение JS-бандла, увидит вызов fetch('/internal/status') и пойдёт проверять руками.

CTF формирует привычку решать быстро: распознал паттерн - применил exploit - забрал flag. Будь то pwn, crypto или reversing - формат один: 15 минут на задачу. В Bug Bounty эта привычка убивает. Деньги лежат не в том, что находится за 5 минут сканирования, а в том, что требует 4 часа ручного ковыряния одного API.

Recon для bug hunting: от перечисления к пониманию​

Стандартный recon: subfinder -d target.com | httpx | nuclei. Три команды, пять минут, ощущение завершённой разведки. На практике это Active Scanning (T1595) и Network Service Discovery (T1046) - сбор поверхности, не более. Список поддоменов и открытых портов - каталог. Разведка начинается, когда вы понимаете, что стоит за каждым поддоменом.

Аналитический подход к Bug Bounty предполагает другой порядок: прежде чем атаковать, разберитесь, как приложение зарабатывает деньги. Платёжный flow, управление пользователями, загрузка файлов, экспорт данных - ошибки именно в этих местах стоят дорого. И для компании, и для хантера.

Практически:
  1. Найдите документацию к API или Swagger/OpenAPI через ffuf -w wordlist.txt -u https://api.target.com/FUZZ -mc 200
  2. Изучите changelog продукта - свежие фичи содержат больше багов, чем legacy-код (разработчики ещё не успели набить шишки)
  3. Проверьте публичные GitHub-репозитории компании (T1213.003, Code Repositories) - в issues и pull requests встречаются имена внутренних эндпоинтов
  4. Пройдите приложение как обычный пользователь - каждый экран, каждую кнопку, каждый запрос в HTTP History

Приоритизация целей bug bounty по бизнес-логике​

Не все эндпоинты одинаково ценны. HackerOne стратегия, которая приносит стабильный доход, строится на приоритизации: тестировать в первую очередь то, где ошибка создаёт максимальный ущерб.

ПриоритетОбластьТипичные находкиОриентир награды
ВысшийПлатежи и биллингIDOR, race condition на списание$1000–5000
ВысокийАутентификация, авторизацияOAuth misconfiguration, privilege escalation$500–3000
СреднийЗагрузка файлов, экспорт данныхPath traversal, SSRF$300–2000
НизкийИнформационные страницыReflected XSS, information disclosure$100–500

Новичок сканирует всё подряд и отправляет low-severity XSS. Опытный хантер тратит 80% времени на первые две строки таблицы - и получает в десять раз больше за один репорт.

Attack surface mapping: что видит сканер и что видит человек​

Сканер видит: 47 поддоменов, 12 открытых портов, 3 known CVE с severity Medium.

Человек видит: основное приложение на app.target.com, отдельный billing API на payments-api.target.com с интеграцией платёжного провайдера, staging-среду на staging.target.com с теми же credentials, внутренний инструмент admin.target.com за Basic Auth.

Разница - в интерпретации. Сканер перечислил хосты. Человек понял архитектуру: staging часто имеет ослабленные проверки, billing API обрабатывает деньги (максимальный impact), admin-панель за Basic Auth - вероятная точка входа. Это и есть переход от Vulnerability Scanning (T1595.002) к осмысленной разведке - Search Victim-Owned Websites (T1594) и Gather Victim Host Information (T1592), выполненным вручную и с пониманием цели.

Ручной поиск уязвимостей: практический workflow​

📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме

Второй паттерн - race condition. Промокод помечен как «одноразовый», но что если отправить 20 параллельных запросов на его активацию? В Burp Suite это делается через Repeater: дублируете вкладку нужное количество раз и отправляете группой (Send group in parallel). Один промокод - двадцать скидок. Сканер такое не проверяет в принципе.

Как находить сложные уязвимости в API​

Сложные уязвимости прячутся в стыках между компонентами. Injection (A03:2021, OWASP) в чистом виде встречается реже - WAF'ы отсекают очевидные пейлоады. А вот SQL-инъекция через JSON-параметр, который проксируется из одного микросервиса в другой без повторной валидации - вполне реальный кейс, я такое встречал дважды.

Burp Suite опытный хантер использует не как прокси для перехвата, а как аналитический инструмент:
  • HTTP History + фильтры - все запросы к /api/*, сортировка по response length, поиск аномалий
  • Comparer - сравнение ответов на запросы с разными ролями: что видит admin vs что видит user
  • Repeater - модификация одного параметра за раз с наблюдением за изменениями в ответе
Bash:
# Вытягиваем скрытые API-эндпоинты из JS-бандлов
grep -oP '"/api/[^"]+' main.*.js | sort -u
Эта команда часто выдаёт эндпоинты, не покрытые ни документацией, ни сканером. На одной из программ такой grep показал /api/internal/user-export - эндпоинт, который возвращал полный дамп пользователей без проверки авторизации. Nuclei про него не знал, потому что его нет ни в одном публичном шаблоне. Классика.

Автоматизация vs ручное тестирование: где граница​

Спор «автоматизация vs ручное тестирование» - ложная дихотомия. Вопрос не «что лучше», а «что для чего».

ЗадачаПодходИнструмент
Сбор поддоменовАвтоматизацияsubfinder, amass
Проверка живых хостовАвтоматизацияhttpx
Известные CVEАвтоматизацияnuclei
Перебор директорийАвтоматизацияffuf, feroxbuster
Анализ бизнес-логикиРучнойBurp Suite, голова
Контроль доступаРучнойBurp Suite Repeater
Race conditionsРучнойBurp Suite (parallel)
Анализ JS-кодаРучнойgrep, DevTools

Автоматизация закрывает первые 20% работы. Оставшиеся 80% - ручной поиск уязвимостей, и именно он приносит деньги.

Чтобы перейти от «сканер-хантера» к аналитическому мышлению, нужно 2–3 месяца осознанной практики. Не «смотреть writeups на YouTube» - а ежедневно брать одну программу и тратить 3–4 часа на чистое ручное тестирование. Без Nuclei, без subfinder, без автоматических пайплайнов. Только Burp Suite, браузер и документация.

Тренироваться можно на HTB - там есть веб-машины, где уязвимость не находится сканером по определению (вспомните любую машину с бизнес-логикой или custom API). TryHackMe даёт более пошаговый формат, но меньше свободы: когда платформа подсказывает «теперь проверь IDOR» - это не аналитическое мышление, а следование инструкции. На CTFtime встречаются web-таски, приближённые к реальным приложениям, но таймбокс CTF снова толкает к скорости вместо глубины. Реальный рост начинается на живых программах, где нет подсказок и нет flag - есть только приложение и ваше понимание его логики.

Месяц такой практики даёт больше, чем год запуска автоматических сканов по чужим wordlist.

Большинство хантеров, с которыми я общаюсь в приватных программах, застряли не из-за нехватки навыков. Проблема - в инерции CTF-мышления. На CTF вы решаете задачу за 15 минут: распознали паттерн, написали exploit, забрали flag. В Bug Bounty эта скорость работает против вас. Пока вы за полчаса прогоняете Nuclei по 50 поддоменам и переходите к следующей программе, кто-то четвёртый час сидит в Burp Suite на одном API - и находит критический IDOR в платёжном flow.

Я видел десятки хантеров, которые собирают всё новые инструменты, пишут всё более навороченные пайплайны автоматизации - и остаются на нуле находок. Не потому что инструменты плохие. Потому что ни один инструмент не заменит привычку задавать вопрос «зачем этот эндпоинт существует и кто к нему не должен иметь доступ». Bug Bounty методология, которая приносит результат - это не набор скриптов, а способ думать о приложении как исследователь, а не как оператор сканера. Для тех, кому writeups уже недостаточно и нужны лабы с реальной прогрессией и разбором застрявших мест - WAPT закрывает именно этот запрос.
Полезно

Комментарии

0