Главная > Uncategorized > Атака XXE (XML eXternal Entity)

Атака XXE (XML eXternal Entity)

«Новое — это хорошо забытое старое» мигом вспомнилась мне поговорка, когда при оценке защищенности очередного веб-приложения успешно прошла атака XXE. Немедленно захотелось написать об этом пару слов, ибо:
— XML-транспорт занял одно из доминирующих мест по распространенности в распределенных приложениях (в т.ч. клиент-серверных веб-приложениях, кстати);
— ни один из 5 запущенных сканеров (специально не поленился и проверил) эту, в принципе достаточно простую с технической точки зрения, уязвимость не нашел;
— ни разу не слышал от коллег упоминаний о нахождении и/или эксплуатации этой уязвимости.
Итак, к делу.
Уверен, что возможность внедрения выражений XPath, равно как и внедрения XML-тэгов ни для кого не является новостью. Это первое, с чего хочется начать проверять целевое приложение, использующее xml. Однако есть еще один вектор атаки, о нем подробнее.

Начнем издалека. Стандартом определены два уровня правильности документа XML:

  • Well-formed документ. Well-formed документ соответствует всем общим правилам синтаксиса XML, применимым к любому XML-документу. И если, например, начальный тег не имеет соответствующего ему конечного тега, то это неправильно построенный документ XML.
  • Valid документ. Valid документ дополнительно соответствует некоторым семантическим правилам. Это более строгая дополнительная проверка корректности документа на соответствие заранее определённым, но уже внешним правилам. Обычно такие правила хранятся в специальных файлах — схемах, где самым подробным образом описана структура документа, все допустимые названия элементов, атрибутов и многое другое.

Основные форматы определения правил валидности xml-документов — это DTD и XML Schema. Остановимся на DTD. Есть два варианта связать документ с его схемой: либо указать ссылку на схему, либо поместить схему прямо в сам xml-документ, в его начало. Вот два примера:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE order SYSTEM "order.dtd">
<order>
<product>1234</product>
<count>1</count>
</order>

<?xml version="1.0"?>
<!DOCTYPE order [
<!ELEMENT count (#PCDATA)>
<!ELEMENT product (#PCDATA)>
<!ELEMENT order (product, count)>
]>
<order>
<product>1234</product>
<count>1</count>
</order>

Кроме того, в xml есть такое понятие как внешние сущности (external entities). Их можно использовать, например, для добавления в xml-документ содержимого внешних файлов. Например, можно определить внешнюю сущность current-date:
<!ENTITY current-date SYSTEM "http://www.getcurrenttime.com/timestamp.xml">
и перенести логику по вычислению текущей даты и времени на внешний сервис. Соответственно, использовать можно так:

<?xml version="1.0"?>
<!DOCTYPE order [
<!ELEMENT count (#PCDATA)>
<!ELEMENT product (#PCDATA)>
<!ELEMENT date (timestamp)>
<!ELEMENT timestamp (#PCDATA)>
<!ELEMENT order (product, count, date)>
<!ENTITY current-date SYSTEM "http://www.getcurrenttime.com/timestamp.xml"&gt;
]>
<order>
<product>1234</product>
<count>1</count>
<date>&current-date;</date>
</order>

Теперь вернемся к парсерам. Парсеры бывают валидирующими и невалидирующими. Вот что сказано в стандарте [http://www.w3.org/TR/REC-xml#include-if-valid] по поводу поведения парсера при наличии в документе ссылок на внешние сущности:
«When an XML processor recognizes a reference to a parsed entity, in order to validate the document, the processor must include its replacement text. If the entity is external, and the processor is not attempting to validate the XML document, the processor may, but need not, include the entity’s replacement text…»
То есть валидирующий парсер обязан включить содержимое внешнего файла. Действительно, для того, чтобы проверить структуру документа, парсер должен разрешить все внешние связи. А вот невалидирующий может включить содержимое внешнего файла по желанию.
На этом месте все уже должны догадаться об атаке.
Если в POST-запросе передается xml, можно делать такое:

<!DOCTYPE input [<!ENTITY xxe SYSTEM "file:///dev/random" >]><input>&xxe;</input>
Делаем DoS.

<!DOCTYPE input [<!ENTITY xxe SYSTEM "file:///path-to-tomcat-application/WEB-INF/web.xml" >]><input>xxe;</input>
Включаем содержимое xml-файла. Валидирующий парсер, очевидно, по итогам разбора выдаст ошибку. Таким образом, этот трюк пройдет только с невалидирующим парсером. Плюс к этому, значение параметра, в который вы внедряете ссылку на внешнюю сущность, должно возвращаться обратно (иначе вы никак не получите содержимое вставленного файла).

<!DOCTYPE input [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]><input>&xxe;</input>
Включаем содержимое обычного файла. Тут все очень зависит от парсера и содержимого файла:
— есть парсеры, которые требуют, чтобы внешние файлы были well-formed xml-документами (самый неудобный случай);
— остальные парсеры требуют, чтобы итоговый документ был well-formed (очевидно). В этом случае в подключаемом файле не должны встречаться специсимволы xml, которые нарушат синтаксис документа. Соответственно, этот трюк может сработать даже с валидирующим парсером (структура документа же нарушится).

Кроме того, необходимыми условиями срабатывания атаки являются:
— парсер должен уметь разрешать ссылки на внешние сущности; для многих простых парсеров это условие не выполняется;
— парсер должен иметь настройки, позволяющие ему разрешать ссылки на внешние сущности; например, известный парсер xerces изначально имел «удобные» настройки по умолчанию, но с некоторой версии (вот бы узнать, с какой) они эти настройки изменили, так что теперь по умолчанию xerces не будет разрешать такие ссылки; зато libxml имеет «удобные» настройки по умолчанию до сих пор.

Ссылки по теме:
1. Первое упоминание об атаке: http://www.securityfocus.com/archive/1/297714.
2. Отличная презентация с конференции OWASP AppSec Germany 2010: XML External Entity Attacks.
3. Еще одна прекрасная презентация по теме с конференции OWASP Poland 2010: XML DTD Attacks.

Реклама
  1. 03.04.2011 в 23:49

    Завёл тикет: https://sourceforge.net/apps/trac/w3af/ticket/162460
    Попробуем сделать :)

    • 04.04.2011 в 07:22

      Круто. Только я, если честно, не представляю, как это сделать по-нормальному.

      Проблемы:
      1. Как узнать, куда внедрять payload?
      В идеальном случае XML-документ собирается на клиенте и передается в теле запроса. С этим все ясно. Но иногда на сервер передаются обычне key=value пары, которые потом проставляются в XML-документ, который уже парсится (или отправляется на другой Application-сервер для обработки)? Соответственно, во втором случае можно везде, где делается XML-injection, так же пробовать внедрять расширенные XML-payload’ы с DTD-описанием XXE и ссылкой на нее. Но как определить, что сервер собирает на основе key=value XML-документ с возможностью внедрения тэгов? Представляется, что самый простой способ — вызвать ошибку парсера.
      Итого, передаем хитрые payload’ы типа "’@ или />><a> и т.п. Если есть ошибка — считаем, что есть возможность внедрения XML и пробуем атаку XXE.

      2. Как понять, что атака успешна?
      С одной стороны, есть вариант с DoS’ом и замером времени отклика сервера. Но такое нельзя делать на production-системах. Есть второй вариант — запрашивать well-known файлы и проверять по сигнатурам, что вернулось их содержимое…

      В общем, обнаружение уязвимости XXE черным ящиком — отдельная большая исследовательская задача :)
      Как сделаете — опубликуй, пожалуйста, алгоритм — очень интересно почитать.

      p.s. Подозреваю, что можно еще как-то фингерпринтить XML-парсер на стороне сервера.

  2. 27.10.2011 в 11:03

    http://yehg.net/lab/pr0js/pentest/wordlists/injections/XML.txt

    Более-менее про реализацию )

  3. M4g
    18.02.2012 в 19:48

    Привет. Я редактор рубрики Взлом в журнале Хакер. Было бы здорово, если бы ты написал статью для нас на тему XXE. Жду ответа на мейл magg@real.xakep.ru.

  1. No trackbacks yet.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: