XSS’им iOS устройства на примере софта от Facebook, Google, ВКонтакте

от автора

Данный фиче-баг схож с историй про отправку сообщения в Facebook от любого юзера — известен, но не получил широкую огласку. Получилось так, что нашел я его сам, а уже потом нашел информацию о нём в интернетах. Но обо всем по порядку…

# intro

Темной, холодной и дождливой Питерской ночью обнаружил я забавный баг, которому оказались подвержены приложения от Facebook, Google, ВКонтакте и скорее всего, от многих других производителей. Для его объяснения нам просто необходимо знать немного теории.

1/2 Идеология iOS

Идеологически iOS имеет принцип: никаких левых файлов на устройстве, никакого прямого доступа к контенту и никаких файловых менеджеров. Мы сами все раскидаем по разным категориям и выдадим конечному юзеру в наиболее удобном формате. В итоге в iOS не предусмотрено сохранение произвольных файлов на устройство. Конечно, есть исключения, когда приложения выкачивают себе дополнительный контент с произвольным типом данных (например, карты городов, ресурсы игры и т.п.), но они все друг от друга изолированы и являются лишь локальным хранилищем для приложения.

2/2 Про HTTP

Протокол HTTP очень прост и использует самую очевидную модель. Всё передается обычным plain текстом. Запрос/ответ обязательно содержит заголовок (header) и (возможно) тело (body). Разделены они через обычный перенос строки (пустую строку). Пример запроса для открытия habrahabr.ru:

GET / HTTP/1.1 Host: habrahabr.ru User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Connection: keep-alive 

Ответ:

HTTP/1.1 200 OK Server: nginx Date: Tue, 19 Nov 2013 13:48:02 GMT Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive Keep-Alive: timeout=25 X-Powered-By: PHP/5.4.21 X-Frame-Options: SAMEORIGIN Content-Encoding: gzip  <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">   <head>     <meta http-equiv="content-type" content="text/html; charset=utf-8" />     <meta name = "viewport" content = "width = 1080">     <title>Лучшие за сутки / Посты / Хабрахабр</title> ... </html> 

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

Content-Disposition: attachment 

Который описан в RFC 2183 следующим образом

2.2 The Attachment Disposition Type

Bodyparts can be designated `attachment’ to indicate that they are
separate from the main body of the mail message, and that their
display should not be automatic
, but contingent upon some further
action of the user. The MUA might instead present the user of a
bitmap terminal with an iconic representation of the attachments, or,
on character terminals, with a list of attachments from which the
user could select for viewing or storage.

В типичном браузере это выглядит так, что вы обращаетесь к файлу, а он не отображается (как вы привыкли) а предлагает его сохранить (their display should not be automatic).

# exploit

А теперь давайте соединим два момента выше. Мы обращаемся на устройстве с iOS к файлу, у которого Content-Disposition: attachment. Получается противоречие. Вроде файл надо сохранить (как обычно и привыкли юзеры, видеть окно сохранения на устройство), но и сделать этого нельзя — ведь возможности такой то и нет. Что же сделали в Apple? Они просто игнорируют в мобильном Safari Content-Disposition и отображают файл в браузере.
Что с мобильными приложениями? В клиентах FB, Gmail, VK, везде есть вложения в сообщения. Если отправить, например, html или svg файл, то вызывается компонент webview (читать как Safari) который его и рендерит.

xss.svg

<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">  <svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">    <polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>    <script type="text/javascript">    alert('Redirect to google.ru...');    document.location="http://google.ru";    </script> </svg> 

В итоге, Apple, пытаясь обезопасить и пытаясь улучшить жизнь своим пользователям создала неочевидный момент для разработчиков iOS и, всё-таки, снижение безопасности. Никаких уведомлений, что данный контент будет показан мгновенно. Возвращаясь к RFC, было бы достаточно обычного уведомления что-то типа: «данный контент должен быть сохранён, но он будет показан в браузере», но ничего подобного мы не видим. Исключение все же есть только в одном варианте — Facebook, мобильная версия.

# demo

GMail
Facebook
VK

# impact

Как можно заметить, javascript выполняется на другом домене, отличным от основного. Этот домен предназначен только для вложений в сообщения и полностью изолирован от основного сайта. Поэтому реакция, например, Google на это — именно такая (т.е. никакая)

The domain in which you’re triggering the XSS — googleuserconent.com — is specifically meant as a compartmentalized «sandbox» for various types of potentially unsafe, user-controlled content. This domain is isolated from any sensitive content due to the same-origin policy.

Что и верно. Например на нём можно и обычном браузере выполнить XSS.

Но есть другие вектора — фишинг или DoS (например с 0day эксплойтом, который задевает все(?) версии iOS — habrahabr.ru/company/dsec/blog/201602/.

В общем, будьте осторожны при открытии вложений на IOS устройствах и при разработке веб-приложений с вложениями. Ведь данный фиче-баг прекрасно воспроизведется и в любом браузере iOS (ведь все они за основу используют Safari).

ссылка на оригинал статьи http://habrahabr.ru/company/dsec/blog/202784/


Комментарии

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *