Learn & practice AWS Hacking:<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">\
Learn & practice GCP Hacking: <imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">](https://training.hacktricks.xyz/courses/grte)
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
Ili kuona kwamba wito za mfumo zinafanywa kwa usahihi, inapaswa kukusanywa programu ya hapo awali na wito za mfumo zinapaswa kuonekana katika **strace ./PROGRAMA\_COMPILADO**
Wakati wa kuunda shellcodes, kuna ujanja unaoweza kufanywa. Amri ya kwanza ni jump kwa call. Call inaita msimbo wa asili na pia inaweka EIP kwenye stack. Baada ya amri ya call, tumeweka string ambayo tunahitaji, hivyo kwa EIP hiyo tunaweza kuelekeza kwenye string na pia kuendelea kutekeleza msimbo.
Inajumuisha msimbo mdogo unaovinjari kurasa za kumbukumbu zinazohusiana na mchakato kutafuta shellcode iliyohifadhiwa (inatafuta saini yoyote iliyowekwa kwenye shellcode). Inafaida katika hali ambapo kuna nafasi ndogo tu ya kuingiza msimbo.
Inajumuisha shells zilizofichwa ambazo zina msimbo mdogo unaozifichua na kuruka kwake, ukitumia hila ya Call-Pop hii itakuwa **mfano wa kufichwa cesar**:
Kwa kuangalia jinsi stack ya mchakato mpya inavyoundwa katika linux, inaweza kuendelezwa exploit kwa njia ambayo programu itazinduliwa katika mazingira ambayo variable pekee ni shellcode. Anwani hii inaweza kisha kuhesabiwa kama: addr = 0xbfffffff - 4 - strlen(NOMBRE\_ejecutable\_completo) - strlen(shellcode)
The **sprintf moves** a formatted string **to** a **variable.** Therefore, you could abuse the **formatting** of a string to cause a **buffer overflow in the variable** where the content is copied to.\
For example, the payload `%.44xAAAA` will **write 44B+"AAAA" in the variable**, which may cause a buffer overflow.
**`atexit()`** ni kazi ambayo **kazi nyingine zinapewa kama vigezo.** Hizi **kazi** zita **tekelezwa** wakati wa kutekeleza **`exit()`** au **kurudi** kwa **main**.\
Ikiwa unaweza **kubadilisha****anwani** ya yoyote ya hizi **kazi** ili kuelekeza kwa shellcode kwa mfano, utapata **udhibiti** wa **mchakato**, lakini hii kwa sasa ni ngumu zaidi.\
Kwa sasa, **anwani za kazi** zitakazotekelezwa zime **fichwa** nyuma ya muundo kadhaa na hatimaye anwani ambayo inaelekeza si anwani za kazi, bali zime **sifishwa kwa XOR** na displacement na **funguo za nasibu**. Hivyo kwa sasa, vector hii ya shambulio si **ya manufaa sana angalau kwenye x86** na **x64\_86**.\
Kazi ya **sifisho** ni **`PTR_MANGLE`**. **Mifumo mingine** kama m68k, mips32, mips64, aarch64, arm, hppa... **hazitekelezi kazi ya sifisho** kwa sababu inarudisha **kile kile** ilichopokea kama ingizo. Hivyo mifumo hii ingekuwa na uwezo wa kushambuliwa kupitia vector hii.
Register zilizohifadhiwa ni: `EBX, ESI, EDI, ESP, EIP, EBP`\
Kinachotokea ni kwamba EIP na ESP vinapita kupitia kazi ya **`PTR_MANGLE`**, hivyo **mifumo iliyo hatarini kwa shambulio hili ni ile ile ya hapo juu**.\
Zinatumika kwa urejeleaji wa makosa au kukatizwa.\
Hata hivyo, kutokana na kile nilichosoma, register nyingine hazijalindwa, **hivyo ikiwa kuna `call ebx`, `call esi` au `call edi`** ndani ya kazi inayoitwa, udhibiti unaweza kuchukuliwa. Au unaweza pia kubadilisha EBP ili kubadilisha ESP.
Kila kitu cha **darasa** kina **VPtr** ambayo ni **pointer** kwa array ya darasa lake. VPtr ni sehemu ya kichwa cha kila kitu, hivyo ikiwa **kuandika upya** VPtr kunafanikiwa inaweza **kubadilishwa** ili **ielekeze** kwa njia ya dummy ili kutekeleza kazi kutakuwa na shellcode.
Inakabili simu za baadhi ya kazi zisizo salama kwa nyingine salama. Haijapangwa. (ni kwa x86 tu, si kwa makusanyo yenye -fomit-frame-pointer, si makusanyo ya kudumu, si kazi zote hatarishi zinakuwa salama na LD\_PRELOAD haifanyi kazi kwenye binaries zenye suid).
Inajumuisha kupakia maktaba za pamoja kutoka 0x00000000 hadi 0x00ffffff ili kila wakati kuwe na byte 0x00. Hata hivyo, hii kwa kweli haizuizi mashambulizi yoyote, na hasa katika little endian.
Inajumuisha kufanya ROP kwa njia ambayo inaita kazi strcpy@plt (kutoka plt) na kuelekeza kwenye ingizo la GOT na kunakili byte ya kwanza ya kazi ambayo inataka kuitwa (system()). Kisha inafanywa vivyo hivyo ikielekeza kwenye GOT+1 na kunakili byte ya 2 ya system()… Mwishowe inaita anwani iliyohifadhiwa katika GOT ambayo itakuwa system()
Katika “size” kuna bits za kuonyesha: Ikiwa kipande cha awali kinatumika, ikiwa kipande kimepewa kupitia mmap() na ikiwa kipande kinahusiana na arena ya msingi.
Ikiwa wakati wa kuachilia kipande chochote kati ya vile vilivyo karibu kinapatikana bure, vinajumuika kupitia macro unlink() na kipande kipya kikubwa zaidi kinapelekwa frontlink() ili kiingize bin inayofaa.
BK->fd = FD -> \*(\&shellcode + 8) = (&\_\_dtor\_end\_\_ - 12) —> Hii inasababisha kuandika bytes 4 kuanzia byte ya 8 ya shellcode, hivyo amri ya kwanza ya shellcode inapaswa kuwa jmp ili kuondoa hii na kuanguka kwenye nops ambazo zinaelekea kwenye sehemu nyingine ya shellcode.
Baada ya shell code tunatia kujaza hadi kufikia uwanja prev\_size na size ya kipande kinachofuata. Katika maeneo haya tunatia 0xfffffff0 (ili kuandika upya prev\_size ili iwe na bit inayosema kuwa iko bure) na “-4“(0xfffffffc) katika size (ili wakati itakapokagua katika kipande cha 3 ikiwa kipande cha 2 kilikuwa bure kwa kweli kiende kwenye prev\_size iliyobadilishwa ambayo itamwambia kuwa kiko bure) -> Hivyo wakati free() itakapochunguza itakwenda kwenye size ya 3 lakini kwa kweli itakwenda kwenye 2 - 4 na kufikiri kuwa kipande cha 2 kiko bure. Na kisha itaita **unlink()**.
Wakati wa kuita unlink() itatumia kama P->fd data za kwanza za kipande cha 2 hivyo hapo kutakuwa na anwani unayotaka kuandika - 12 (kwa sababu katika FD->bk itazidisha 12 kwa anwani iliyohifadhiwa katika FD). Na katika anwani hiyo itatia anwani ya pili ambayo itakutana katika kipande cha 2, ambayo tunataka iwe anwani ya shellcode (P->bk bandia).
**fake\_size = pack("\<I”, 0xfffffffc) #-4, para que piense que el “size” del 3º trozo está 4bytes detrás (apunta a prev\_size) pues es ahí donde mira si el 2º trozo está libre**
**got\_free = pack("\<I", 0x08048300 - 12) #Dirección de free() en la plt-12 (será la dirección que se sobrescrita para que se lanza la shellcode la 2º vez que se llame a free)**
**payload += prev\_size + fake\_size + got\_free + addr\_sc #Se modifica el 2º trozo, el got\_free apunta a donde vamos a guardar la direccion addr\_sc + 12**
Hivyo, programu itafikiri kuwa “a” iko bure na katika bin, hivyo itaita unlink() ili kuondoa. Hata hivyo, kama kichwa cha PREV\_SIZE kina thamani -4. Itafikiri kuwa kipande cha “a” kwa kweli kinaanza katika b+4. Yaani, itafanya unlink() kwa kipande kinachoanza katika b+4, hivyo katika b+12 kutakuwa na pointer “fd” na katika b+16 kutakuwa na pointer “bk”.
Inaitwa frontlink wakati kitu kinacholewa na hakuna kipande chake kilichokaribu ambacho hakiko bure, hakuitwi unlink() bali inaitwa moja kwa moja frontlink().
Kwa njia hii, kwa kuandika upya katika mallocs mbili kwa njia isiyo ya kudhibitiwa na katika moja kwa njia ya kudhibitiwa lakini ambayo inachiliwa tu hiyo moja, tunaweza kufanya exploit.
Katika kesi ya kutaka kutumia moja, itapewa bila shida. Katika kesi ya kutaka kutumia nyingine, itapewa nafasi ile ile hivyo tutakuwa na pointers “fd” na “bk” zilizopotoshwa na data ambazo zitaandikwa na uhifadhi wa awali.
Ni muhimu kuwa na simu moja ya free() ili kusababisha utekelezaji wa msimbo wa kawaida. Inahitajika kutafuta kipande cha pili ambacho kinaweza kuzidiwa na kipande cha awali na kuachiliwa.
Katika \[1] inakagua uwanja wa size bit NON\_MAIN\_ARENA, ambayo inaweza kubadilishwa ili kuifanya ukaguzi urudishe kweli na kutekeleze heap\_for\_ptr() ambayo inafanya and kwa “mem” ikiacha 0 bytes 2.5 zisizo muhimu (katika kesi yetu kutoka 0x0804a000 inabaki 0x08000000) na inafikia 0x08000000->ar\_ptr (kama vile ni struct heap\_info)
Kwa njia hii ikiwa tunaweza kudhibiti kipande kwa mfano katika 0x0804a000 na kuna kipande kitakachochiliwa katika **0x081002a0** tunaweza kufikia anwani 0x08100000 na kuandika chochote tunachotaka, kwa mfano **0x0804a000**. Wakati kipande hiki cha pili kitakapochiliwa kitakuta kuwa heap\_for\_ptr(ptr)->ar\_ptr inarudisha kile tulichoandika katika 0x08100000 (kwa sababu inatumika kwa 0x081002a0 and ambayo tuliona hapo awali na kutoka hapo inachukuliwa thamani ya bytes 4 za kwanza, ar\_ptr)
Hivyo ikiwa katika av->bins\[2] tunatia thamani ya \_\_DTOR\_END\_\_-12 katika amri ya mwisho itandikwa katika \_\_DTOR\_END\_\_ anwani ya kipande cha pili.
Yaani, katika kipande cha kwanza tunapaswa kuweka mara nyingi anwani ya \_\_DTOR\_END\_\_-12 kwa sababu hapo ndipo itachukuliwa na av->bins\[2]
Katika anwani ambayo itakuwa anwani ya kipande cha pili na sifuri tano za mwisho tunapaswa kuandika anwani ya kipande hiki cha kwanza ili heap\_for\_ptr() ifikirie kuwa ar\_ptr iko mwanzo wa kipande cha kwanza na kuchukua kutoka hapo av->bins\[2]
Kwa njia hii itaitwa \_int\_free(TROZO1, TROZO2) na itafuata maagizo ya kuandika katika \_\_DTOR\_END\_\_ anwani ya prev\_size ya TROZO2 ambayo itaruka kwenye shellcode.
Mbinu hii haiwezi kutumika tena kwani ilifanywa karibu na patch ile ile kama kwa unlink. Inalinganishwa ikiwa eneo jipya ambalo linaelekezwa pia linaelekeza kwake.
Kwa njia hii ikiwa tunatia katika “fb” inatoa anwani ya kazi katika GOT, katika anwani hii itatia anwani ya kipande kilichosababisha. Ili kufanya hivyo itahitajika kuwa arena iko karibu na anwani za dtors. Kwa usahihi av->max\_fast iwe katika anwani ambayo tutakuwa tukisababisha.
Hivyo ikiwa katika uwanja wa size tunatia ukubwa wa 8 + NON\_MAIN\_ARENA + PREV\_INUSE —> fastbin\_index() itatreturn fastbins\[-1], ambayo itakuwa inaelekeza kwa av->max\_fast
Zaidi ya hayo, inapaswa kutimizwa kwamba kipande kilichokaribu na kilichochiliwa kinapaswa kuwa kikubwa zaidi ya 8 -> Kwa kuwa tumesema kwamba size ya kipande kilichochiliwa ni 8, katika kipande hiki bandia tunapaswa tu kuweka size kubwa zaidi ya 8 (kama vile shellcode itakuwa katika kipande kilichochiliwa, itabidi kuweka mwanzo jump ambayo itanguka kwenye nops).
Kwa sababu ya sifuri za \_DTOR\_END\_ na anwani chache katika GOT, hakuna anwani katika sehemu hizi zinazofaa kuandikwa, hivyo tuone jinsi ya kutumia fastbin kushambulia stack.
Zaidi ya hayo, katika **av->system\_mem** (1484bytes juu ya nafasi kwenye stack) kutakuwa na takataka nyingi ambazo zitaturuhusu kupita ukaguzi unaofanywa.
Zaidi ya hayo, inapaswa kutimizwa kwamba kipande kilichokaribu na kilichochiliwa kinapaswa kuwa kikubwa zaidi ya 8 -> Kwa kuwa tumesema kwamba size ya kipande kilichochiliwa ni 16, katika kipande hiki bandia tunapaswa tu kuweka size kubwa zaidi ya 8 (kama vile shellcode itakuwa katika kipande kilichochiliwa, itabidi kuweka mwanzo jump ambayo itanguka kwenye nops ambazo ziko baada ya uwanja wa size wa kipande bandia jipya).
Katika kesi hii tunatafuta kuwa na pointer kwa malloc ambayo inaweza kubadilishwa na mshambuliaji (kwa mfano, kwamba pointer iko kwenye stack chini ya overflow inayoweza kutokea kwa variable).
Hivyo, tunaweza kufanya pointer hii kuelekeza popote. Hata hivyo, si kila mahali ni sahihi, ukubwa wa kipande bandia unapaswa kuwa mdogo kuliko av->max\_fast na kwa usahihi sawa na ukubwa unaohitajika katika simu ya baadaye kwa malloc()+8. Kwa hivyo, ikiwa tunajua kwamba baada ya pointer hii hatari inaitwa malloc(40), ukubwa wa kipande bandia unapaswa kuwa sawa na 48.
Ikiwa kwa mfano programu ingeuliza mtumiaji nambari, tunaweza kuingiza 48 na kuelekeza pointer ya malloc inayoweza kubadilishwa kwa bytes nne zinazofuata (ambazo zinaweza kuwa za EBP kwa bahati, hivyo 48 inabaki nyuma, kana kwamba ni kichwa cha size). Zaidi ya hayo, anwani ptr-4+48 inapaswa kutimiza masharti kadhaa (ikiwa katika kesi hii ptr=EBP), yaani, 8 <ptr-4+48<av->system\_mem.
Ikiwa hii itatimiza, wakati simu inayofuata ambayo tulisema ilikuwa malloc(40) itapewa kama anwani anwani ya EBP. Ikiwa mshambuliaji pia anaweza kudhibiti kile kinachoandikwa katika malloc hii anaweza kuandika upya EBP na EIP kwa anwani anayotaka.
Hii nadhani ni kwa sababu wakati itakapochiliwa free() itakumbuka kwamba katika anwani ambayo inaelekeza kwa EBP ya stack kuna kipande cha ukubwa mzuri kwa malloc() mpya ambayo inataka kuhifadhiwa, hivyo inatoa anwani hiyo.
Kitu cha kwanza kinachofanywa ni kuandika upya size ya kipande wilderness kwa thamani kubwa sana (0xffffffff), hivyo ombi lolote la kumbukumbu kubwa ya kutosha litashughulikiwa katika \_int\_malloc() bila haja ya kupanua heap
Kitu cha pili ni kubadilisha av->top ili ielekeze kwenye eneo la kumbukumbu chini ya udhibiti wa mshambuliaji, kama vile stack. Katika av->top itatia \&EIP - 8.
Victim inachukua thamani ya anwani ya kipande cha sasa cha wilderness (av->top ya sasa) na remainder ni jumla ya anwani hiyo na idadi ya bytes zinazohitajika na malloc(). Hivyo ikiwa \&EIP-8 iko katika 0xbffff224 na av->top ina 0x080c2788, basi kiasi tunachohitaji kuhifadhi katika malloc inayoweza kudhibitiwa ili av->top iwe inaelekeza kwenye $EIP-8 kwa malloc inayofuata itakuwa:
Ni muhimu kujua kwamba size ya kipande kipya cha wilderness ni kubwa zaidi kuliko ombi lililofanywa na malloc ya mwisho. Yaani, ikiwa wilderness inaelekeza kwa \&EIP-8, size itakuwa tu katika uwanja wa EBP wa stack.
Vipande vilivyokuwa vimeachiliwa vinatolewa kwenye bin kulingana na ukubwa wao. Lakini kabla ya kuingizwa huwekwa katika unsorted bins. Kipande kinapokuwa kimeachiliwa hakijatiwa mara moja kwenye bin yake bali kinabaki katika unsorted bins. Kisha, ikiwa kipande kipya kinahifadhiwa na kipande cha awali kilichokuwa kimeachiliwa kinaweza kutumika, kinarejeshwa, lakini ikiwa kinahifadhiwa kikubwa zaidi, kipande kilichokuwa kimeachiliwa katika unsorted bins kinatiwa kwenye bin yake inayofaa.
bin->bk = bck; Kipande cha pili cha mwisho kinakuwa cha mwisho, ikiwa bck inaelekeza kwenye stack kipande kinachofuata kinachohifadhiwa kitapewa anwani hii
bck->fd = bin; Inafunga orodha ikifanya hii kuelekeza kwa bin
Inahitaji:
Kuhifadhi malloc mbili, kwa njia ambayo kipande cha kwanza kinaweza kuzidiwa baada ya kipande cha pili kuachiliwa na kuingizwa kwenye bin yake (yaani, kuhifadhi malloc kubwa zaidi kuliko kipande cha pili kabla ya kufanya overflow)
Lengo ni lifuatalo, ikiwa tunaweza kufanya overflow kwenye heap ambayo chini yake kuna kipande kilichokuwa kimeachiliwa na katika bin yake, tunaweza kubadilisha pointer yake bk. Ikiwa tunabadilisha pointer yake bk na kipande hiki kinakuwa cha kwanza kwenye orodha ya bin na kinahifadhiwa, bin itadanganywa na kuambiwa kwamba kipande cha mwisho kwenye orodha (kilichofuata kutoa) kiko kwenye anwani bandia ambayo tumepatia (kwa stack au GOT kwa mfano). Hivyo ikiwa kutakuwa na kuhifadhiwa kipande kingine na mshambuliaji ana ruhusa kwake, atapewa kipande katika nafasi inayotakiwa na anaweza kuandika ndani yake.
Baada ya kuachiliwa kipande kilichobadilishwa ni muhimu kuhifadhi kipande kikubwa zaidi kuliko kilichokuwa kimeachiliwa, hivyo kipande kilichobadilishwa kitatoka kwenye unsorted bins na kuingizwa kwenye bin yake.
Hivyo bin itasubiri zamu ili kuitwa malloc() mara nyingi za kutosha ili iweze kutumika tena bin iliyobadilishwa na kudanganya bin ikifanya ionekane kwamba kipande kinachofuata kiko kwenye anwani bandia. Kisha itatoa kipande ambacho kinavutia kwetu.
Ili kutekeleza udhaifu haraka iwezekanavyo, bora ingekuwa: Hifadhi kipande hatari, hifadhi kipande ambacho kitabadilishwa, achilia kipande hiki, hifadhi kipande kikubwa zaidi ambacho kitabadilishwa, badilisha kipande hicho (udhaifu), hifadhi kipande cha ukubwa sawa na kilichohatarishwa na hifadhi kipande cha pili cha ukubwa sawa na hiki kitakuwa kile kitakachoelekeza kwenye anwani iliyochaguliwa.
Ili kulinda shambulio hili, ilitumika ukaguzi wa kawaida kwamba kipande “siyo” bandia: inakagua ikiwa bck->fd inaelekeza kwa victim. Yaani, katika kesi yetu ikiwa pointer fd* ya kipande bandia inayopangwa kwenye stack inaelekeza kwa victim. Ili kupita ulinzi huu mshambuliaji anapaswa kuwa na uwezo wa kuandika kwa njia fulani (kwa stack labda) kwenye anwani sahihi anwani ya victim. Ili hivyo ionekane kama kipande halisi.
Shambulio ni kama la awali, yaani, inahitaji kubadilisha pointer bk na inahitaji simu zote hizo za malloc(), lakini zaidi inahitaji kubadilisha size ya kipande kilichobadilishwa ili size hiyo - nb iwe <MINSIZE.
Kimsingi inajumuisha kuhifadhi kumbukumbu yote inayowezekana kwa heaps na kujaza hizi na mto wa nops unaomalizika na shellcode. Zaidi ya hayo, kama mto inatumika 0x0c. Kwa hivyo itajaribu kuruka kwenye anwani 0x0c0c0c0c, na hivyo ikiwa itandika anwani yoyote ambayo itaitwa na mto huu itaruka huko. Kimsingi mbinu ni kuhifadhi kadri iwezekanavyo ili kuona ikiwa inandika pointer yoyote na kuruka kwenye 0x0c0c0c0c ikitarajia kwamba huko kuna nops.
Inajumuisha kupitia uhifadhi na kuachiliwa kuandaa kumbukumbu ili kuwe na vipande vilivyohifadhiwa kati ya vipande vya bure. Buffer inayoweza kuzidiwa itakuwa katika moja ya mayai.
Learn & practice AWS Hacking:<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">\
Learn & practice GCP Hacking: <imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">](https://training.hacktricks.xyz/courses/grte)
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.