mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/binary-exploitation/libc-heap/use-after-free/first-fit.
This commit is contained in:
parent
832f92b990
commit
16ffc013fb
@ -12,10 +12,10 @@
|
||||
|
||||
उदाहरण:
|
||||
|
||||
- आप 300 बाइट (`a`) आवंटित करते हैं, फिर 250 बाइट (`b`), `a` को फ्री करते हैं और फिर से 250 बाइट (`c`) मांगते हैं।
|
||||
- आप 300 बाइट (`a`) आवंटित करते हैं, फिर 250 बाइट (`b`), फिर `a` को फ्री करते हैं और फिर से 250 बाइट (`c`) मांगते हैं।
|
||||
- जब आप `a` को फ्री करते हैं, तो यह अनसॉर्टेड बिन में चला जाता है।
|
||||
- यदि आप फिर से 250 बाइट मांगते हैं, तो आवंटक `a` को टेल पर पाता है और इसे विभाजित करता है, आपके अनुरोध के अनुसार फिट होने वाला भाग वापस करता है और बाकी को बिन में रखता है।
|
||||
- `c` पिछले `a` की ओर इशारा करेगा और `a's` से भरा होगा।
|
||||
- यदि आप फिर से 250 बाइट मांगते हैं, तो आवंटक `a` को टेल में पाता है और इसे विभाजित करता है, आपके अनुरोध के अनुसार फिट होने वाला भाग वापस करता है और बाकी को बिन में रखता है।
|
||||
- `c` पिछले `a` की ओर इशारा करेगा और `a` की सामग्री से भरा होगा।
|
||||
```c
|
||||
char *a = malloc(300);
|
||||
char *b = malloc(250);
|
||||
@ -24,13 +24,9 @@ char *c = malloc(250);
|
||||
```
|
||||
### Fastbins
|
||||
|
||||
Fastbins छोटे मेमोरी टुकड़ों के लिए उपयोग किए जाते हैं। असंरचित बिन के विपरीत, फास्टबिन नए टुकड़ों को सिर में जोड़ते हैं, जिससे अंतिम-में-प्रथम-निकालने (LIFO) व्यवहार उत्पन्न होता है। यदि आप छोटे मेमोरी टुकड़े की मांग करते हैं, तो आवंटक फास्टबिन के सिर से खींचेगा।
|
||||
Fastbins छोटे मेमोरी टुकड़ों के लिए उपयोग किए जाते हैं। असंरचित बिन के विपरीत, फास्टबिन नए टुकड़ों को सिर में जोड़ते हैं, जिससे अंतिम-में-प्रथम-निकालने (LIFO) व्यवहार उत्पन्न होता है। यदि आप मेमोरी का एक छोटा टुकड़ा मांगते हैं, तो आवंटक फास्टबिन के सिर से खींचेगा।
|
||||
|
||||
उदाहरण:
|
||||
|
||||
- आप प्रत्येक 20 बाइट के चार टुकड़े आवंटित करते हैं (`a`, `b`, `c`, `d`)।
|
||||
- जब आप उन्हें किसी भी क्रम में मुक्त करते हैं, तो मुक्त किए गए टुकड़े फास्टबिन के सिर में जोड़े जाते हैं।
|
||||
- यदि आप फिर 20-बाइट का टुकड़ा मांगते हैं, तो आवंटक फास्टबिन के सिर से हाल ही में मुक्त किया गया टुकड़ा लौटाएगा।
|
||||
Example:
|
||||
```c
|
||||
char *a = malloc(20);
|
||||
char *b = malloc(20);
|
||||
@ -45,18 +41,89 @@ b = malloc(20); // c
|
||||
c = malloc(20); // b
|
||||
d = malloc(20); // a
|
||||
```
|
||||
## अन्य संदर्भ और उदाहरण
|
||||
---
|
||||
### 🔥 आधुनिक glibc विचार (tcache ≥ 2.26)
|
||||
|
||||
glibc 2.26 से हर थ्रेड अपनी **tcache** रखता है जिसे *unsorted bin* से *पहले* क्वेरी किया जाता है। इसलिए एक first-fit परिदृश्य **तब ही प्राप्त होगा यदि**:
|
||||
|
||||
1. अनुरोधित आकार **`tcache_max`** (डिफ़ॉल्ट रूप से 64-बिट पर 0x420) से **बड़ा है**, *या*
|
||||
2. संबंधित tcache बिन **पहले से ही भरा हुआ है या मैन्युअल रूप से खाली किया गया है** (7 तत्वों को आवंटित करके और उन्हें उपयोग में रखकर)।
|
||||
|
||||
वास्तविक हमलों में आप आमतौर पर एक सहायक रूटीन जोड़ेंगे जैसे:
|
||||
```c
|
||||
// Drain the tcache for a given size
|
||||
for(int i = 0; i < 7; i++) pool[i] = malloc(0x100);
|
||||
for(int i = 0; i < 7; i++) free(pool[i]);
|
||||
```
|
||||
एक बार जब tcache समाप्त हो जाता है, तो बाद में की गई frees अनसॉर्टेड बिन में जाती हैं और क्लासिक फर्स्ट-फिट व्यवहार (टेल सर्च, हेड इंसर्शन) फिर से सक्रिय किया जा सकता है।
|
||||
|
||||
---
|
||||
### 🚩 पहले-फिट के साथ ओवरलैपिंग-चंक UAF बनाना
|
||||
|
||||
नीचे दिया गया अंश (glibc 2.38 पर परीक्षण किया गया) दिखाता है कि अनसॉर्टेड बिन में स्प्लिटर का दुरुपयोग कैसे किया जा सकता है ताकि 2 **ओवरलैपिंग पॉइंटर्स** बनाए जा सकें - एक शक्तिशाली प्राइमिटिव जो एकल फ्री को राइट-आफ्टर-फ्री में परिवर्तित करता है।
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(){
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
/* 1. prepare 2 adjacent chunks and free the first one */
|
||||
char *A = malloc(0x420); // big enough to bypass tcache
|
||||
char *B = malloc(0x420);
|
||||
strcpy(A, "AAAA\n");
|
||||
free(A); // A → unsorted
|
||||
|
||||
/* 2. request a *smaller* size to force a split of A */
|
||||
char *C = malloc(0x400); // returns lower half of former A
|
||||
|
||||
/* 3. The remainder of A is still in the unsorted bin.
|
||||
Another 0x400-byte malloc will now return the *same*
|
||||
region pointed to by B – creating a UAF/overlap. */
|
||||
char *C2 = malloc(0x400);
|
||||
|
||||
printf("B = %p\nC2 = %p (overlaps B)\n", B, C2);
|
||||
|
||||
// Arbitrary write in B is immediately visible via C2
|
||||
memset(B, 'X', 0x10);
|
||||
fwrite(C2, 1, 0x10, stdout); // prints Xs
|
||||
}
|
||||
```
|
||||
Exploitation recipe (common in recent CTFs):
|
||||
|
||||
1. **Drain** the tcache for the target size.
|
||||
2. **Free** a chunk so it lands in the unsorted bin.
|
||||
3. **Allocate** a slightly smaller size – the allocator splits the unsorted chunk.
|
||||
4. **Allocate** again – the leftover part overlaps with an existing in-use chunk → UAF.
|
||||
5. Overwrite sensitive fields (function pointers, FILE vtable, etc.)
|
||||
|
||||
A practical application can be found in the 2024 HITCON Quals *Setjmp* challenge where this exact primitive is used to pivot from a UAF to full control of `__free_hook`.{{#ref}}
|
||||
../../../../references/2024_setjmp_firstfit.md
|
||||
{{#endref}}
|
||||
|
||||
---
|
||||
### 🛡️ Mitigations & Hardening
|
||||
|
||||
* **Safe-linking (glibc ≥ 2.32)** केवल एकल-लिंक्ड *tcache*/**fastbin** सूचियों की सुरक्षा करता है। असंरचित/छोटे/बड़े बिन अभी भी कच्चे पॉइंटर्स को संग्रहीत करते हैं, इसलिए पहले-फिट आधारित ओवरलैप तब भी संभव हैं यदि आप एक हीप लीक प्राप्त कर सकते हैं।
|
||||
* **Heap pointer encryption & MTE** (ARM64) अभी तक x86-64 glibc को प्रभावित नहीं करते हैं, लेकिन वितरण हार्डनिंग फ्लैग जैसे `GLIBC_TUNABLES=glibc.malloc.check=3` असंगत मेटाडेटा पर abort करेंगे और naïve PoCs को तोड़ सकते हैं।
|
||||
* **Filling tcache on free** (2024 में glibc 2.41 के लिए प्रस्तावित) असंरचित उपयोग को और कम करेगा; सामान्य एक्सप्लॉइट विकसित करते समय भविष्य के रिलीज़ की निगरानी करें।
|
||||
|
||||
---
|
||||
## Other References & Examples
|
||||
|
||||
- [**https://heap-exploitation.dhavalkapil.com/attacks/first_fit**](https://heap-exploitation.dhavalkapil.com/attacks/first_fit)
|
||||
- [**https://8ksec.io/arm64-reversing-and-exploitation-part-2-use-after-free/**](https://8ksec.io/arm64-reversing-and-exploitation-part-2-use-after-free/)
|
||||
- ARM64. उपयोग के बाद मुक्त: एक उपयोगकर्ता वस्तु उत्पन्न करें, इसे मुक्त करें, एक वस्तु उत्पन्न करें जो मुक्त किए गए टुकड़े को प्राप्त करती है और इसे लिखने की अनुमति देती है, **पिछली स्थिति को ओवरराइट करते हुए user->password**। उपयोगकर्ता का पुन: उपयोग करें ताकि **पासवर्ड जांच को बायपास किया जा सके**
|
||||
- ARM64. Use after free: Generate an user object, free it, generate an object that gets the freed chunk and allow to write to it, **overwriting the position of user->password** from the previous one. Reuse the user to **bypass the password check**
|
||||
- [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/use_after_free/#example**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/use_after_free/#example)
|
||||
- कार्यक्रम नोट्स बनाने की अनुमति देता है। एक नोट में नोट की जानकारी malloc(8) में होगी (जिसमें एक फ़ंक्शन का पॉइंटर होगा जिसे कॉल किया जा सकता है) और एक अन्य malloc(\<size>) का पॉइंटर होगा जिसमें नोट की सामग्री होगी।
|
||||
- हमला 2 नोट्स (note0 और note1) बनाने का होगा जिनकी malloc सामग्री नोट जानकारी के आकार से बड़ी होगी और फिर उन्हें मुक्त करें ताकि वे तेज बिन (या tcache) में जा सकें।
|
||||
- फिर, एक और नोट (note2) बनाएं जिसकी सामग्री का आकार 8 हो। सामग्री note1 में होगी क्योंकि टुकड़ा पुन: उपयोग किया जाएगा, जहां हम फ़ंक्शन पॉइंटर को win फ़ंक्शन की ओर इंगित करने के लिए संशोधित कर सकते हैं और फिर नोट1 को Use-After-Free करके नए फ़ंक्शन पॉइंटर को कॉल कर सकते हैं।
|
||||
- The program allows to create notes. A note will have the note info in a malloc(8) (with a pointer to a function that could be called) and a pointer to another malloc(<size>) with the contents of the note.
|
||||
- The attack would be to create 2 notes (note0 and note1) with bigger malloc contents than the note info size and then free them so they get into the fast bin (or tcache).
|
||||
- Then, create another note (note2) with content size 8. The content is going to be in note1 as the chunk is going to be reused, were we could modify the function pointer to point to the win function and then Use-After-Free the note1 to call the new function pointer.
|
||||
- [**https://guyinatuxedo.github.io/26-heap_grooming/pico_areyouroot/index.html**](https://guyinatuxedo.github.io/26-heap_grooming/pico_areyouroot/index.html)
|
||||
- कुछ मेमोरी आवंटित करना, इच्छित मान लिखना, इसे मुक्त करना, पुनः आवंटित करना संभव है और चूंकि पिछले डेटा अभी भी वहां है, इसे टुकड़े में नए अपेक्षित संरचना के अनुसार माना जाएगा जिससे मान सेट करना या ध्वज प्राप्त करना संभव हो जाएगा।
|
||||
- It's possible to alloc some memory, write the desired value, free it, realloc it and as the previous data is still there, it will treated according the new expected struct in the chunk making possible to set the value ot get the flag.
|
||||
- [**https://guyinatuxedo.github.io/26-heap_grooming/swamp19_heapgolf/index.html**](https://guyinatuxedo.github.io/26-heap_grooming/swamp19_heapgolf/index.html)
|
||||
- इस मामले में एक विशिष्ट टुकड़े के अंदर 4 लिखना आवश्यक है जो पहला है जिसे आवंटित किया गया है (यहां तक कि सभी को बलपूर्वक मुक्त करने के बाद भी)। प्रत्येक नए आवंटित टुकड़े में इसका नंबर ऐरे इंडेक्स में संग्रहीत होता है। फिर, 4 टुकड़े (+ प्रारंभ में आवंटित) आवंटित करें, अंतिम में 4 होगा, उन्हें मुक्त करें और पहले को पुनः आवंटित करने के लिए मजबूर करें, जो अंतिम मुक्त टुकड़े का उपयोग करेगा जिसमें 4 होगा।
|
||||
- In this case it's needed to write 4 inside an specific chunk which is the first one being allocated (even after force freeing all of them). On each new allocated chunk it's number in the array index is stored. Then, allocate 4 chunks (+ the initialy allocated), the last one will have 4 inside of it, free them and force the reallocation of the first one, which will use the last chunk freed which is the one with 4 inside of it.
|
||||
- 2024 HITCON Quals Setjmp write-up (Quarkslab) – practical first-fit / unsorted-split overlap attack: <https://ctftime.org/writeup/39355>
|
||||
- Angstrom CTF 2024 *heapify* write-up – abusing unsorted-bin splitting to leak libc and gain overlap: <https://hackmd.io/@aneii11/H1S2snV40>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user