BOWall
Препятствие исполнения функций динамических библиотек из областей
данных и стека
Данный метод имеет прямое отношение ко второму классу защиты и противодействует
всему спектру атак с внедрением кода. Сущность метода заключается в принципе
функционирования Windows NT. Любая программа выполняется в непривилегированном
3-м кольце защиты процессора. Сама же операционная система и драйвера работает
в 0-кольце. Поэтому для выполнения любых операций взаимодействия с внешними
устройствами и с привилегированными областями памяти, т.е. практически любой
не вычислительной операции приложение должно использовать сервисные функции
операционной системы, что отражено на следующем рисунке.

Вызов системных сервисов
Как видно из рисунка, приложения и подсистемы функционируют непривилегированном
режиме пользователя, а ядро ОС и его сервисы в режиме ядра. Подсистема Win32
образована динамической библиотекой KERNEL32.DLL, которая использует интерфейс
ОС, предоставляемый NTDLL.DLL. Последняя в свою очередь обращается к сервисам
ОС при помощи прерывания 2E. Приложение также обращаться непосредственно к NTDLL.DLL
и вызывать прерывание 2E. Обработчик прерывания, работающий в режиме ядра, определяет
точку входа требуемого сервиса по таблице распределения системных сервисов и
передает ему управление. Код требуемого сервиса передается обработчику в регистре
EAX. В Windows NT 3.5 - 4.0 нет возможности дополнять таблицу системных сервисов,
тем самым расширяя функциональность ядра ОС. Однако, подобная возможность появилась
в Windows 2000.
В связи с этим суть данного метода защиты заключается в том, что код внедренный
атакующим в буфер, как и любая другая программа, вынужден для выполнения каких
либо действий использовать вызовы функций динамических библиотек. Таким образом,
можно реализовать защиту, если каждую экспортируемую функцию динамической библиотеки
дополнить кодом проверки адреса вызова. Адрес вызова соответствует адресу возврата
из вызываемой внешней функции. Поэтому расположение адреса возврата области
памяти данных или стека является признаком атаки.
Дополнение кода проверки осуществляется посредством модификации исполняемого
файла динамической библиотеки. Причем, модификация осуществляется крайне просто
по сравнению с предыдущим методом и с полной гарантией работоспособности модифицируемой
библиотеки. Последнее достигается за счет того, что изменяется таблица экспортируемых
функций DLL, а не затрагивается исходный код.
Сложность представляет лишь внедрение в исполняемый файл динамической библиотеки
кода проверки. Профессионально выполненный внедренный код эксплоита не зависит от
версий DLL и работает через таблицу импорта атакуемой программы либо получает адреса
функций посредством вызовов LoadLibrary, GetProcAddress.
Благодаря такому исполнению код эксплоита работает на любой конфигурации операционной
системы. Именно таким атакам и противодействует данная защита. В случае, если
атакующий использует в своем эксплоите жестко заданные адреса нужных ему функций,
данная защита в этом виде бессильна. Однако, и злоумышленнику не удастся разработать
гарантированно работающий код. Здесь в качестве дополнительной меры защиты следует
переметить функции DLL по другому базовому адресу. Но и тут, как описано выше,
атакующий может найти образ нужной ему DLL в памяти и вычислить адреса требуемых
функций. Тем не менее даже эксплоит все же останется привязанным к конкретной
версии динамической библиотеки.
Итак, несмотря на простоту реализации, этот метод все же не обеспечивает полной
защиты, но значительно осложняет жизнь атакующему, имеющему мало информации
об атакуемой системе.
|