BlackBox тестирование безопасности клиент-серверного API

2 года назад я выступал на конференции CodeFest с темой «Пентест на стероидах. Автоматизируем процесс» и делал пересказ выступления в качестве статьи. В этом году я с большим удовольствием снова принял участие в конференции и выступил с темой «BlackBox тестирование безопасности клиент-серверного API» и, видимо уже в качестве традиции, также делаю пересказ выступления. 59085c85f1d20969e3a7ae2ce18466e1.pngУязвимости API встречаются. Правда.

О чем разговор? Разговор про API, но API бывает разным — API операционной системы, сайта, дектопной программы, да хоть чего. Вкратце — API это обращение к методам чего-либо (например в случае ОС — запись в файл) через определенный метод. И запуск какого-нибудь файла с т.ч. зрения разработки произойдет схожим образом (тоже через API метод ОС), хотя результат выполнения команды совершенно разный. В веб-технологиях многие тоже реализуют API к своим проектам, и если на пальцах: можно отправить сообщение в соц. сети зайдя на сайт, а можно — сформировав специальный HTTP запрос. И при реализации подобного альтернативного использования функционала допускаются (как и везде) ошибки в безопасности. Статья как раз о специфичных ошибках при реализации подобного функционала в веб-проектах.От интерфейса к API методам Разберем уязвимость в API на youtube, которая не получила широкой огласки. Youtube запрещает из интерфейса использовать спец. символы типа (которые нужны для html тэгов и проведения атаки XSS) в названии роликов. Но! Если найти API и попробовать изменить название этого же видео, то все пройдет успешно. Как итог: нет, xss не выполнилась на странице youtube. Но выполнилась в письме на gmail (когда приходит письмо с роликом), что еще критичнее.Выводы? Логично — проблема в разной работе методов. А вот почему она случилась — это более интересный вопрос. Здесь бы я выделил следующее:

Практически все большие проекты используют ООП и паттерны подобные MVC. И реализации API должны были просто отнаследоваться от метода в интерфейсе и забрать все его ограничения. Значит или нет подобного шаблона и метод писался с нуля (бред? кто знает) или кастомный «хак» в работе интерфейса; Кастомный хак? Проблема разработчика, конечно. Но еще и тимлида, нужно постоянно доносить до разработчиков, где и что нужно реализовывать. Т.е. четко для всех разобрать извечный тред: где в процессе разработки мы валидируем данные (в модели, сервисе, контроллере, где-то еще). Это последствия проблемы применения сложных паттернов при разработке, которые тимлид то понимает нормально, а разработчики не дотягивают и часть валидаций в проекте в одном месте, часть — в другом. Для API корректно отнаследовались, но получили уязвимость. Что для тестировщиков?

Нужно вообще забыть всё, что мы знали об интерфейсе (его ограничениях) и тестировать проект с нуля; Проверять подмену параметров, яркий пример со скрином про FaceBook — из интерфейса нельзя было подменить id отправителя, а вот из API — можно; Проверять «стандартные» атаки, типа sqli/xss; Если есть автотесты — то это круто. Можно заменить стандартный пейлоад типа testValue1 на различные спецсимволы типа ',», >, < и матчить их (ищем XSS). Сжатие Часто API начинают разрабатывать для применения для мобильных устройств. И, при реализации, добавляют различные сжатия перед отправкой и разжатие после принятия. И есть старая, бородатая атака (ей ложили различные файлообменники) как ZIP бомбы. Вот вопрос: какого размера при распаковке может достичь архив в 42 кб? 4,5 петабайта. Скачать здесь, и тут. Суть простая — создается файл забитый нулями и сжимается. Поэтому сжатие, точнее распаковка — опасное дело, будьте внимательны.Зло JSON Иногда API предоставляется не только для какого-то конечного юзера, а порой и для пересылки данных внутри проекта. Часто это встречается на больших, крупных сайтах с различными доменами. И как-то надо взаимодействовать на стороне клиента между доменами, и тут на помощь приходит JSONP. Это такой JSON с нужными на домене 1, который оборачивается в callback. При обращении на домен 1 юзер отправит свои куки, и можно проверить, авторизован ли он и выдать нужные данные. На втором домене вставляется подобный JS с уже определенной функцией parseResponse. Но суть в том, что злоумышленник может также вставить на своем домене этот скрипт, определить свой callback и, если там sensetive данные — как-то их использовать. Прекрасный пример использования подобной уязвимости продемонстрирован в статье «Сражаясь с анонимностью».

Криптография Говоря про API сразу на им приходит подписывание запросов. Так как доступ к API часто выдается различным пользователям нужна схема их идентификации. И чаще всего используют следующую схему: каждому выдается свой API ключ, которым разработчик подписывает свои запросы, как-то так: sign = sha*(… + DATA + …)

Data — отправляемые данные, вместо многоточия API ключ.И вопрос, где ставить ключ, слева или справа? Только справа (мы говорим про подписывание запросов именно с применением подобной, очень популярной схемы). Почему? Существует атака на расширение строки. Давайте подробнее.Представим, что у нас есть данные A=1&B=2&C=3, подпись от них 07ce36c769ae130708258fb5dfa3d37ca5a67514, подпись идет по ошибочной схеме sign=sha1(KEY+DATA).А теперь ситуация: кто-то перехватил буквально один запрос от клиента к серверу и теперь хочет поменять данные в запросе, но ему потребуется новая подпись, а ключ для подписи не передается (оно и логично). Что он знает? Оригинальные данные и их подпись. Вкратце: есть техническая возможность создать расширить строку (дописать свои данные) и сделать новую подпись (хэш), не зная N байт в начале. На практике новые данные с отступом N байт при хэшировании в начале выглядят так: A=1&B=2&C=3\x80\x00\x00…\x02&C=4 . где

A=1&B=2&C=3 — изначальные данные \x80\x00\x00…\x02 — спец. байты для «отступа» (ключ для подписи) при хэшировании &c=4 — наши новые данные 12fea45fa3af7c4c7c2c327356eb9327.pngПри отправке одного и того же параметра например PHP — возьмет второй. Как раз то, что и нужно для атаки. Так как на первый мы не можем повлиять

Зло победило: можно подписывать запросы, менять параметры не зная ключа для подписи. А вот выдержка из документации по работе с API VK и Mail.RU

Vkontakte: sig = md5(name1=value1name2=value2api_secret) Mail.RU sig = md5(uid + params + private_key) Как видим — ключ справа.Я обмолвился про кражу всего одного запроса. На практике это бывает чуть проще, чем кажется (история #1, статья)

Небезопасный XML Думаю каждый встречался с XML, ничем не примечательный тип данных Простой хлеб Мука Но уже менее людей встречались с сущностями в XML

DTD Example:

XML example:

&writer;©right; Которые позволяют что-то определить, а потом повторно использовать. На примере выше — просто строки.А еще меньше людей сталкивались с внешними XML сущностями…

]> &xxe; В качестве сущности может выступить что-то внешнее, локальный файл, внешний файл по http и т.д. Т.е. это стандарт. Изначально задумывался в благих целях, например нужно отдать XMLку клиенту и взять текущее время с другого сервера (другого xml файла, доступного по HTTP).Долго не рассуждая, уязвимость очевидна. Используя различные врапперы — file:///, http:// атакующий может получать информацию о системе, сети и т.п. Иногда это может привести и к удаленному выполнению команд, например в PHP существует враппер expect://, который сначала выполняет команду на ОС и возвращает результат её работы. Так что по-умолчанию этой атаке подвержены все стандартные парсеры XML. Одно из решений приходит таким: отключить поддержку внешних сущностей. Тогда атакущий может применить XML бомбу:

]> &lol9; И «положить» сервер. Суть в постоянной пересылке сущности на сущность.Стоит помнить, что это может быть проблема не только сервера, но и клиента (например дектопное ПО клиента парсит XML).Самый яркий пример использования уязвимости — взлом FaceBook в ноябре 2013, который мог повлечь и выполнение команд от ОС.

Резюмируя:

В первую очередь перетестировать все «интересные» ограничения интерфейса; Разобраться со сжатием; Внимательно следит за JS callbac’ами; Криптография. Может быть не только атака на расширение строки, а просто слабый (например — короткий) ключ, или как-то предсказуемый. А еще можно встретить просто зашитые в мобильное приложение API данные. Кстати, их можно найти через сервис http://hackapp.com; XML — XXE; Что угодно ещё. Презентация:

Демо видео sha padding и XXE:[embedded content]

© Habrahabr.ru