Комикс о UXSS в Safari и Chrome

By 14 ноября 2017Blog

Привет! Помимо уязвимостей клиентской части веб-приложений опасность представляют и само клиентское ПО. Нет, речь даже не о java или flash, а о самих браузерах.

Хочу показать тебе примеры двух браузеров-конкурентов с уязвимостью UXSS (Universal Cross-site Scripting), один из которых с закрытым исходным кодом, а другой с открытым. UXSS — это ошибка в логике работы браузера, благодаря которой злоумышленник может выполнить javascript сценарий в рамках произвольного сайта. Грубо говоря — сделать XSS там, где ее нет.

 

Safari

Что я могу сказать хорошего о Safari? Это простой и легковесный браузер, в котором нет ничего лишнего. Это правда самый быстрый браузер который мне довелось использовать. Что плохого? Ну… Он странный.

Возможно, ты уже читал мою статью о чтении локальных файлов с помощью браузера. Если коротко — открыв следующий html файл в Safari он прочитает локальные файлы и попытается слить личные документы, в рамках PoC — на свою же локальную машину (в консоли разработчика ты увидишь ошибки).

А еще функции в консоли выполняются в момент ее написания, жуть!

 

А вот что ты слышал о псевдорасширении parent-tab://? Да ничего, лишь пара упоминаний. Однако в Safari он присутствует.

Примечательно, что до 11 версии (уже) parent-tab имеет все те же привилегии для доступа к объектам домена, например к cookie.

А еще круче — в него можно писать. Вот создаешь локальный html, пишешь <iframe> с parent-tab и js’ом записываешь произвольное содержимое! Так рождается первый эксплойт, где в parent-tab.html — редирект на parent-tab://+domain

Однако, его нельзя вызвать с другого сайта, что немного огорчает. Локальные эксплойты не так весело (ну чтение файлов веселее).

Тут на помощь пришел Frans Rosén, который выяснил, что записать свою полезную нагрузку можно также с помощью window.open с аргументом _top. Вжух — и мы получаем доступ к данным сайта.

Но оказалось, эта бага в WebKit, поэтому, возможно, применима и к Chrome. Примеры эксплойта на CVE-2017-7089 ждет тебя на github.

Chrome

Хром более защищенный браузер. Наверное. Все таки это браузер с открытым исходным кодом. Между тем, несмотря на современность — в нем до сих пор поддерживаются старые вещи, например поддержка древнегреческого формата MHTML (MIME-HTML).

Что из себя представляет данный формат? Это текстовый документ, в котором прописан заголовок, тип контента (Content-Type: multipart/related) и разделитель контента (boundary). Да-да, multipart в файле. Дальше следуют дополнительные параметры, типа кодировки (может быть base64).

Ну проще один раз увидеть.

Так вот, к файлу можно написать атрибут Content-location, а потом обратиться к нему в самом html.

Например, пишем Content-location: /abc, содержимое файла. И вызываем <img src=/abc>. А можно написать Content-location: https://example.com/abc, и загрузить <img src=https://example.com/abc>

Если это изображение — то оно появится на странице при попытке открыть данный файл.

Все бы ничего, но javascript в нем запрещен. Вообще.

Но и тут находится одно «но».  Везде, кроме XSLT.

Объявляем content-type: application/xml, вставляем XSLT, получаем alert():

MIME-Version: 1.0
Content-Type: multipart/related;
type="text/html";
boundary="----MultipartBoundary--"
------MultipartBoundary--
Content-Type: application/xml;
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xml" href="#stylesheet"?>
<!DOCTYPE catalog [
<!ATTLIST xsl:stylesheet
id ID #REQUIRED>
]>
<xsl:stylesheet id="stylesheet" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*">
<html><script>alert()</script></html>
</xsl:template>
</xsl:stylesheet>
------MultipartBoundary----

Ну и как ты уже догадался, в таком документе мы можем написать Content-location: https://example.com и вызвать javascript оттуда, обойдя песочницу вопреки всем законам SOP. Добавляем к предыдущему файлу следующий файл и вместо alert вызываем его в фрейме.

------MultipartBoundary--
Content-Type: text/html
Content-Location: https://google.com
<script>alert('Location origin: '+location.origin)</script>

Для открытия MHTML нужно вернуть в ответе от сервера тип контента multipart/related, в итоге построится следующее DOM-дерево:

В хроме внесен соответствующий патч (благодаря которой был найден эксплойт). Плюсы — открытый исходный код позволяет наблюдать за всеми внесенными изменениями. Минусы точно такие же.

Демонстрация эксплойта по следующей ссылке (Chrome < 62), исходники CVE-2017-5124 на github.

Вывод

Какой-такой вывод? Ну будь аккуратнее, обновляй ПО для минимизации рисков, но ты это слышал уже тысячу раз. Что-то нового я тебе сказать не могу 🙂

Join the discussion 3 комментария

Leave a Reply