Je, unafanya kazi katika kampuni ya usalama wa mtandao? Unataka kuona kampuni yako ikionyeshwa kwenye HackTricks? au unataka kupata upatikanaji wa toleo jipya zaidi la PEASS au kupakua HackTricks kwa PDF? Angalia MIPANGO YA KUJIUNGA!
Programu iliyotangulia ina vichwa vya programu 9, kisha, upangaji wa sehemu unaonyesha katika kichwa cha programu gani (kutoka 00 hadi 08) kila sehemu inapatikana.
PHDR - Kichwa cha Programu
Ina meza za vichwa vya programu na metadata yenyewe.
INTERP
Inaonyesha njia ya mzigo wa kutumia kusoma faili ya binary kwenye kumbukumbu.
LOAD
Vichwa hivi hutumiwa kuonyesha jinsi ya kusoma faili ya binary kwenye kumbukumbu.
Kila kichwa cha LOAD huonyesha eneo la kumbukumbu (ukubwa, ruhusa, na usawazishaji) na inaonyesha baits za ELF binary za kunakili hapo.
Kwa mfano, la pili lina ukubwa wa 0x1190, linapaswa kuwa katika 0x1fc48 na ruhusa za kusoma na kuandika na litajazwa na 0x528 kutoka kwa offset 0xfc48 (hailazi nafasi yote iliyohifadhiwa). Kumbukumbu hii italeta sehemu .init_array .fini_array .dynamic .got .data .bss.
DYNAMIC
Kichwa hiki husaidia kuunganisha programu na mahitaji yake ya maktaba na kutumia marekebisho. Angalia sehemu ya .dynamic.
NOTE
Hii hifadhi habari za metadata za muuzaji kuhusu faili ya binary.
GNU_EH_FRAME
Inaainisha eneo la meza za kufungua upya stack, zinazotumiwa na wachunguzi na kazi za kutunza mizunguko ya C++.
GNU_STACK
Ina mazingira ya ulinzi wa kuzuia utekelezaji wa stack. Ikiwa imewezeshwa, faili ya binary haitaweza kutekeleza nambari kutoka kwenye stack.
GNU_RELRO
Inaonyesha usanidi wa RELRO (Relocation Read-Only) wa faili ya binary. Ulinzi huu utaweka sehemu fulani za kumbukumbu kama kusoma tu (kama vile GOT au meza za init na fini) baada ya programu kusomwa na kabla haijaanza kukimbia.
Katika mfano uliotangulia inaiga baits 0x3b8 hadi 0x1fc48 kama kusoma tu ikigusa sehemu .init_array .fini_array .dynamic .got .data .bss.
Tambua kuwa RELRO inaweza kuwa ya sehemu au kamili, toleo la sehemu halilindi sehemu .plt.got, ambayo hutumiwa kwa kufunga uvivu na inahitaji nafasi hii ya kumbukumbu kuwa na ruhusa za kuandika kuandika anwani za maktaba mara ya kwanza wanapopatikana.
TLS
Inaainisha meza ya vipengele vya TLS, ambavyo huhifadhi habari kuhusu pembejeo za mnyororo wa ndani.
Vichwa vya Sehemu
Vichwa vya sehemu hutoa mtazamo wa kina zaidi wa faili ya binary ya ELF.
Jedwali la String: Inaleta pamoja strings zote zinazohitajika na faili ya ELF (lakini sio zile zinazotumiwa na programu). Kwa mfano, inaleta majina ya sehemu kama vile .text au .data. Na kama .text iko kwenye offset 45 katika jedwali la strings itatumia nambari 45 katika uga wa jina.
Ili kupata mahali ambapo jedwali la string liko, ELF ina pointer kwenye jedwali la string.
Jedwali la Alama: Inaleta habari kuhusu alama kama vile jina (offset katika jedwali la strings), anwani, saizi na metadata zaidi kuhusu alama.
Sehemu Kuu
.text: Maelekezo ya programu ya kukimbia.
.data: Variables za kimataifa zenye thamani iliyowekwa wazi katika programu.
.bss: Variables za kimataifa zilizoachwa bila kuanzishwa (au kuanzishwa kwa sifuri). Variables hapa zinaanzishwa moja kwa moja kuwa sifuri hivyo kuzuia sifuri zisizohitajika kuongezwa kwenye binary.
.rodata: Variables za kimataifa zenye thamani zisizobadilika (sehemu isiyoweza kusomwa).
.tdata na .tbss: Kama .data na .bss wakati variables za thread-local zinapotumiwa (__thread_local katika C++ au __thread katika C).
.dynamic: Angalia chini.
Alama
Alama ni mahali lenye jina katika programu ambalo linaweza kuwa function, object la data la kimataifa, variables za thread-local...
readelf -s lnstat
Symbol table '.dynsym' contains 49 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000001088 0 SECTION LOCAL DEFAULT 12 .init
2: 0000000000020000 0 SECTION LOCAL DEFAULT 23 .data
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strtok@GLIBC_2.17 (2)
4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND s[...]@GLIBC_2.17 (2)
5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strlen@GLIBC_2.17 (2)
6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fputs@GLIBC_2.17 (2)
7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND exit@GLIBC_2.17 (2)
8: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _[...]@GLIBC_2.34 (3)
9: 0000000000000000 0 FUNC GLOBAL DEFAULT UND perror@GLIBC_2.17 (2)
10: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
11: 0000000000000000 0 FUNC WEAK DEFAULT UND _[...]@GLIBC_2.17 (2)
12: 0000000000000000 0 FUNC GLOBAL DEFAULT UND putc@GLIBC_2.17 (2)
[...]
Kila kuingia cha alama kina:
Jina
Vipengele vya kufunga (dhaifu, mahali au kuu): Alama ya mahali inaweza kupatikana tu na programu yenyewe wakati alama za kuu zinashirikiwa nje ya programu. Kitu dhaifu ni kwa mfano kazi inayoweza kubadilishwa na moja tofauti.
Aina: NOTYPE (aina haikufafanuliwa), OBJECT (data ya kikoa cha kimataifa), FUNC (kazi), SECTION (sehemu), FILE (faili ya msingi ya nambari kwa wachunguzi wa hitilafu), TLS (kigezo cha mnyororo wa eneo), GNU_IFUNC (kazi isiyo ya moja kwa moja kwa ajili ya uhamishaji)
Directory ya NEEDED inaonyesha kwamba programu inahitaji kupakia maktaba iliyotajwa ili iendelee. Directory ya NEEDED inakamilika mara tu maktaba inapokuwa kamili na tayari kutumika.
Uhamishaji
Mzigo lazima pia uhamishe mahitaji baada ya kuzipakia. Uhamishaji huu unaonyeshwa kwenye meza ya uhamishaji katika muundo wa REL au RELA na idadi ya uhamishaji inatolewa katika sehemu za kudumu RELSZ au RELASZ.
Ikiwa programu imepakia mahali tofauti na anwani inayopendelewa (kawaida 0x400000) kwa sababu anwani tayari inatumika au kwa sababu ya ASLR au sababu nyingine yoyote, urekebishaji wa stati hurekebisha pointa ambazo zilikuwa na thamani zikitarajia binary ipakuliwe katika anwani inayopendelewa.
Kwa mfano, sehemu yoyote ya aina R_AARCH64_RELATIV inapaswa kurekebisha anwani kwenye upendeleo wa urekebishaji pamoja na thamani ya kuongeza.
Urekebishaji wa Kudumu na GOT
Urekebishaji unaweza pia kurejelea alama ya nje (kama kazi kutoka kwa tegemezi). Kama vile kazi ya malloc kutoka libC. Kisha, mzigo unapopakia libC katika anwani ikichunguza wapi kazi ya malloc imepakuliwa, itaandika anwani hii kwenye jedwali la GOT (Global Offset Table) (inayoonyeshwa katika jedwali la urekebishaji) ambapo anwani ya malloc inapaswa kufafanuliwa.
Jedwali la Uunganishaji wa Taratibu
Sehemu ya PLT inaruhusu kufanya uunganishaji wa uvivu, ambao maana yake ni kwamba ufumbuzi wa eneo la kazi utafanywa mara ya kwanza inapofikiwa.
Kwa hivyo wakati programu inaita malloc, kimsingi inaita eneo linalofanana la malloc katika PLT (malloc@plt). Mara ya kwanza inapoitwa, inatatua anwani ya malloc na kuihifadhi ili wakati malloc inaitwa tena, anwani hiyo itatumika badala ya msimbo wa PLT.
Uanzishaji wa Programu
Baada ya programu kupakia, ni wakati wake wa kufanya kazi. Walakini, msimbo wa kwanza unaorushwa si mara zote ni main. Hii ni kwa sababu kwa mfano katika C++ ikiwa kigezo cha kawaida ni kitu cha darasa, kipengee hiki lazima kianzishwe kabla ya main kuanza, kama vile:
Tafadhali elewa kwamba hizi variables za kimataifa zinapatikana katika .data au .bss lakini katika orodha __CTOR_LIST__ na __DTOR_LIST__ vitu vya kuanzisha na kuharibu vimehifadhiwa kwa mpangilio ili kufuatilia.
Kutoka kwa msimbo wa C ni rahisi kupata matokeo sawa kwa kutumia vifaa vya GNU:
__attributte__((constructor)) //Add a constructor to execute before__attributte__((destructor)) //Add to the destructor list
Kutoka kwa mtazamo wa compiler, ili kutekeleza hatua hizi kabla na baada ya kazi ya main kutekelezwa, ni rahisi kuunda kazi ya init na kazi ya fini ambazo zitatajwa katika sehemu ya dynamic kama INIT na FIN na kuwekwa katika sehemu za init na fini za ELF.
Chaguo lingine, kama ilivyotajwa, ni kutaja orodha __CTOR_LIST__ na __DTOR_LIST__ katika viingilio vya INIT_ARRAY na FINI_ARRAY katika sehemu ya dynamic na urefu wa hizi unatajwa na INIT_ARRAYSZ na FINI_ARRAYSZ. Kila kuingilio ni kidude cha kazi ambacho kitaitwa bila hoja.
Zaidi ya hayo, ni rahisi pia kuwa na PREINIT_ARRAY na pointers ambazo zitatekelezwa kabla ya kidude cha INIT_ARRAY.
Mpangilio wa Uanzishaji
Programu inapakiwa kumbukani, vitu vya kimataifa vya tuli vinainishwa katika .data na vile visivyoainishwa vinawekwa sifuri katika .bss.
Mahitaji yote kwa programu au maktaba zina anzishwa na kiunganishaji wa kudumu unatekelezwa.
Kazi za PREINIT_ARRAY zinatekelezwa.
Kazi za INIT_ARRAY zinatekelezwa.
Ikiwa kuna kuingilio la INIT linaitwa.
Ikiwa ni maktaba, dlopen inamalizika hapa, ikiwa ni programu, ni wakati wa kuita kituo cha kuingia halisi (kazi ya main).
Uhifadhi wa Wateja-Kwa-Wateja (TLS)
Hizi hutajwa kwa kutumia neno __thread_local katika C++ au kifupisho cha GNU __thread.
Kila wateja atahifadhi eneo la kipekee kwa kivinjari hiki hivyo ni wateja pekee wanaweza kupata kivinjari chao.
Inapotumiwa, sehemu .tdata na .tbss hutumiwa katika ELF. Ambazo ni kama .data (inaanzishwa) na .bss (haikoanzishwa) lakini kwa TLS.
Kila kivinjari kitakuwa na kuingilio katika kichwa cha TLS kinachotaja ukubwa na kivinjari cha TLS, ambacho ni kivinjari kitatumia katika eneo la data la kipekee la kivinjari.
__TLS_MODULE_BASE ni ishara inayotumiwa kutaja anwani ya msingi ya uhifadhi wa wateja-kwa-wateja na inaelekeza kwenye eneo kumbukumbu linaloleta data yote ya wateja-kwa-wateja ya moduli.