Авторские курсы Михаила Тарасова

XXE через нестандартные MIME: как взломать API через «левый» content-type

XXE через нестандартные MIME: как взломать API через «левый» content-type

Точка входа

Что вижу:
API принимает данные с Content-Type: application/xml+quotes, но парсит как XML. В ответе на <root>&foo;</root> → ошибка «Entity ‘foo’ not defined». Пахнет внедрением сущностей, как тухлый сыр в холодильнике пентестера.

Как поймал:
— Инструмент: curl -X POST -H "Content-Type: application/x-broken" --data-binary @payload.xml
— Метод: Подмена MIME-типа на кастомный (application/x-php-serialized, text/x-xmlz).

Чем пахнет:
— Класс: Blind XXE через неочевидные MIME + парсер-легаси.
— Вероятность: 7/10. Девы верят, что «нестандартный MIME = защита».

Че почем

Эксплойт:

Где evil.dtd:

Обход защиты:
— Если WAF блокирует SYSTEM: Замени на PHP-фильтры: php://filter/convert.base64-encode/resource=/etc/shadow.
— Если запрещают внешние DTD: Используй внутренние ентити через параметры:

Доказательство:
Скриншот логов с утекшим /etc/passwd в URL-параметре. «Видишь root:x:0? Это не список юзеров — это твой future RCE».

Хвост от старика

3 вектора для добивания:

  1. XXE через SVG в PDF: Засунь вектор в SVG, заверни в PDF с MIME application/pdf+xml.

  2. Атака на SOAP: Если API кушает application/soap+xml, подмени на text/xml и вставь ентити.

  3. JSON-Polyglot:

План атаки:

  1. Фаззишь MIME-типы: application/xml-reporttext/xml-stream.

  2. Ловишь слепой XXE через OOB-канал (DNS или HTTP).

  3. Если слепой — используй тайминг-атаки:

  1. → Длинный ответ = файл существует.

Бонус от деда

Если в хедерах X-Parser: libxml2/2.9.0:
— Гугли CVE-2020-24941 (XXE в PHP 7.4).
— Эксплойт:

Content-Type: application/xml-woof.

Мемная аналитика:
«Нестандартный MIME — как рюкзак с надписью «не бомба»: все видят, но парсят как обычный XML».

Итог:
— Уязвимость: Парсеры, жрущие XML под любым MIME.
— Фикс: Жёстко валидировать Content-Type, отключать ентити.
— Но пока фикса нет — дамь файлы через кастомные заголовки.

Мои курсы