
Данная статья является вводной для небольшого цикла, посвященного механизмам безопасности, предназначенным для противодействия успешной эксплуатации уязвимостей класса memory corruption в web-браузерах. В рамках этого цикла мы рассмотрим, какие механизмы и с какой целью внедряются разработчиками браузеров, и поговорим о том, как их можно было или до сих пор можно обойти.
Security mitigations
Как-то подобную тему мы уже поднимали в своем блоге в статье .
Подобные механизмы можно разделить на категории по уровню, на котором они работают или применяются:
- На уровне аппаратного обеспечения – (DEP, MPX, CFI, SMEP, SMAP, UMIP, …).
- На уровне операционной системы – реализовано создателями ОС. Например, SEHOP, ForceASLR. В случае ОС Linux может быть еще выполнено в виде дополнительного патча (Grsecurity).
- На уровне компилятора/линковщика – stack cookie, SafeSEH.
- На уровне приложения:
- Стороннего – EMET, Malwarebytes Anti-Exploit, HitmanPro, PaX и подобные реализации в различных антивирусах;
- Встроенного – реализовано прямо в исходном коде приложения.
Механизмы могут быть также направлены на решение конкретной задачи:
- Усложнить (понизить стабильность техники)
- Сделать невозможной работу какой-то техники (Противодействие конкретной технике)
- Смягчить последствия (Изоляции от остальной системы, sandbox)
- с BlackHat USA 2012
- с BlackHat USA 2016
App specific security mitigations
Данный цикл статей как раз и будет посвящен последней категории, т.н. app specific security mitigations. Появление этих механизмов обусловлено самой функциональностью приложения и особенностями его реализации, как правило, затрагивающими или реализующими собственные абстракции манипулирования памятью: собственная ВМ, собственный менеджер кучи, собственный скриптовый язык и т.д.
Самыми яркими представителями можно назвать:
- Браузеры
- Редакторы документов (Word)
- Виртуальные машины (JVM, Dalvik VM, ActionScript VM)
Браузеры
Поскольку браузеры — самые яркие (и, наверное, самые интересные) представители ПО, реализующие собственные механизмы безопасности от эксплуатации уязвимостей класса memory corruption, мы решили в нашем исследовательском центре сосредоточиться на них. Цикл статей будет посвящен: IE + Edge, Chrome и Firefox для настольных ПК под управлением ОС Windows на x86/x64 архитектуре. Список этих механизмов был взят из обновляемой подборки : нашего друга , за что ему большое спасибо.
В 2011 году компания Accuvant LABS выпустила документ , но уже много воды утекло с того момента, и браузеры серьезно изменились. Однако, ознакомиться с этой информацией все равно не лишне.
Если обобщить рассматриваемые нами в дальнейшем механизмы, можно обозначить несколько групп:
- предотвращение непредусмотренного выполнения кода или данных
- предотвращение проблем, связанных со временем жизни объекта
- сохранение целостности кода, данных или метаданных
- ограничение информации об адресном пространстве
- ограничение возможностей атакующего (sandbox)

Для тех, кто хочет более подробно ознакомиться с успешными эксплоитами для браузеров, советуем обратить внимание на выступление “$HELL ON EARTH: FROM BROWSER TO SYSTEM COMPROMISE” ( и ) с BlackHat LasVegas 2016.
Как можно заметить, даже такие “бронированные” программы успешно атакуются с обходом всех механизмов защиты как ОС, так и их собственных. В итоге, исследователи обходят с десяток механизмов безопасности – в действительности, конечно, меньше, так как это сильно зависит от типа используемых уязвимостей. Например, не обходятся механизмы stack cookie с SafeSEH, SEHOP, если уязвимость UaF — поскольку природа уязвимости никак не связана со стеком, и данные механизмы не задействованы. Самую большую угрозу для браузеров представляют уязвимости типа use-after-free (UaF) — – тут все обусловлено сложностью браузеров. Поэтому неудивительно, что разработчики трудятся над созданием механизмов защиты, ориентированных на противодействие данному типу уязвимостей. Следующий момент, которому уделено также пристальное внимание (с точки зрения безопасности) создателями браузеров, это написание JIT (just-in-time) кода. Это связано с тем, что атакующий использовать такой код для расположения своего шеллкода внутри JIT spray, который одновременно позволяет обойти как DEP, так и ASLR. Поэтому разработчики и стали в этом направлении. Об этом мы также поговорим позже.
Важно понимать, что у любого атакующего есть определенные цели, и он будет к ним идти по пути наименьшего сопротивления. Так, например, не всегда ему нужно выполнять свой собственный шеллкод и закрепляться в системе, получая доступ к данным других приложений. Если в этом нет необходимости, то не нужно обходить CFG и sandbox. При этом, он способен похитить какие-то данные доступные/хранимые браузером, или задействовать его же стандартный функционал, но в своих целях (например, подмена данных или изменение настройки браузера).
RW-примитив
Все постепенно идет к тому, что при наличии у атакующего RW-примитива (уязвимости или ряда уязвимостей, позволяющих ему читать и писать в память), все текущие механизмы защиты обходятся.
Чаще всего, это реализуется благодаря:
- : Improper Release of Memory Before Removing Last Reference ('Memory Leak')
- : Write-what-where Condition — write-what-where memory corruption примитива
Стоит отметить, что примитив “Write-what-where” иногда бывает ограничен:
- Не контролируется, то что пишется
- Возможно писать только NULL
- Возможно только инкрементировать значение
- Как-то ограничен диапазон адресов, куда мы можем писать
Для ознакомления с мощностью RW-примитива приведем ряд примеров:
- Замечательный побега из гостевой виртуальной машины VirtualBox, также благодаря RW примитиву.
- эксплотации в Silverlight (CVE-2016-0034)
- Отличный под Linux
- Пример [,] под Android
- Пример [,,] с ядром Windows
- Браузеры, конечно, не исключение, но об этом позже.
В цикле статей мы рассмотрим более специфичные техники обходов механизмов браузеров.
Промежуточный вывод
Уязвимости класса memory corruption были, есть и будут и их будут продолжать эксплотировать. Единственное со временем это все становится сложнее. И очень много зависит от природы уязвимости. Так что на компилятор, ОС, надейся, а сам не плошай.
P.S. Повреждение памяти это хорошо для атакующего, а логические уязвимости просто замечательно или даже web баги типа UXSS это всегда это 100% надёжность, и часто кросплатформенность.