21.05.2013

Новая техника подготовки динамической памяти для эксплуатации уязвимостей браузера в Metasploit

image

Наличие уязвимостей в браузерах во все времена было опасной угрозой для Интернет-сообщества. Как правило, уязвимости нулевого дня используются для укрупнения ботнетов или «изощренных» адресных атак в политических или экономических интересах.

Автор: sinn3r

Наличие уязвимостей в браузерах во все времена было опасной угрозой для Интернет-сообщества. Как правило, уязвимости нулевого дня используются для укрупнения ботнетов или «изощренных» адресных атак в политических или экономических интересах. Хотя уязвимости нулевого дня появляются чаще, чем когда-либо, некоторые методы их использования остаются практически теми же. Наиболее часто используемый трюк: подготовка динамической памяти или «heap spray», когда происходит подготовка памяти путем управления участками кучи (heap allocations), а затем размещение кода в определенном месте. Таким образом, когда вы контролируете аварийную ситуацию, вы можете обойти защитный механизм программы и выполнить код. Однако с годами использовать эту технику становится все труднее. Методы, которые работают в браузерах IE6 и 7, не будут работать с IE8. А то, что работает в IE 8, вероятно, не будет работать в IE9 и 10.

Недавно Питер Ван Экхауте (Peter Van Eeckhoutte) представил новую технику по подготовке динамической памяти, которая работает с несколькими браузерами: Internet Explorer 8, 9, 10, а также последней версией Firefox. Я практически убежден, что эта техника может изменить способ написания эксплоитов для браузеров в Metasploit. Так что я решил портировать пример Питера в Metasploit как новую функцию (с его помощью) и показать вам пример использования этой функции.

Рабочая среда

В данном примере я буду использовать Internet Explorer 10 в Windows 8. Убедитесь, что разрешена отладка скриптов в IE во время разработки. В качестве отладчика я буду использовать WinDBG, который можно загрузить отсюда:

http://msdn.microsoft.com/en-us/windows/hardware/gg463009.aspx

Пример кода

Процедура, использующая новый метод, написана на JavaScript. Перед использованием убедитесь, что у вас подключен модуль «Msf::Exploit::Remote::HttpServer::HTML», а затем просто запустите процедуру «js_property_spray», которая вернет код sprayHeap(). Далее вы можете внедрить этот код в вашу веб-страницу. Функция sprayHeap() поддерживает следующие параметры:

Параметр

Описание

shellcode

Шеллкод для запуска. В качестве примера, можно использовать такой формат: unescape("%u4141%u4141"). Обычно это означает ROP плюс шеллкод.

objId

Необязательный. Значение атрибута ID для HTML-тега <div>. Если вы опустите этот параметр, JavaScript сгенерирует простой div-элемент.

offset

Необязательный. Размер смещения для помещения шеллкода по нужному адресу. По умолчанию 0x104 байт.

heapBlockSize

Необязательный. Необходимый размер участка. Обратите внимание: если этот размер слишком мал, ваш шеллкод не сохранится в указанном месте в памяти. По умолчанию 0x80000.

maxAllocs

Необязательный. Количество участков. Обратите внимание: в IE10, если он работает слишком медленно, результаты работы шеллкода будут также непредсказуемы. Экспериментальным путем мы выяснили, что оптимальный вариант где-то около 0x500. По умолчанию 0x350.

def load_spray_html
spray = js_property_spray #Load the heap spraying JavaScript
html = %Q|
<html>
<head></head>
<body>
<script>
#{spray}
var s = unescape("%u4141%u4141%u4242%u4242%u4343%u4343%u4444%u4444%u4545%u4545%u4646%u4646%u4747%u4747");
sprayHeap({shellcode:s}); // Call the heap spray routine
alert("Done!");
</script>
</body>
</html>
|
return html
end

Для тестирования этой функции вы можете загрузить код отсюда:

https://gist.github.com/wchen-r7/89f6d6c8d26745e99e00

Исследование подготовки динамической памяти

В Internet Explorer при каждой итерации создается два участка, содержащих наши данные. Первый участок создается при вызове функции substring(), однако, в конце концов, он освободится. Второй участок создается, когда данным назначаются свойства. В этом случае будет вызываться функция SetStringProperty (или SetProperty в IE9), и данные останутся в памяти. Все эти участки можно найти в стандартной куче процесса.

Когда подготовка динамической памяти завершена, вы можете посмотреть ее структуру в отладчике:

!heap -stat -h

WinDBG должен вывести список всех участков стандартной кучи процесса, нечто вроде этого:

Поскольку по умолчанию значение переменной heapBlockSize равно 0x80000, а значение переменной maxAllocs по умолчанию равно 0x350, совершенно очевидно, что все работает корректно. Для выгрузки всех участков, введите следующую команду:

!heap -flt s 0x80000

Затем вы увидите нечто вроде этого:

Обратите внимание, все начальные адреса участков оканчиваются на XXXXXX18, т.е. имеют довольно предсказуемый паттерн. Когда адрес предсказуем – это означает, что ваша полезная нагрузка (payload) также находится в предсказуемом месте. Рассмотрим повнимательнее последний адрес:

db 2b108018

Вы видите, что адрес указывает на поле, состоящее из значений 0x20. Это означает, что мы имеем дело с мусорным наполнением участка. Теперь, вероятно, вы задумались над тем, где же хранятся данные, верно? В WinDBG вы можете открыть "View" -> "Memory" и ввести начальный адрес кучи (в нашем случае, опять же, 0x2b108018), после чего вы увидите дамп памяти, прокручивая который вверх/вниз вы можете найти ваши данные. Примерно так:

В качестве справки: по умолчанию в Internet Explorer участок хранит ваши данные по адресу 0x20302228, однако вам необходимо около 0x500 итераций для IE 10, чтобы убедиться в этом. Мы также выяснили, что адрес 0x0c0d0228, кажется, также является пригодным местом для хранения данных. В Firefox та же самая информация находится по адресу 0x20302210. Для экспериментов вы можете собрать экспериментальные данные и сравнить их, используя mona.py.

«js_property_spray» также можно использовать для манипуляций с LFH (Low-Fragmentation Heap, слабо фрагментированная куча). Я бы рекомендовал прочесть статью Криса Валасека (Chris Valasek) «Understanding the Low Fragmentation Heap» перед экспериментами.

Перед опробованием новой техники, пожалуйста, обновите репозитарий Metasploit. Если до этого вы не имели дела с Metasploit, вы можете загрузить его по следующему адресу:

http://www.metasploit.com/download/

или введите имя

CAPTCHA