Entendiendo el PEB

PEBa ulertzen

Jacobo


Hau izango da artikulu sorta baten lehenengoa, non Windows inguruneetan malwarearen munduan murgiltzeko beharrezko oinarrizko teoria ulertzen saiatuko den. 

Zaila da hasiera puntua jartzea zibersegurtasun arlo honetan murgiltzeko. Puntu bat, alderdi konplexuak eta ez ohikoak ulertzeko aukera ematen duena eta aldi berean ulermena eskuragarria dena, 0 mailatik, oinarrizkoa, abiatzea esaten dena, baina ez duena informatikari orok jakin beharreko oinarrizko gauza gehiegi kontatzen. 

Horrela, PEBtik hastea erabaki da, Zer da? Zergatik da garrantzitsua malware garapenean?

Teoria pixka bat:

Interesgarria da ulertzea zer dagoen Windows-en exekutagarri fitxategien atzean, gure guztiontzat ohiko EXE luzapena duen fitxategi bat izan ala DLL edo SYS bezalako (agian ezezagunagoak diren) luzapenak. 

Hasteko, jakin behar da guztiak fitxategi mota bera direla, Windows-ek Portable Executable Format deitzen duena. Fitxategi hauek egituratzea ulertzea hurrengo artikuluen gai izango da. Hala ere, gutxienez jakin behar da fitxategi horietako bat exekutatzen denean, Windows-ek prozesu bat sortzen duela, gutxienez harizko bat duena, fitxategiaren kodea exekutatzeko arduradunak izango direnak.

Sortutako prozesu hau exekutagarriari beharrezko tresna guztiak emateko arduraduna dela esan daiteke, exekutagarri hori behar bezala abiarazteko. 

Adibidez: C kode bat idazten denean, pantailan “Hola mundo” inprimatzeko printf tipiko baten bidez, azpian gauza batzuk gertatzen dira, erabiltzaile arruntak, baita garatzaileak ere, ezagutzen ez ditugunak. 

Printf funtzio bat da, ucrtbase.dll izeneko liburutegi batean definitua eta deklaratua. Hala ere, funtzio hau oso maila altukoa da eta badakigu Windowsek kernel bat duela funtzio hauek ezagutzen ez dituena. Nola lortzen da orduan kernelak irentsi dezakeen informazioa? Windowsen API natiboen edo WinAPIen bidez. 

Laburbilduz, programa bat sortzen dugunean printf batekin eta exekutatzen dugunean, jakin badakigu deialdi sorta bat sortuko dela maila oso altutik, printf bezalakoetatik hasi eta maila oso baxura, adibidez ZwWriteFile bezalakoetara. WinAPI funtzioen deialdiak sakon ulertzea beste artikulu baten gai izango da.

Berriro ere galdera hau da: Nola ematen dio prozesu batek exekutagarriari beharrezko tresnak behar bezala abiarazteko? Erantzuna erraza da, exekutagarriak abiarazteko behar duen informazio guztia kontrolatuz. Hau da, ikusi dugunez, gure programak gutxienez ucrtbase.dll izeneko DLL bat behar du. Nola lortzen du exekutagarriak (eta kargatzen du memorian) DLLaren helbidea printf bezalako funtzioak erabiltzeko? PEB bidez. 

Process Enviroment Block Windowsen datu egitura bat da, prozesuen abiarazteari buruzko informazioa biltzen duena, eta ondorioz exekutagarriak, hala nola bere PID-a, prozesua debug egiten ari den ala ez, eta batez ere, LDR_DATA bezalako beste egituretara puntatzaileak, exekutagarriaren beharrezko DLLen informazioa gordeko dutenak, hala nola haien helbidea.

Egitura hau partzialki dokumentatua dago Windows-ekin. 19 aldagai dituenetik 7 aldagairen inguruko informazio argia besterik ez digute ematen. 

 


Badakigu byte motako aldagai guztiak memorian byte bat hartuko dutela eta PVOID aldagaiak zerbaiten puntatzaileak izango direla, beraz 8 byte hartuko dituztela memorian. Gutxienez haien tamaina jakitea beharrezkoa da memoriaren helbideak eta desplazamenduak ondo kalkulatzeko, kodea depuratzen ari garenean edo gure kodeetan horietara sartzen saiatzen garenean.

Zorionez, gai hauetan ikertzen duen komunitatea dugu eta datu ez ofizialak eskaintzen dizkigute, baina Microsoften dokumentazio beraren baino zehatzagoak. Adibide bat da https://www.vergiliusproject.com/ orria, non Windowsen egitura gehienak kontsulta ditzakegun. Gomendatzen dugu web honetako PEB egitura bisitatzea: https://www.vergiliusproject.com/kernels/x64/windows-11/24h2/_PEB. Zertxobait antzekoa da eta bere aldagaiak benetako ideia bat izateko balio du. 

Windowsen dokumentazio ofiziala kontuan hartuz, PEBren aldagai garrantzitsuenetakoa (une honetan) Ldr izeneko aldagaia da. Aldagai hau berriro Windowsen egitura bat izango da, _PEB_LDR_DATA motakoa, eta PEB bezala, Microsoft-ek partzialki dokumentatua. 

Dokumentazio ofizialaren arabera, hau da bere itxura.

 


Gure helburua PEB ulertzea da, prozesuen kontrol egitura nola den eta nola baimentzen dien exekutagailuei (PE) behar dituzten DLL guztiak erabiltzea, besteak beste. 

PEB_LDR_DATA-k LIST_ENTRY motako aldagaia du, InMemoryOrderModuleList izenekoa, bi adierazlez osatua. Adierazle hauek exekutagailuak behar dituen DLL guztien memoriako helbidea adierazten dute, bai hurrengo DLLarena bai aurrekoarena, DLLak kargatzeko bi bider lotutako zerrenda sortuz. 

 


Adierazle hauek, Microsoft-en dokumentazioaren arabera, Flink eta Blink izenekoak dira. 

Une honetan interesgarria da pentsatzea nola zerrenda bi bider lotu honek exekutagailuari DLL zein kargatu behar duen informazio osoa ematen dion. Pentsatzen badugu, gutxienez DLLaren izena eta diskoan gordeta dagoen bide absolutua jakin beharko dira memorian kargatzeko. 

Bi bider lotutako zerrenda bat dugu, _LIST_ENTRY egituraz osatua, non flink hurrengo _LIST_ENTRY-ren helbidera apuntatzen duen, eta hurrengo flink-a lortuko den, eta horrela jarraituz. Non dago beharrezko DLL bakoitzaren informazioa?

Hau oso erraza da. _LIST_ENTRY bakoitza _LDR_DATA_TABLE_ENTRY izeneko egitura handiago baten parte da. Berriro ere, Windowsen egitura bat da, Microsoft-ek partzialki dokumentatua.

 


Ikusten denez, bigarren lerroan LIST_ENTRY egitura dago (kontuz, ez da egitura horretako adierazlea, baizik eta bi adierazleen 16 byte bertan daude). Era berean, DllBase, EntryPoint edo FullDllName aldagaien balioak ikus daitezke, eta horiek exekutagailuak behar dituen DLL guztiak kargatzeko beharrezko informazio osoa dute. 

Laburbilduz, PEB Windowsen egitura bat da, prozesuaren beharrezko informazio guztia biltzen duena. Horri esker, exekutagailu batek beharrezko DLL guztiak kargatu ditzake, programaren eta kernelaren funtzioak kargatzeko. Ikasi den bezala, hori guztia egitura multzo baten bidez egiten da, informazio guztia ordenean mantentzen dutenak. 

 



Eskua lanera:

PEB eta bere egitura osoa aztertzeko eta behatzeko, Windowsen depuradore ofiziala den WinDBG erabiliko da. Gainera, VisualStudio laguntzaz C hizkuntzan programa txiki bat sortuko da, datu guztiak egiaztatzeko eta ezagutzak indartzeko, eta ulertzeko exekutagailu batetik horietara sar daitekeela. 

Lehenik eta behin, WinDBG erabiliko dugu. Depuradore honek exekutagailu bat diskoetatik abiarazi eta bere prozesua aztertzea ahalbidetzen digu, baita exekutatzen ari den prozesu bati atxikitzea edo itsastea ere.

 


Kasuan honetan, gure programa "Hola mundo" printf-arekin zero-tik abiatuta exekutatuko dugu.

 


Exekutatu ondoren, lehen komandoa !peb erabiliko dugu (WinDBG-k maiuskulak eta minuskulak bereizten ditu). Horrek depuradoreari egitura eta azpiegitura honi buruzko informazio guztia erakutsiko dio.

 


!peb komandoari esker, egitura eta memoriaren helbide guzti hauek ikus daitezke. Lehenik eta behin, lehen gezia PEBren memoriaren helbidera zuzentzen du. Oraindik ez da esan, baina argi dago helbide hau memoria birtualeko helbide bat dela eta PEB bakarra dela prozesu bakoitzeko. 

Prozesu batek harizpi edo thread kopuru bat izan dezake. Hau posible dela eta jakinda harizpi bakoitzak bere TEB (Thread Environment Block) egitura izango duela, prozesu bereko harizpien TEB bakoitzak bere PEB izango al du?

Hurrengo gezia Ldr aldagaiaren helbidea erakusten digu, lehen LIST ENTRY egiturarako zuzendaria izango duena. 

Azkenik, PEBtik kargatutako DLL guztiak lortu direla ikus daiteke, tartean printf arduratzen den ucrtbased.dll.

WinDBG-k memoriaren dump bat egitea eta horien edukia ikustea ahalbidetzen digu, beraz, memoria eta egitura hauek nola gordetzen diren ikusiko dugu. 

Lehenik eta behin, PEB egiturara sartzen hasiko gara (0x00000042393fc000).

 




0x18 desplazamendu baten ondoren, Ldr aldagaiarengana iritsi daiteke, egiturara zuzendaria dena. Helbide honetara eta hurrengoetara jarraituko dugu lehen kargatutako modulura iristeko.

 


Hau da emaitza. Emango dudan pista bakarra da du komandoarekin lehen kargatutako moduluko FullDllName aldagaiaren memoriaren dump-a egin dugula. Gainerako laukitxoak, kolorez bereizita, identifikatzen saiatzea komeni zaizue 😉.



Hurrengo pausoak:

Zergatik beharrezkoa da egitura hau guztia eta nola maneiatu depuradorea malware garatzaile gisa?

Segurtasun neurriak, hala nola EDRak edo Windows Defender bera, egunero eboluzionatzen saiatzen dira, opkode kate errepikatuak bezalako gauzak maila baxuagoetan detektatzeko. Honek gure garapenaren maila baxuko funtzionamendua ahalik eta gehien ulertzea eskatzen du. 

Bereziki, PEBren existentzia ulertzea, zein datu dituen eta nola sar daitekeen ulertzeak bidea zabaltzen digu anti hooking neurriak ezartzeko, anti debugging neurriak ezartzeko edo Reflective Loader Injection bezalako teknika aurreratuagoak egiteko, non exekutagailuaren mendekotasun guztiak eskuz kargatu beharko diren. 

Exe bat sortu da aurretik ikusi diren datu batzuk lortzeko.

 


Irakurlearen esku uzten da, .c fitxategia hartzea eta aldatzea PEB egiturako beste aldagai batzuk lortzeko informazioa saiatuz.







Itzuli blogera

Utzi iruzkin bat

Kontuan izan iruzkinak argitaratu aurretik onartu behar direla.