Шприц для bsd или функции на игле

         

Введение


Классический алгоритм внедрения shell-кода выглядит так: сохраняем несколько байт перехватываемой функции и ставим jump на свой thunk, который делает что задумано, выполняет сохраненные байты и передает управление оригинальной функции, которая может вызываться как по jump, так и по call (подробнее этот вопрос рассмотрен в статье "crackme, прячущий код на API-функциях", опубликованной в Хакере).

Самое сложное — выбрать место для размещения thunk'а. Это должна быть память доступная всем процессам, а такой памяти в нашем распоряжении нет! Мы знаем, что "подопытная" библиотека отображается на адресное пространство каждого процесса, но это пространство уже занято! Наскрести пару десятков байт, отведенных под выравнивание, вполне реально, только нам этого не хватает! Приходится хитрить.

Прежде всего мы можем разместить код перехватчика в какой-нибудь "ненужной" функции, например, gets, а в начало всех перехватываемых функций внедрить… нет, не jump (в этом случае перехватчик не сможет определить откуда пришел вызов), а call gets! Внутри gets, перехватчик выталкивает из стека адрес возврата, уменьшает его на длину команды call (в 32-разрядном режиме — 5 байт) и получает искомый указатель на функцию.

Рисунок 1 установка hook'а на функцию write, в начало которой внедрена команда перехода на gets (E8h 4Bh 73h F9h FFh), пусть вас не смущает тот факт, что HT-редактор показывает gets под именем _IO_gets, функция gets имеет несколько синонимов и это — один из них

Зная указатель, можно определить имя функции — в этом нам поможет функция dladdr из GNU Extensions. В POSIX она не входит, но поддерживается практически всеми UNIX'ами, так что на этот счет можно не волноваться. (Примечание: напоминаем, что при внедрении в gets, равно как и любую другую функцию, мы можем пересекать границы страниц, поскольку за концом текущей страницы наверняка находится совсем посторонняя область памяти! если же возникает необходимость модифицировать функцию gets целиком, необходимо найти все принадлежащие ей страницы, тем же самым методом, которым мы нашли первую из них).




Содержание  Назад  Вперед