Недавно корпорация Microsoft ввела в своих продуктах новый функционал безопасности под названием «Защита от перезаписи обработчика структурных исключений» (SEHOP).
Авторы:
Stéfan Le Berre s.leberre@sysdream.com
Damien Cauquil d.cauquil@sysdream.com
Недавно корпорация Microsoft ввела в своих продуктах новый функционал безопасности под названием «Защита от перезаписи обработчика структурных исключений» (SEHOP). Данный функционал присутствует в таких операционных систем, как:
SEHOP расширяет обработку структурных исключений и применяет большое количество проверок безопасности структуры обработки исключений (SEH), используемой программами. Основная функция SEHOP заключается в проверке всех SEH структур в обрабатываемом стеке, особенно последней SEH структуры, которая имеет особое значение, так как ее обработчик указывает прямо на функцию файла библиотек. Вот классический пример SEH цепочки:
Каждая SEH структура в цепочке указывает на последующую структуру, а последняя структура, в свою очередь, содержит обработчик, указывающий на ntdll!_except_handler4. При эксплуатации перезаписи SEH структуры стека, последующий SEH указатель получает некий байт-код, а измененный SEH обработчик указывает на последовательность инструкций «POP POP RET», расположенных за пределами SafeSEH модуля.
Используемый в SEHOP алгоритм валидации был описан А.Сотировым (A. Sotirov) на конференции Black Hat в 2008 году. Давайте рассмотрим его:
Также, необходимо помнить о сопутствующих ограничениях:
Так работает классическая схема эксплуатации:
SEH обработчик указывает на последовательность инструкций «POP POP RET», а первый член структуры, вместо действительного адреса стека, содержит код. При обработке исключений Windows передает управление обработчикам исключений, согласно SEH цепочке. Первый обработчик исключений перезаписывается, а процесс исполнения направляется на последовательность инструкций «POP POP RET» (вместо обработки исключения). Данная последовательность передает процесс выполнения первым двум байтам первого члена текущей SEH структуры, являющей собой jump инструкцию (0xEB06). Таким образом, SEH цепочка разрывается:
Два первых байта первого DWORD в SEH структуре никогда не выполняются. Их можно изменить, таким образом, сделав DWORD действительным контролируемым адресом стека. Также, существует возможность изменения остальных двух байт, которые будут указывать на действительный контролируемый адрес стека. Еще их можно определить как jump инструкцию. DWORD можно считать как действительным адресом стека, так и действительной командой, при вызове выполняющей jump.
Если поместить ложную SEH структуру в адрес стека, указанный первым DWORD, то удастся изменить всю SEH цепочку, а также получить контроль над SEH структурой. Сделать ее валидной нам поможет подтверждение первой SEH структуры.
Нужно решить основной вопрос: какую jump инструкцию можно запрограммировать таким образом, чтобы ее байт-код отображал адрес с 4-байтным смещением. Здесь подходит только одна инструкция: JE (закодированная в виде 0x74). Данная команда представляет собой условный jump. Jump выполняется, если установлен флаг Z. При обработке исключений, флаг Z в Windows по умолчанию не выставляется, его необходимо установить путем выполнения инструкций вычисления, например, нулевого значения. Для этого может хорошо подойти оператор “XOR”. Решение нашей задачи становиться ясным: необходимо переключиться на последовательность «XOR, POP, POP, RET» для того, чтобы интерпретировать команду JE в JMP. В этом и заключалась сложная часть техники обхода SEHOP.
Инструкции «XOR, POP, POP, RET» найти несложно, некоторые последовательности можно найти в конце функций, возвращающихся к нулевому результату:
Чтобы быть уверенным в успешной эксплуатации, мы добавим в наш PoC код инструкции «XOR, POP, POP, RET».
Предположим, что по адресу 0x0022FD48 находится первая SEH структура. Можно создать еще одну SEH структуру по адресу 0x0022FD74, содержащую следующий SEH указатель со значением 0xFFFFFFFF и обработчиком, указывающим на ntdll!FinalExceptHandler. Если сделать так, чтобы обработчик первой структуры указывал на последовательность «XOR, POP, POP, RET», то появится возможность перенаправления хода выполнения в необходимом направлении, не разрывая при этом саму цепь. По сути, восстанавливается валидная ложная SEH цепочка, которая перенаправляет ход выполнения в специальный шеллкод.
Основным ограничением является ASLR, присутствующий в Microsoft Windows 7 и Vista. Успех эксплуатации зависит от знания адреса ntdll!FinalExceptHandler. При каждой перезагрузке системы, ImageBase Ntdll в случайном порядке изменяется, что значительно усложняет эксплуатацию. Произведенные с ASLR тесты (без реверсинга) показали, что из 16 битов, представляющих ImageBase, только 9 битов изменяются в случайном порядке. Это означает, что при попытке эксплуатации переполнения буфера, вероятность обхода SEHOP равна 1 к 512.
Для демонстрации работы вышеуказанной техники было создано небольшое приложение. Это приложение копирует содержимое файла «OwnMe.txt» в память и, по ходу операции, разбивает стек, вызывая исключения, перехватываемые обработчиком исключений.
Необходимые действия:
Последовательность «XOR, POP, POP, RET» известна потому, что мы поместили ее в код программы. Данную последовательность можно найти в памяти по адресу 0x004018E1.
При аварийном завершении работы программы, получаем:
После этого, необходимо создать валидную ложную SEH цепь со второй SEH структурой, расположенной по адресу 0x0012F774 и содержащей 0xFFFFFFFF в качестве первого члена структуры (следующий SEH указатель) и FinalExceptionHandler в качестве SEH обработчика. Затем, содержимое SEH структуры, расположенной по адресу 0x0012F700, изменяется и указывает на созданную нами ложную SEH структуру, а обработчик устанавливается в значение 0x004018E1. Во избежание выполнения данных, перед каждой SEH структурой помещается jump инструкция (JMP +8).
При эксплуатации, выполнение должно происходить таким образом:
Шеллкод запустит calc.exe:
Сам по себе функционал SEHOP не является надежной защитой от переполнения буфера в стеке. В этой статье был продемонстрирован способ обхода «Защиты от перезаписи обработчика структурных исключений». В то же время, SEHOP является весьма эффективным в связке с ASLR и DEP.
http://sysdream.com/
http://ghostsinthestack.org/
http://virtualabs.fr/
[1] Preventing the Exploitation of Structured Exception Handler (SEH) Overwrites with SEHOP:
http://blogs.technet.com/srd/archive/2009/02/02/preventing-the-exploitation-of-seh-overwrites-
with-sehop.aspx
[2] SEHOP per-process opt-in support in Windows 7:
http://blogs.technet.com/srd/archive/2009/11/20/sehop-per-process-opt-in-support-in-windows-
7.aspx
[3] Bypassing Browser Memory Protections: http://taossa.com/archive/bh08sotirovdowd.pdf
[4] ZIP containing our target program & exploit http://www.sysdream.com/SEHOP.zip