Безопасность как искусство
92,45
рейтинг
20 ноября 2013 в 00:33

Разработка → 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). Да и не все выносят upload контент на отдельные домены (и вот тут уже impact как от полноценной xss на основном домене). Стоит отметить, что нужен именно отдельный домен, а не поддомен.

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

Комментарии (3)

  • +3
    Почему-то такой код не работает во вконтакте:

       <script type="text/javascript">
       var allcookies = document.cookie;
       alert("All Cookies : " + allcookies );
       </script>
    


    Хотя и там в контексте поддомена на котором кук нет.
    • 0
      iOS уже не торт.
    • 0
      Я сразу увидел Ваше сообщение, всё времени нет посмотреть детально. Алерта и правда нет, думаю на выходных еще посмотрю.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разработка