Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #58, СЕНТЯБРЬ 2005 г.

Stealth patching своими руками

Крис Касперски

Спецвыпуск: Хакер, номер #058, стр. 058-050-3


Это можно сделать создав удаленный поток, за что отвечает функция CreateRemoteThread (в 9x она не работает, но 9x - уже почти труп), или воспользоваться связкой VirtualAllocEx/WriteProcessMemory. Обе технологии давно отработаны и описаны в сотнях хакерских мануалов. Большинство троянов именно так и работает. А вот это уже нехорошо. Теряется фактор новизны, неожиданности и внезапности. Разработчики антивирусов активно работают над созданием оружия, срубающего внедряющийся код еще на излете. К тому же вторжение в чужое адресное пространство может быть расценено как модификация приложения в памяти. Юристам ведь не объяснишь, что авторские права распространяются лишь на образ приложения на диске/памяти, но отнюдь не на адресное пространство целиком!

В принципе, можно разместить отладочный обработчик в области памяти, принадлежащей операционной системе, например KERNEL32.DLL. Microsoft довольно лояльно относится к таким проделкам, и ее практикуют довольно многие коммерческие программы, но здесь есть одно "но". Все, что находится ниже адреса 80000000h, состоит в прямом ведении прикладного процесса и на каждый из них проецируется индивидуально. То есть если мы изменим пару байт в "своей" проекции KERNEL32.DLL, все остальные процессы не узнают об этом! А это значит, что внедрение отладочного обработчика должно осуществляться из контекста атакуемого процесса, следовательно, мы должны внедриться и модифицировать его! Замкнутый круг? Не совсем. Можно, к примеру, модифицировать KERNEL32.DLL на диске. Технически это возможно (хотя и непросто), но... нас сразу же обнаружат! Первой возмутится SFC (а это значит, что ее придется отключать), за ней потянутся антивирусные сторожи, ревизоры, мониторы и прочие силовые структуры. Нет, этот метод не подходит.

А почему бы не загрузить свой драйвер и не разместить отладочный обработчик внутри него? Верхняя половина адресного пространства (от 80000000h и выше) проецируется на все процессы. Сюда загружается NTOSKRNL.EXE и драйверы, следовательно, наш драйвер будет "виден" из любого процесса. Более элегантного и, самое главное, законного способа внедрения, пожалуй, и не придумаешь. От победы и финала нас отделяет только одна маленькая проблема, а именно то, что верхняя половина адресного пространства недоступна прикладным процессам. Попытка передачи управления тут же возбуждает исключение, неизбежное, как восход солнца. Это и демонстрирует следующая программа. Она сканирует адресное пространство и выводит адреса всех страниц, к которым есть доступ на исполнение. Ни одной страницы выше 80000000h здесь не обнаруживается.

(Поиск страниц, пригодных для исполнения)

#include <windows.h>

#include <stdio.h>

main()

{

unsigned int p = 0x00001000; // начальный адрес

while(p) // мотаем цикл по всему мясокомбинату

{

// выводим адреса всех страниц, к которым есть доступ на исполнение

if (!IsBadCodePtr(p)) printf("%08Xh ",p);

// перемещаемся на следующую страницу

p+=0x1000;

}

Назад на стр. 058-050-2  Содержание  Вперед на стр. 058-050-4