Новость из категории: Информация

Как обойти проверку подписи в xml?

Как обойти проверку подписи в xml?

В данной статье я опишу атаку XML Signature Wrapping (XSW). Но давай обо всем по порядку. Сначала общая теория в очень упрощенном виде.

Есть такое понятие, как «веб-сервис». Это некоторый интерфейс для взаимодействия между компьютерами. В качестве формата общения между ними используется XML, а если точнее, то его подвид — SOAP (Simple Object Access Protocol). То есть в общем виде это некий HTTP-сервер, на котором по определенному URLy висит веб-сервис в ожидании SOAP-запросов. Он их принимает, парсит, выполняет и отвечает в виде SOAP-ответов.

В качестве примера веб-сервиса (-ов) можно взять какой-нибудь продукт от VMware, ESXi-сервер например. Когда мы подключаемся к нему, используя стандартный vSphere-клиент, то, подсмотрев трафик, увидим множество SOAP запросов и ответов. Крутостей у SOAP'а много. Например, мы можем сделать для VMware свой клиент, на основании стандартных SOAP-библиотек почти на любом языке, и управлять сервером из консоли. Далее нам следует познакомиться с такой штукой, как XML Signature.

XMLDSig — это стандарт, описывающий, как должен подписываться XML-документ. Зачем это надо? Для того, чтобы сервер, получивший сообщение, был уверен, что его никто не изменил по пути. Зачем оно надо, если есть HTTPS (SSL)? Это необходимо по причине того, что один XML-документ может проходить несколько посредников и надо быть уверенным, что никто из них ничего не изменит. К тому же один XML-документ может быть подписан несколькими подписями (разные подписи на разные части документа). И эти два момента невозможны с использованием SSL.

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

Как обойти проверку подписи в xml?
Пример подписанного SOAP-запроса

Далее интересное для тех, кто незнаком с XMLDSig, — как «работает» стандарт. Чтобы не теоретизировать — покажу по пунктам на примере (см. рис. выше). На рисунке мы видим SOAP-пакет (строки 1-41), который состоит из двух возможных элементов — Header (2-33) и Body (35-39). В Body содержится сам запрос с параметрами, которые фактически будут обрабатываться веб-сервисом (бизнес-логика). В Header — «заголовки» для SOAP-процессора. В них нас более всего интересует XMLDSig — это строки 10-31.
Основные отличия XMLDSig от других стандартов подписей заключаются в следующем. В XMLDSig мы не подписываем весь документ полностью и целиком, а только какие-то его элементы (например, весь Body). К тому же с XMLDSig мы имеем возможность использовать несколько подписей на разные элементы. Пред-положим, что есть документ, который должен пройти несколько звеньев. Каждое звено (сервер) будет получать данный документ, добавлять свой кусочек XML — несколько элементов в Body, подписывать их (и отмечать соответствующими заголовками в Heade) и передавать дальше. А в конце получающая сторона сможет про-верить подписи каждого изменения добавления данных на каждом звене.



Так вот. Подписей может быть несколько. Обозначение подписи — элемент Signature (10). В нем есть три потомка: описание подписи — Signature!nfo (11-28), сама подпись (29) и описание ключа клиента (30). Самое интересное — Signaturelnfo. В нем самые важные элементы для нас — Reference (14, 21). Это указатели на то, какие элементы должны быть подписаны. Например, Reference (14) указывает параметром UR! на «id-22566565», а это — Body (35-39). И потому в этом Reference хранится хеш-значение от всего Body в элементе DigestValue (19), а алгоритм хеширования указывается в предыдущем элементе — DigestMethod (18).

Еще есть элемент Transforms (15-17), который может содержать в себе различные Transform (16). Смысл их понятен из названия. По сути, это определение преобразований данных, которые должны быть сделаны, перед тем как считать их хеш-сумму. Необходимо это потому, что XML очень гибок семантически. То есть, например, мы можем между параметрами вставить много переносов и пробелов, но XML-процессор все правильно воспримет. А вот для подсчета хеш-суммы это не годится. Потому и требуются «трансформации». Они указывают, по какому алгоритму стоит обработать данные, перед тем как считать хеш-сумму. Кстати, элемент CanonicalizationMethod определяет примерно то же самое, только для самого элемента Signaturelnfo.

И чтобы точно стало все ясно — покажу обратный пример. У нас есть элемент — TimeStamp (5-8), который указывает время жизни данного SOAP-запроса, чтобы запрос действовал только определенный период. Чтобы его не подменили/подделали, мы его подписываем. Для этого XML-процессор берет этот элемент (со всеми его потомками), трансформирует в стандартный вид (канонизирует), считает его хеш и кладет все это в заголовок SOAP-запроса с указанием того, что за место подписывается (Reference с Timestam-1 (21)). Далее XML-процессор проделывает аналогичные действия и с другими частями XML-документа, если это необходимо (Reference на Body — 14-я строка). Когда же заголовок Signedlnfo (11-28), описывающий, что подписывается, готов, XML-процессор шифрует его, используя свой закрытый ключ, а итог кладет в поле Signatu reValue — строка 29 (как и хеши, оно закодировано Base64). Думаю, что теперь точно должен быть понятен весь алгоритм.

Таким образом, даже небольшое изменение подписанных элементов приведет к тому, что изменится их хеш-сумма, а потому изменение будет замечено принимающей стороной... Выглядит секьюрно? Да. Но не очень :). Итак, переходим к атаке.

Еще только когда стандарт появился, нашлись люди, которые его поковыряли и наковыряли большую дыру. Было это где-то лет семь назад. Проблема заключается в гибкости XML и его подписей. Посмотри, каким образом указывается ссылка на элемент, который подписан. Это элемент Reference c атрибутом URL. А в URLe — значение атрибута элемента, типа «Timestamp-1». Технология, используемая для создания «ссылок», — XPointer. Да, мы легко можем найти этот элемент - Timestamp-1... Да, но постой! XPointer же не указывает на то, где этот подписанный элемент находится внутри XML-документов, то есть не указывает на его позицию относительно других элементов! А это значит, что мы можем переместить элемент (например, весь TimeStamp) в другое место и при этом проверка подписи пройдет успешно.

Итак, основа для атаки заключается в том, что подсистема принимающего XML-процессора, которая проверяет подпись, находит одни элементы и работает с ними, а уровень бизнес-логики приложения работает уже с другими элементами. Круто!

Как обойти проверку подписи в xml?
Классическая XSW-атака

Как же этого достичь? У нас есть масса вариаций. Вот пара примеров. Во-первых, посмотри рис. выше. Там мы настоящий Body перемещаем в Header (а точнее, в фейковый элемент, который не обрабатывается SOAP-процессором), а также создаем свой Body с нашей нагрузкой, но с другим именем. И когда сервер получит такой SOAP-запрос, оно будет проверять подпись элемента Body из фейкового элемента в Header (и подпись будет верна, так как хеш-значение будет неизмененным), а наш, хакерский Body уже попадет в само приложение. Оно ведь и верно, так как в приложение идет первый элемент Body элемента Envelope... Угар, как видишь!

Но это еще не все. Я сказал, что у нас есть масса вариаций для того, чтобы прятать те или иные элементы. Зачем это нужно? Да затем, что XML-парсеров много, а они, как известно, имеют каждый свои правила парсинга :). Приведу второй пример. В прошлом году в веб-сервисе от Amazon, который используется для управления серверами, была найдена как раз такая бага (точнее, возможность проведения XSW-атаки). И любой желающий, заполучив хотя бы один SOAP-запрос от жертвы на Амазон, имел возможность, используя XSW, выполнять ЛЮБЫЕ действия с серверами жертвы. Но XSW-атака была не стандартная, классическая там не проходила, так как в амазоновском сервисе была проверка на имена элементов (типа Body во всем документе должен был иметь именно определенное значение ID). Зато в их XML-парсере была особенность, которой ресерчеры и воспользовались: XML-парсер для проверки подписи брал первый элемент Body, а в приложение попадал второй. Вообще-то, по стандарту в SOAP может быть только один Body, но парсеры такие парсеры... Таким образом, Амазон отлично атаковался XSW за счет использования двух Body — первый с корректной подписью жертвы, а второй — с командами от хакера...

Надеюсь, пояснил понятно, а то столько напечатать пришлось :).

Здесь хотелось бы отметить несколько моментов. Хотя я и говорил о SOAP и веб-сервисах, но XML DSIG на самом деле может работать и вне SOAP'а, на обычных XML-документах. Разницы большой нет. SOAP был избран в качестве основы для примеров потому, что является более стандартным. В обычных XML-документах действуют более разнообразные алгоритмы того, какие данные попадают в проверяльщик подписей, а какие в само приложение.

Далее о минусах. Для проведения атаки, как ты, наверное, заметил, нам надо иметь хотя бы одно подписанное SOAP-сообщение от жертвы. И это очень большая проблема данной атаки... Как его заполучить? Один из вариантов — атака man-in-the-middle. Мы просто перехватим SOAP-запрос. Но да, скажешь ты, если это HTTP-протокол. А что делать, если HTTPS? Читай следующую статью :).

Очень советую понять сказанное хорошенько, так как в следующий раз (здесь не влезло) я продолжу тему, но уже про другое и эти знания нам понадобятся.

Еще материалы по теме: goo.gl/pZMfH, goo.gl/ddt!3. И еще один белый шар для XSW-атаки: несмотря на свою бородатость, атака эта актуальна. С 2011 года Юрай Соморовски (Juraj Somorovsky) и его коллеги проводили анализ этой проблемы в различных системах и фреймворках для создания веб-сервисов и обнаружили, что большая их часть уязвима к XSW. А с учетом того, что веб-сервисы чаще всего являются частью каких-то крупных (гигантских) приложений, повсеместного внедрения патчей к XSW можно ждать еще очень долго. Вот тебе и олдскульная атака.

Рейтинг статьи

Оценка
0/5
голосов: 0
Ваша оценка статье по пятибальной шкале:
 
 
   

Поделиться

Похожие новости

Комментарии

^ Наверх