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

Умри, но сейчас

КРИС КАСПЕРСКИ АКА МЫЩЪХ

Спецвыпуск: Хакер, номер #070, стр. 070-076-4


ЛИСТИНГ

код, удаляющий текущий процесс

module = GetModuleHandle(0);

GetModuleFileName(module, buf, MAX_PATH);

if(0x80000000 & GetVersion())

{

// для Win9x

fnFreeOrUnmap = FreeLibrary;

}

else

{

// для WinNT

fnFreeOrUnmap = UnmapViewOfFile;

CloseHandle((HANDLE)4);

}

__asm

{

lea eax, buf

push 0

push 0

push eax

push ExitProcess

push module

push DeleteFile

push fnFreeOrUnmap

ret

}

Проще раскрутить головоломку с конца. Очевидно, что ret передает управление по адресу, который был занесен в стек перед ним, то есть вызывает функцию fnFreeOrUnmap, которой, в зависимости от версии Windows, оказывается либо FreeLibrary, либо UnmapViewOfFile. Получив управление, функция смотрит на стек и думает: ага, «DeleteFile» — это адрес возврата, а вот «module» — это мой аргумент. Освободив страничный образ, она передает управление по адресу возврата (на месте которого лежит адрес DeleteFile) и увеличивает значение указателя стека на 4 (размер переданных ей аргументов).

Получив управление, DeleteFile смотрит на стек и думает: ага, «ExitProcess» – это адрес возврата, а вот «push eax» — мой аргумент с именем файла, который нужно удалить! И ведь удаляет, поскольку модуль к этому времени уже освобожден.

Следующей (и последней) управление получает функция ExitProcess, завершающая выполнение программы, которой уже нет.

Элегантно! Никаких тебе временных bat-файлов и прочей дисковой активности (которую, кстати, могут заметить всякие недружелюбно настроенные мониторы). Но разве кто-нибудь гарантировал (документация или лично Билл Гейтс), что UnmapViewOfFile позволяет освобождать образ exe-файла? На NT и W2K это работало лишь потому, что ядро хранило ссылку на обработчик объекта-секции (не путать с секциями PE-файла) и UnmapViewOfFile послушно его освобождало. Начиная с XP, ядро обращается к обработчику секции через указатель, обламывая вызов UnmapViewOfFile, а вместе с ним весь кайф.

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

[6 незаконнорожденные потоки]

Чтобы не порождать отдельный процесс, некоторая малварь внедряется в один из уже существующих, порождая в нем свой поток, причем делает это настолько неумело, что сразу же обращает на себя внимание и легко обнаруживается утилитой «Process Explorer» Марка Руссиновича или любым отладчиком (OlyDbg, soft-ice). А все потому, что память, в которой малварь размещает свой код, в 99% случаях выделяется через VirtualAlloc/VirtualAllocEx, то есть берется из динамической памяти, в то время как нормальные потоки вращаются в пределах образов исполняемых файлов или DLL.

Назад на стр. 070-076-3  Содержание  Вперед на стр. 070-076-5