Перейти к содержимому

Как учить пентест веб-приложений: нелинейный подход через разбор провалов в багбаунти

Как учить пентест веб-приложений: нелинейный подход через разбор провалов в багбаунти
Время чтения: 11 мин.

Три месяца на HackerOne (платформа для багбаунти — программ поиска уязвимостей за вознаграждение) — ноль принятых репортов. Курс по WAPT (Web Application Penetration Testing — тестирование на проникновение веб-приложений) пройден целиком, все лабы сданы, сертификат на стене. А на реальной программе я не мог найти IDOR (Insecure Direct Object Reference — доступ к чужим данным через подмену идентификатора в запросе) в API с пятью эндпоинтами (URL-адресами, через которые приложение принимает запросы). Проблема была не в курсе. Проблема — в том, как я его проходил.

Почему линейное прохождение курса по пентесту не работает

Стандартный подход к обучению пентесту веб-приложений одинаков везде: открываешь первый модуль, дотягиваешь до последнего, ставишь галочку. SANS SEC542, CyberEd, любой WAPT-курс — структура одна: разведка → сканирование → эксплуатация → отчёт. Тот же SEC542 выстраивает «repeatable process from reconnaissance through exploitation and reporting» поверх OWASP WSTG (Web Security Testing Guide — методологическое руководство для тестирования безопасности веб-приложений). Структура корректная. Способ усвоения — нет.

Линейное прохождение создаёт иллюзию компетентности. Ты знаешь, что IDOR существует. Ты решил лабу с IDOR. Но на реальной цели IDOR выглядит иначе: нет подсказок, нет очевидного /api/users/123, нет маркера «здесь уязвимость». Вместо этого — UUID (длинный уникальный идентификатор вида 550e8400-...) вместо числовых ID, вложенные объекты в JSON, авторизация через JWT (JSON Web Token — токен в заголовке запроса для подтверждения личности пользователя) и контроль доступа, который работает на одних эндпоинтах и отсутствует на других.

По данным OWASP Top 10 (рейтинг десяти самых критичных рисков веб-приложений, обновляется раз в несколько лет), Broken Access Control — нарушение контроля доступа — стоит на первом месте (A01:2021): 94% протестированных приложений содержали ту или иную форму этой проблемы. В стандартных курсах на контроль доступа приходится один-два модуля из десяти-пятнадцати. Арифметика не сходится.

Критерий Линейное прохождение Адаптивный подход
Порядок модулей От первого к последнему Определяется провалами на реальных целях
Повторение модуля Только если «не понял» После каждого провала в соответствующей категории
Связь с практикой Лабораторные задания курса Реальные багбаунти-программы параллельно
Измерение прогресса Количество пройдённых модулей Снижение числа провалов по OWASP-категориям
Время на модуль Примерно одинаковое Больше на слабые зоны, меньше на сильные

Разрыв между лабой и багбаунти — это не пробел в знаниях. Это пробел в навыке применения знаний к нестандартным ситуациям. Закрыть его можно одним способом: столкнуться с провалом и осознанно вернуться к теории.

Трекер провалов — основа адаптивного обучения пентесту

Адаптивное обучение пентесту начинается не с выбора курса, а с системы фиксации ошибок. Я веду таблицу провалов — Google Sheets, ничего сложного. Каждая строка — ситуация, когда я потратил время на программу и ушёл без результата или с отклонённым репортом.

Структура таблицы:

Дата Программа Что искал Что пропустил Почему пропустил OWASP-категория Модуль курса Статус
2024-03-12 SaaS, e-commerce SQLi в поиске IDOR в /api/orders/{id} Не проверил горизонтальный доступ A01:2021 Access Control Переигран
2024-04-08 Финтех XSS в профиле Race condition на промокоде Тестировал последовательно, не параллельно A04:2021 Race Conditions В процессе

За полгода ведения трекера набралось 23 записи. 14 из них — категория A01:2021 (Broken Access Control). Три — A04:2021 (Insecure Design — ошибки проектирования бизнес-логики, а не реализации кода). Остальные разбросаны между инъекциями (A03:2021) и SSRF (Server-Side Request Forgery — когда атакующий заставляет сервер выполнить запрос к внутреннему ресурсу).

Когда видишь паттерн — решение становится очевидным. Мне не нужно было проходить весь курс заново. Нужно было переигрывать конкретный модуль по контролю доступа — но уже с контекстом реальных провалов.

Как маппить провалы в багбаунти на модули WAPT-курса

Методика обучения WAPT, которая работает на практике, устроена как цикл: провал → анализ → возврат к теории → лаба без подсказок → повторная попытка на реальной цели.

Зафиксируй провал с конкретикой

Записи вида «ничего не нашёл» бесполезны. Нужны детали: какие эндпоинты тестировал, какие запросы отправлял, что видел в ответах. Если работаешь через Burp Suite (перехватывающий прокси для анализа и модификации HTTP-трафика между браузером и сервером), сохрани проект — потом вернёшься к логам.

Пример полезной записи: «Тестировал /api/v2/invoices/{id}. Менял id с 1001 на 1002 в GET-запросе (GET — HTTP-метод для получения данных). Получил 403 Forbidden (ответ сервера: «доступ запрещён»). Решил, что доступ защищён. Не проверил: другие HTTP-методы (PUT — обновление, DELETE — удаление), параметр expand=user в строке запроса, эндпоинт /api/v2/invoices/export

Пример бесполезной записи: «Потестил API, всё закрыто.»

Чувствуешь разницу? Первый вариант — это карта, по которой можно вернуться и доработать. Второй — белый шум.

Определи OWASP-категорию пробела

Каждый провал попадает в одну из категорий OWASP Top 10. Зачем это нужно — чтобы увидеть паттерн и понять, какой модуль переигрывать:

  • Не нашёл IDOR → A01:2021 (Broken Access Control)
  • Пропустил SQLi (SQL injection — внедрение SQL-кода в запрос к базе данных) в нестандартном параметре → A03:2021 (Injection)
  • Не понял логику бизнес-процесса → A04:2021 (Insecure Design)
  • Не заметил устаревшую библиотеку → A06:2021 (Vulnerable and Outdated Components)

Если провал не ложится ни в одну категорию — скорее всего, проблема не в знаниях, а в разведке: ты не нашёл достаточно поверхности атаки. Тогда переигрывай модуль по рекогносцировке.

Переигрывай модуль с контекстом провала

Возвращаешься не к «курсу целиком», а к конкретному модулю. Один вопрос: «Что здесь я понял на уровне теории, но не перенёс на реальный кейс?»

Порядок переигрывания:

  1. Прочитай теорию, держа в голове свой конкретный провал
  2. Выполни лабу без подсказок — запиши каждый шаг
  3. Сравни с эталонным решением — разница между твоим и эталонным путём и есть тот навык, который нужно тренировать
  4. Вернись к реальной программе и примени именно этот навык

Разбор провалов в багбаунти: три кейса

IDOR в API — пропущенный Broken Access Control

Тестировал SaaS-платформу (облачный сервис по подписке) для управления проектами. Стандартный REST API (архитектура, где ресурсы доступны по URL-адресам и управляются HTTP-методами), аутентификация через Bearer-токен (строка авторизации в заголовке запроса). Проверил очевидное: подмена числового id в GET-запросах к основным эндпоинтам. Всё закрыто — 403. Закрыл задачу.

Через неделю другой исследователь сдал репорт по этой же программе. Уязвимость: IDOR через GraphQL-мутацию (GraphQL — альтернативный способ работы с API, где клиент сам описывает, какие данные запрашивает). Мутация использовала другой идентификатор — не user_id, а internal_project_ref. REST API был защищён, GraphQL — нет.

Что я пропустил: в курсе тестирование контроля доступа и GraphQL шли разными модулями. Я «прошёл» оба, но не связал их в одну задачу. А на реальном проекте они всегда связаны.

Переигрывание: вернулся к модулю по контролю доступа, собрал собственный чек-лист. Теперь для каждого приложения проверяю:

  1. REST API — подмена id в GET, PUT, DELETE, PATCH-запросах
  2. GraphQL — мутации и query с чужими идентификаторами
  3. WebSocket (протокол двусторонней связи в реальном времени) — подписка на чужие события, если он есть
  4. Экспорт и массовые операции — проверка прав на /export, /bulk, /download

Дополнительно прогоняю [ffuf](https://github.com/ffuf/ffuf) (инструмент для перебора URL-путей и параметров) по API-путям, чтобы найти эндпоинты, которых нет в UI:

ffuf -u https://target.com/api/v2/FUZZ -w /usr/share/wordlists/dirb/common.txt -mc 200,403,401

-u — URL с маской FUZZ, которую ffuf заменяет словами из словаря. Флаг -mc 200,403,401 оставляет ответы с этими HTTP-кодами. Код 403 тоже интересен: он говорит «эндпоинт существует, но доступ запрещён» — и, возможно, запрещён не для всех ролей.

Предпосылки: Kali Linux или установленный ffuf (go install github.com/ffuf/ffuf/v2@latest), доступ к словарю.

Результат: через две недели нашёл IDOR в другой программе — через массовый экспорт отчётов, где проверка прав работала на уровне UI, но отсутствовала на уровне API. Тот самый паттерн, который я раньше пропускал.

Race condition — «проверил» не значит «нашёл»

Тестировал e-commerce платформу. Промокод на скидку 50% — одноразовый. Применил, убедился, что повторное применение возвращает ошибку. Закрыл задачу.

Проблема: я проверял последовательно. Один запрос — ответ — второй запрос. Race condition (состояние гонки — когда несколько параллельных запросов обрабатываются одновременно и обходят проверку, потому что каждый «видит» промокод как неиспользованный) работает иначе: нужно отправить 10–20 запросов одновременно.

В курсе был модуль по race conditions, но я прошёл его на скорость: понял концепцию, решил лабу с подсказкой, двинулся дальше. На реальной цели не хватило мышечной памяти — я банально не помнил, как настроить Burp Suite для параллельной отправки.

Переигрывание: вернулся к модулю, но сначала попробовал сломать лабу без инструкции, записывая каждый шаг. Потом сравнил с эталонным подходом и нашёл разрыв: я отправлял запросы через обычный Repeater (вкладка Burp Suite для ручной отправки запросов), а нужно было использовать «Send group (parallel)» — создать несколько вкладок с одинаковым запросом на применение промокода, выделить все и отправить параллельно.

Ожидаемый результат: если уязвимость есть — два или более запросов вернут HTTP 200 с подтверждением скидки. Если защита работает — только один получит 200, остальные — 409 Conflict или аналог.

Business logic — уязвимость без CVE

Этот провал не закроешь автоматическим сканером. Платформа с двухэтапной регистрацией: шаг 1 — email и пароль, шаг 2 — подтверждение email и выбор тарифа. Бесплатный тариф — урезанные функции. Платный — полный доступ.

Тестировал каждый шаг по отдельности: XSS (Cross-Site Scripting — внедрение вредоносного JavaScript-кода в веб-страницу) в полях формы, SQLi в параметрах, CSRF (Cross-Site Request Forgery — атака, при которой браузер жертвы выполняет действие на другом сайте без её ведома) на критичных операциях. Ничего.

Что пропустил: между шагом 1 и шагом 2 сервер создавал пользователя с тарифом premium_trial. Если пропустить шаг 2 и обратиться к API с токеном из шага 1 — пользователь оставался на premium_trial без подтверждения email и без оплаты. Это Insecure Design (A04:2021) — уязвимость не в коде, а в архитектуре процесса.

Переигрывание: в курсе нет отдельного модуля «бизнес-логика», но есть модули по аутентификации и авторизации. Я переигрывал их, фокусируясь не на XSS/SQLi, а на вопросе: «Какие предположения делает приложение о порядке действий пользователя?»

Теперь для каждого приложения рисую схему workflow: регистрация → подтверждение → активация → использование. Потом проверяю: что будет, если перепрыгнуть шаг? Повторить шаг? Выполнить шаги в обратном порядке? Именно здесь прячутся баги, которые не найдёт ни один сканер.

Практика пентеста веб-приложений: пошаговый алгоритм

Ниже — конкретный алгоритм, который превращает стандартный курс по этичному хакингу в адаптивную систему обучения WAPT по модулям. Три действия, ничего лишнего.

Делай раз: создай трекер и начни фиксировать провалы.

Открой Google Sheets или Notion. Создай таблицу с колонками: дата, программа/цель, что тестировал, что пропустил, почему пропустил, OWASP-категория, модуль курса, статус переигрывания. Заполняй после каждой сессии на багбаунти-программе — даже если она закончилась ничем. Особенно если закончилась ничем.

Предпосылки: аккаунт на платформе багбаунти (HackerOne, Bugcrowd) или развёрнутое тренировочное приложение — DVWA (Damn Vulnerable Web Application — намеренно уязвимое приложение для обучения) или OWASP Juice Shop (уязвимый «интернет-магазин» с полным набором рисков OWASP Top 10).

Как понять, что получилось: через 2–3 недели в таблице 5+ записей с заполненной OWASP-категорией. Если записей меньше — ты либо мало тестируешь, либо не фиксируешь «пустые» сессии.

Делай два: раз в две недели анализируй паттерны.

Отфильтруй трекер по OWASP-категории. Посмотри, где больше всего записей. Если 3+ записей в одной категории — сигнал: навык по этому направлению не переносится с лабы на реальную цель.

Как понять, что получилось: ты можешь назвать свою слабую зону конкретно — «A01:2021, Broken Access Control, я не проверяю GraphQL-эндпоинты» — а не абстрактно «мне нужно больше практики».

Делай три: переигрывай конкретный модуль курса с контекстом провала.

Открой модуль, который покрывает твою слабую категорию. Не проходи его как в первый раз — используй свой провал как кейс. Вопрос один: «Что из теории этого модуля я не применил на реальной цели?» Выполни лабу без подсказок, запиши шаги, сравни с эталоном. Потом вернись к реальной программе.

Как понять, что получилось: после 2–3 циклов «провал → модуль → повтор» количество записей в трекере по конкретной категории снижается. У меня A01:2021 упала с 14 записей за первое полугодие до 3 за второе. Первый принятый репорт пришёл не после нового курса — после третьего возврата к модулю по контролю доступа.

Большинство споров о том, как готовиться к багбаунти, сводятся к выбору «правильного» курса или «правильной» платформы. Я видел людей, которые прошли SEC542 и за полгода не сдали ни одного репорта. И видел тех, кто взял бесплатный OWASP WSTG, связку Burp Community + ffuf и закрыл первую валидную находку через месяц. Разница не в материале — в том, как человек работает с обратной связью от реальных целей.

Курс — каркас. Багбаунти — среда, которая показывает, где каркас шатается. Если проходишь курс и не возвращаешься к нему — получаешь иллюзию компетентности. Если возвращаешься после каждого провала — получаешь навык.

У меня ушло четыре месяца на осознание, что первый «полный» проход WAPT-курса был разминкой. Настоящая прокачка навыков этичного хакера началась, когда я стал переигрывать модули под конкретные неудачи. Если ты сейчас проходишь WAPT-курс линейно и думаешь, что после финального модуля готов к багбаунти — остановись и спроси: на какой реальной цели ты уже попробовал? Провалы, которые ты соберёшь параллельно с обучением, стоят дороже любого сертификата. А если хочешь не просто writeup, а пройти всю атаку от разведки до отчёта — на WAPT есть лаба с прогрессией на каждый кейс и ментор в чате при затыке.

Эту тему и смежные навыки разбирают на практике в курсе «Тестирование веб-приложений на проникновение (WAPT)» Codeby Academy.