Double Free

Support HackTricks

Basic Information

यदि आप एक मेमोरी ब्लॉक को एक से अधिक बार मुक्त करते हैं, तो यह आवंटक के डेटा को गड़बड़ कर सकता है और हमलों के लिए दरवाजा खोल सकता है। यह कैसे होता है: जब आप एक मेमोरी ब्लॉक को मुक्त करते हैं, तो यह मुक्त टुकड़ों की सूची में वापस चला जाता है (जैसे "फास्ट बिन")। यदि आप एक ही ब्लॉक को लगातार दो बार मुक्त करते हैं, तो आवंटक इसे पहचानता है और एक त्रुटि फेंकता है। लेकिन यदि आप बीच में एक और टुकड़ा मुक्त करते हैं, तो डबल-फ्री जांच को बायपास किया जाता है, जिससे भ्रष्टाचार होता है।

अब, जब आप नई मेमोरी के लिए पूछते हैं ( malloc का उपयोग करके), तो आवंटक आपको एक ब्लॉक दे सकता है जिसे दो बार मुक्त किया गया है। इससे दो अलग-अलग पॉइंटर्स एक ही मेमोरी स्थान की ओर इशारा कर सकते हैं। यदि एक हमलावर उन पॉइंटर्स में से एक को नियंत्रित करता है, तो वे उस मेमोरी की सामग्री को बदल सकते हैं, जो सुरक्षा समस्याओं का कारण बन सकता है या यहां तक कि उन्हें कोड निष्पादित करने की अनुमति भी दे सकता है।

Example:

#include <stdio.h>
#include <stdlib.h>

int main() {
// Allocate memory for three chunks
char *a = (char *)malloc(10);
char *b = (char *)malloc(10);
char *c = (char *)malloc(10);
char *d = (char *)malloc(10);
char *e = (char *)malloc(10);
char *f = (char *)malloc(10);
char *g = (char *)malloc(10);
char *h = (char *)malloc(10);
char *i = (char *)malloc(10);

// Print initial memory addresses
printf("Initial allocations:\n");
printf("a: %p\n", (void *)a);
printf("b: %p\n", (void *)b);
printf("c: %p\n", (void *)c);
printf("d: %p\n", (void *)d);
printf("e: %p\n", (void *)e);
printf("f: %p\n", (void *)f);
printf("g: %p\n", (void *)g);
printf("h: %p\n", (void *)h);
printf("i: %p\n", (void *)i);

// Fill tcache
free(a);
free(b);
free(c);
free(d);
free(e);
free(f);
free(g);

// Introduce double-free vulnerability in fast bin
free(h);
free(i);
free(h);


// Reallocate memory and print the addresses
char *a1 = (char *)malloc(10);
char *b1 = (char *)malloc(10);
char *c1 = (char *)malloc(10);
char *d1 = (char *)malloc(10);
char *e1 = (char *)malloc(10);
char *f1 = (char *)malloc(10);
char *g1 = (char *)malloc(10);
char *h1 = (char *)malloc(10);
char *i1 = (char *)malloc(10);
char *i2 = (char *)malloc(10);

// Print initial memory addresses
printf("After reallocations:\n");
printf("a1: %p\n", (void *)a1);
printf("b1: %p\n", (void *)b1);
printf("c1: %p\n", (void *)c1);
printf("d1: %p\n", (void *)d1);
printf("e1: %p\n", (void *)e1);
printf("f1: %p\n", (void *)f1);
printf("g1: %p\n", (void *)g1);
printf("h1: %p\n", (void *)h1);
printf("i1: %p\n", (void *)i1);
printf("i2: %p\n", (void *)i2);

return 0;
}

इस उदाहरण में, कई मुक्त किए गए चंक्स (7) के साथ tcache भरने के बाद, कोड चंक h को मुक्त करता है, फिर चंक i को, और फिर h को फिर से, जिससे एक डबल फ्री होती है (जिसे Fast Bin dup भी कहा जाता है)। यह पुनः आवंटन करते समय ओवरलैपिंग मेमोरी पते प्राप्त करने की संभावना खोलता है, जिसका अर्थ है कि दो या अधिक पॉइंटर्स एक ही मेमोरी स्थान की ओर इशारा कर सकते हैं। एक पॉइंटर के माध्यम से डेटा को हेरफेर करने से दूसरे पर प्रभाव पड़ सकता है, जिससे एक महत्वपूर्ण सुरक्षा जोखिम और शोषण की संभावना उत्पन्न होती है।

इसे निष्पादित करते समय, ध्यान दें कि i1 और i2 को वही पता मिला:

Initial allocations:
a: 0xaaab0f0c22a0
b: 0xaaab0f0c22c0
c: 0xaaab0f0c22e0
d: 0xaaab0f0c2300
e: 0xaaab0f0c2320
f: 0xaaab0f0c2340
g: 0xaaab0f0c2360
h: 0xaaab0f0c2380
i: 0xaaab0f0c23a0
After reallocations:
a1: 0xaaab0f0c2360
b1: 0xaaab0f0c2340
c1: 0xaaab0f0c2320
d1: 0xaaab0f0c2300
e1: 0xaaab0f0c22e0
f1: 0xaaab0f0c22c0
g1: 0xaaab0f0c22a0
h1: 0xaaab0f0c2380
i1: 0xaaab0f0c23a0
i2: 0xaaab0f0c23a0

Examples

  • हम केवल Fast-Bin आकार के चंक्स आवंटित कर सकते हैं सिवाय आकार 0x70 के, जो सामान्य __malloc_hook ओवरराइट को रोकता है।

  • इसके बजाय, हम Fast Bin dup (1/2 मौका) के लिए लक्ष्य के रूप में 0x56 से शुरू होने वाले PIE पते का उपयोग करते हैं।

  • एक स्थान जहां PIE पते संग्रहीत होते हैं वह है main_arena, जो Glibc के अंदर है और __malloc_hook के पास है।

  • हम main_arena के एक विशिष्ट ऑफसेट को लक्षित करते हैं ताकि वहां एक चंक आवंटित किया जा सके और __malloc_hook तक पहुंचने के लिए चंक्स को आवंटित करना जारी रखें ताकि कोड निष्पादन प्राप्त किया जा सके।

  • Tcache बिन और एक null-byte ओवरफ्लो का उपयोग करके, हम एक डबल-फ्री स्थिति प्राप्त कर सकते हैं:

  • हम आकार 0x110 के तीन चंक्स (A, B, C) आवंटित करते हैं

  • हम B को मुक्त करते हैं

  • हम A को मुक्त करते हैं और null-byte ओवरफ्लो का उपयोग करने के लिए फिर से आवंटित करते हैं

  • अब B का आकार क्षेत्र 0x100 है, 0x111 के बजाय, इसलिए हम इसे फिर से मुक्त कर सकते हैं

  • हमारे पास आकार 0x110 का एक Tcache-bin और आकार 0x100 का एक है जो उसी पते की ओर इशारा करता है। इसलिए हमारे पास एक डबल फ्री है।

  • हम Tcache poisoning का उपयोग करके डबल फ्री का लाभ उठाते हैं।

References

Support HackTricks

Last updated