Translated ['src/binary-exploitation/libc-heap/heap-overflow.md', 'src/b

This commit is contained in:
Translator 2025-07-30 06:14:49 +00:00
parent be0502d102
commit f22cda77ea
2 changed files with 70 additions and 9 deletions

View File

@ -4,7 +4,7 @@
## Basic Information
Ένα heap overflow είναι σαν ένα [**stack overflow**](../stack-overflow/index.html) αλλά στο heap. Βασικά σημαίνει ότι κάποιος χώρος είχε κρατηθεί στο heap για να αποθηκεύσει κάποια δεδομένα και **τα αποθηκευμένα δεδομένα ήταν μεγαλύτερα από τον κρατημένο χώρο.**
Ένα heap overflow είναι σαν ένα [**stack overflow**](../stack-overflow/index.html) αλλά στο heap. Βασικά σημαίνει ότι κάποιος χώρος έχει κρατηθεί στο heap για να αποθηκεύσει κάποια δεδομένα και **τα αποθηκευμένα δεδομένα ήταν μεγαλύτερα από τον κρατημένο χώρο.**
Στα stack overflows γνωρίζουμε ότι μερικοί καταχωρητές όπως ο δείκτης εντολών ή το stack frame θα αποκατασταθούν από το stack και θα μπορούσε να είναι δυνατό να γίνει κατάχρηση αυτού. Στην περίπτωση των heap overflows, **δεν υπάρχει καμία ευαίσθητη πληροφορία που να αποθηκεύεται από προεπιλογή** στο heap chunk που μπορεί να υπερχειλιστεί. Ωστόσο, θα μπορούσε να είναι ευαίσθητη πληροφορία ή δείκτες, οπότε η **κριτική σημασία** αυτής της ευπάθειας **εξαρτάται** από **ποια δεδομένα θα μπορούσαν να αντικατασταθούν** και πώς ένας επιτιθέμενος θα μπορούσε να εκμεταλλευτεί αυτό.
@ -19,19 +19,19 @@
Μία από τις τεχνικές που χρησιμοποιούνται για αυτό είναι το **Heap Grooming** το οποίο χρησιμοποιείται για παράδειγμα [**σε αυτή την ανάρτηση**](https://azeria-labs.com/grooming-the-ios-kernel-heap/). Στην ανάρτηση εξηγείται πώς όταν στο iOS kernel μια ζώνη εξαντλείται από μνήμη για να αποθηκεύσει chunks μνήμης, επεκτείνεται κατά μία σελίδα kernel, και αυτή η σελίδα χωρίζεται σε chunks των αναμενόμενων μεγεθών που θα χρησιμοποιηθούν με σειρά (μέχρι την έκδοση iOS 9.2, τότε αυτά τα chunks χρησιμοποιούνται με τυχαίο τρόπο για να δυσκολέψουν την εκμετάλλευση αυτών των επιθέσεων).
Επομένως, στην προηγούμενη ανάρτηση όπου συμβαίνει ένα heap overflow, προκειμένου να αναγκαστεί το υπερχειλισμένο αντικείμενο να συγκρούεται με μια παραγγελία θύματος, αρκετές **`kallocs` αναγκάζονται από αρκετά νήματα για να προσπαθήσουν να διασφαλίσουν ότι όλα τα ελεύθερα chunks είναι γεμάτα και ότι δημιουργείται μια νέα σελίδα**.
Επομένως, στην προηγούμενη ανάρτηση όπου συμβαίνει ένα heap overflow, προκειμένου να αναγκαστεί το υπερχειλισμένο αντικείμενο να συγκρούεται με μια σειρά θύματος, αρκετές **`kallocs` αναγκάζονται από αρκετές νήματα για να προσπαθήσουν να διασφαλίσουν ότι όλα τα ελεύθερα chunks είναι γεμάτα και ότι δημιουργείται μια νέα σελίδα**.
Για να αναγκαστεί αυτή η γέμιση με αντικείμενα συγκεκριμένου μεγέθους, η **εκτός γραμμής κατανομή που σχετίζεται με ένα mach port του iOS** είναι ένας ιδανικός υποψήφιος. Με την κατασκευή του μεγέθους του μηνύματος, είναι δυνατό να καθοριστεί ακριβώς το μέγεθος της κατανομής `kalloc` και όταν το αντίστοιχο mach port καταστραφεί, η αντίστοιχη κατανομή θα απελευθερωθεί αμέσως πίσω στο `kfree`.
Στη συνέχεια, μερικοί από αυτούς τους χώρους μπορούν να **απελευθερωθούν**. Η **λίστα ελεύθερων `kalloc.4096` απελευθερώνει στοιχεία με σειρά τελευταίου εισερχόμενου πρώτου εξερχόμενου**, που σημαίνει βασικά ότι αν μερικοί χώροι απελευθερωθούν και η εκμετάλλευση προσπαθήσει να κατανεμηθεί αρκετά αντικείμενα θύματα ενώ προσπαθεί να κατανεμηθεί το αντικείμενο που είναι ευάλωτο σε υπερχείλιση, είναι πιθανό ότι αυτό το αντικείμενο θα ακολουθείται από ένα αντικείμενο θύμα.
Στη συνέχεια, μερικοί από αυτούς τους χώρους μπορεί να είναι **ελεύθεροι**. Η **λίστα ελεύθερων `kalloc.4096` απελευθερώνει στοιχεία με σειρά τελευταίου εισερχόμενου πρώτου εξερχόμενου**, που σημαίνει βασικά ότι αν μερικοί χώροι είναι ελεύθεροι και η εκμετάλλευση προσπαθεί να κατανοήσει αρκετά αντικείμενα θύματα ενώ προσπαθεί να κατανοήσει το αντικείμενο που είναι ευάλωτο σε υπερχείλιση, είναι πιθανό ότι αυτό το αντικείμενο θα ακολουθείται από ένα αντικείμενο θύμα.
### Example libc
[**Σε αυτή τη σελίδα**](https://guyinatuxedo.github.io/27-edit_free_chunk/heap_consolidation_explanation/index.html) είναι δυνατό να βρείτε μια βασική προσομοίωση heap overflow που δείχνει πώς η αντικατάσταση του prev in use bit του επόμενου chunk και η θέση του prev size είναι δυνατό να **συγκεντρώσουν ένα χρησιμοποιούμενο chunk** (κάνοντάς το να νομίζει ότι είναι αχρησιμοποίητο) και **στη συνέχεια να το κατανεμηθεί ξανά** έχοντας τη δυνατότητα να αντικαταστήσει δεδομένα που χρησιμοποιούνται σε διαφορετικό δείκτη επίσης.
[**Σε αυτή τη σελίδα**](https://guyinatuxedo.github.io/27-edit_free_chunk/heap_consolidation_explanation/index.html) είναι δυνατό να βρείτε μια βασική προσομοίωση heap overflow που δείχνει πώς η αντικατάσταση του prev in use bit του επόμενου chunk και η θέση του prev size είναι δυνατό να **συγκεντρώσουν ένα χρησιμοποιούμενο chunk** (κάνοντάς το να νομίζει ότι είναι αχρησιμοποίητο) και **στη συνέχεια να το κατανοήσουν ξανά** έχοντας τη δυνατότητα να αντικαταστήσουν δεδομένα που χρησιμοποιούνται σε διαφορετικό δείκτη επίσης.
Ένα άλλο παράδειγμα από [**protostar heap 0**](https://guyinatuxedo.github.io/24-heap_overflow/protostar_heap0/index.html) δείχνει ένα πολύ βασικό παράδειγμα ενός CTF όπου ένα **heap overflow** μπορεί να εκμεταλλευτεί για να καλέσει τη συνάρτηση νικητή για **να πάρει τη σημαία**.
Στο παράδειγμα [**protostar heap 1**](https://guyinatuxedo.github.io/24-heap_overflow/protostar_heap1/index.html) είναι δυνατό να δείτε πώς με την κατάχρηση ενός buffer overflow είναι δυνατό να **αντικατασταθεί σε ένα κοντινό chunk μια διεύθυνση** όπου **τυχαία δεδομένα από τον χρήστη** θα γραφούν.
Στο παράδειγμα [**protostar heap 1**](https://guyinatuxedo.github.io/24-heap_overflow/protostar_heap1/index.html) είναι δυνατό να δείτε πώς με την κατάχρηση ενός buffer overflow είναι δυνατό να **αντικατασταθεί σε ένα κοντινό chunk μια διεύθυνση** όπου **θα γραφούν αυθαίρετα δεδομένα από τον χρήστη**.
### Example ARM64
@ -45,4 +45,36 @@ python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt
- Χρησιμοποιούμε μια ευπάθεια Integer Overflow για να αποκτήσουμε Heap Overflow.
- Διαφθείρουμε δείκτες σε μια συνάρτηση μέσα σε ένα `struct` του υπερχειλισμένου κομματιού για να ορίσουμε μια συνάρτηση όπως το `system` και να αποκτήσουμε εκτέλεση κώδικα.
### Παράδειγμα Πραγματικού Κόσμου: CVE-2025-40597 Κακή χρήση του `__sprintf_chk`
Στο firmware 10.2.1.15 του SonicWall SMA100, το module reverse-proxy `mod_httprp.so` εκχωρεί ένα **0x80-byte** heap chunk και στη συνέχεια συγχωνεύει πολλές συμβολοσειρές σε αυτό με το `__sprintf_chk`:
```c
char *buf = calloc(0x80, 1);
/* … */
__sprintf_chk(buf, /* destination (0x80-byte chunk) */
-1, /* <-- size argument !!! */
0, /* flags */
"%s%s%s%s", /* format */
"/", "https://", path, host);
```
`__sprintf_chk` είναι μέρος του **_FORTIFY_SOURCE**. Όταν λαμβάνει μια **θετική** παράμετρο `size`, επαληθεύει ότι η προκύπτουσα συμβολοσειρά χωράει μέσα στο προορισμένο buffer. Με την παράδοση **`-1` (0xFFFFFFFFFFFFFFFF)** οι προγραμματιστές ουσιαστικά **απενεργοποίησαν τον έλεγχο ορίων**, μετατρέποντας την ενισχυμένη κλήση πίσω σε μια κλασική, μη ασφαλή `sprintf`.
Η παροχή μιας υπερβολικά μεγάλης **`Host:`** κεφαλίδας επιτρέπει επομένως σε έναν επιτιθέμενο να **υπερχείλει το chunk των 0x80 byte και να καταστρέψει τα μεταδεδομένα του επόμενου chunk της heap** (tcache / fast-bin / small-bin ανάλογα με τον αλγόριθμο κατανομής). Ένα crash μπορεί να αναπαραχθεί με:
```python
import requests, warnings
warnings.filterwarnings('ignore')
requests.get(
'https://TARGET/__api__/',
headers={'Host': 'A'*750},
verify=False
)
```
Η πρακτική εκμετάλλευση θα απαιτούσε **heap grooming** για να τοποθετήσει ένα ελεγχόμενο αντικείμενο αμέσως μετά το ευάλωτο κομμάτι, αλλά η ρίζα του προβλήματος επισημαίνει δύο σημαντικά διδάγματα:
1. **_FORTIFY_SOURCE δεν είναι πανάκεια** η κακή χρήση μπορεί να αναιρέσει την προστασία.
2. Πάντα να περνάτε το **σωστό μέγεθος buffer** στην οικογένεια `_chk` (ή, ακόμα καλύτερα, να χρησιμοποιείτε `snprintf`).
## References
* [watchTowr Labs Stack Overflows, Heap Overflows and Existential Dread (SonicWall SMA100)](https://labs.watchtowr.com/stack-overflows-heap-overflows-and-existential-dread-sonicwall-sma100-cve-2025-40596-cve-2025-40597-and-cve-2025-40598/)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -4,7 +4,7 @@
## Τι είναι το Stack Overflow
Ένα **stack overflow** είναι μια ευπάθεια που συμβαίνει όταν ένα πρόγραμμα γράφει περισσότερα δεδομένα στο stack από όσα έχει εκχωρηθεί να κρατήσει. Αυτά τα επιπλέον δεδομένα θα **επικαλύψουν γειτονικό χώρο μνήμης**, οδηγώντας στη διαφθορά έγκυρων δεδομένων, διαταραχή της ροής ελέγχου και ενδεχομένως την εκτέλεση κακόβουλου κώδικα. Αυτό το ζήτημα προκύπτει συχνά λόγω της χρήσης μη ασφαλών συναρτήσεων που δεν εκτελούν έλεγχο ορίων στην είσοδο.
Ένα **stack overflow** είναι μια ευπάθεια που συμβαίνει όταν ένα πρόγραμμα γράφει περισσότερα δεδομένα στο stack από όσα έχει εκχωρηθεί να κρατήσει. Αυτά τα επιπλέον δεδομένα θα **επικαλύψουν τον γειτονικό χώρο μνήμης**, οδηγώντας στη διαφθορά έγκυρων δεδομένων, στην αναστάτωση της ροής ελέγχου και ενδεχομένως στην εκτέλεση κακόβουλου κώδικα. Αυτό το ζήτημα προκύπτει συχνά λόγω της χρήσης μη ασφαλών συναρτήσεων που δεν εκτελούν έλεγχο ορίων στην είσοδο.
Το κύριο πρόβλημα αυτής της επικαλύψεως είναι ότι ο **αποθηκευμένος δείκτης εντολών (EIP/RIP)** και ο **αποθηκευμένος δείκτης βάσης (EBP/RBP)** για να επιστρέψει στην προηγούμενη συνάρτηση είναι **αποθηκευμένα στο stack**. Επομένως, ένας επιτιθέμενος θα είναι σε θέση να τα επικαλύψει και να **ελέγξει τη ροή εκτέλεσης του προγράμματος**.
@ -53,11 +53,11 @@ pattern search $rsp #Search the offset given the content of $rsp
Κατά τη διάρκεια μιας υπερχείλισης (υποθέτοντας ότι το μέγεθος της υπερχείλισης είναι αρκετά μεγάλο) θα είστε σε θέση να **επικαλύψετε** τις τιμές των τοπικών μεταβλητών μέσα στη στοίβα μέχρι να φτάσετε στο αποθηκευμένο **EBP/RBP και EIP/RIP (ή ακόμα περισσότερα)**.\
Ο πιο κοινός τρόπος για να εκμεταλλευτείτε αυτόν τον τύπο ευπάθειας είναι να **τροποποιήσετε τη διεύθυνση επιστροφής** έτσι ώστε όταν η συνάρτηση τελειώσει, η **ροή ελέγχου θα ανακατευθυνθεί όπου έχει καθορίσει ο χρήστης** σε αυτόν τον δείκτη.
Ωστόσο, σε άλλα σενάρια, ίσως απλά **η επικαλυπτική τιμή κάποιων μεταβλητών στη στοίβα** να είναι αρκετή για την εκμετάλλευση (όπως σε εύκολες προκλήσεις CTF).
Ωστόσο, σε άλλα σενάρια, ίσως απλά **η επικαλύψη κάποιων τιμών μεταβλητών στη στοίβα** να είναι αρκετή για την εκμετάλλευση (όπως σε εύκολες προκλήσεις CTF).
### Ret2win
Σε αυτούς τους τύπους προκλήσεων CTF, υπάρχει μια **συνάρτηση** **μέσα** στο δυαδικό που **ποτέ δεν καλείται** και που **πρέπει να καλέσετε για να κερδίσετε**. Για αυτές τις προκλήσεις χρειάζεται απλώς να βρείτε την **απόσταση για να επικαλύψετε τη διεύθυνση επιστροφής** και **να βρείτε τη διεύθυνση της συνάρτησης** που θα καλέσετε (συνήθως [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html) θα είναι απενεργοποιημένο) έτσι ώστε όταν η ευάλωτη συνάρτηση επιστρέψει, η κρυφή συνάρτηση θα κληθεί:
Σε αυτούς τους τύπους προκλήσεων CTF, υπάρχει μια **συνάρτηση** **μέσα** στο δυαδικό αρχείο που **ποτέ δεν καλείται** και που **πρέπει να καλέσετε για να κερδίσετε**. Για αυτές τις προκλήσεις χρειάζεται απλώς να βρείτε την **απόσταση για να επικαλύψετε τη διεύθυνση επιστροφής** και **να βρείτε τη διεύθυνση της συνάρτησης** που θα καλέσετε (συνήθως [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html) θα είναι απενεργοποιημένο) έτσι ώστε όταν η ευάλωτη συνάρτηση επιστρέψει, η κρυφή συνάρτηση θα κληθεί:
{{#ref}}
ret2win/
@ -73,7 +73,7 @@ stack-shellcode/
### ROP & Ret2... τεχνικές
Αυτή η τεχνική είναι το θεμελιώδες πλαίσιο για να παρακάμψετε την κύρια προστασία της προηγούμενης τεχνικής: **Μη εκτελέσιμη στοίβα (NX)**. Και επιτρέπει την εκτέλεση αρκετών άλλων τεχνικών (ret2lib, ret2syscall...) που θα καταλήξουν να εκτελούν αυθαίρετες εντολές εκμεταλλευόμενοι υπάρχουσες εντολές στο δυαδικό:
Αυτή η τεχνική είναι το θεμελιώδες πλαίσιο για να παρακάμψει την κύρια προστασία της προηγούμενης τεχνικής: **Μη εκτελέσιμη στοίβα (NX)**. Και επιτρέπει την εκτέλεση αρκετών άλλων τεχνικών (ret2lib, ret2syscall...) που θα καταλήξουν να εκτελούν αυθαίρετες εντολές εκμεταλλευόμενοι υπάρχουσες εντολές στο δυαδικό αρχείο:
{{#ref}}
../rop-return-oriented-programing/
@ -95,4 +95,33 @@ stack-shellcode/
../common-binary-protections-and-bypasses/
{{#endref}}
### Πραγματικό Παράδειγμα: CVE-2025-40596 (SonicWall SMA100)
Μια καλή επίδειξη του γιατί **`sscanf` δεν πρέπει ποτέ να εμπιστεύεστε για την ανάλυση μη αξιόπιστης εισόδου** εμφανίστηκε το 2025 στη συσκευή SSL-VPN SMA100 της SonicWall.
Η ευάλωτη ρουτίνα μέσα στο `/usr/src/EasyAccess/bin/httpd` προσπαθεί να εξαγάγει την έκδοση και το σημείο πρόσβασης από οποιοδήποτε URI που αρχίζει με `/__api__/`:
```c
char version[3];
char endpoint[0x800] = {0};
/* simplified proto-type */
sscanf(uri, "%*[^/]/%2s/%s", version, endpoint);
```
1. Η πρώτη μετατροπή (`%2s`) αποθηκεύει με ασφάλεια **δύο** bytes στο `version` (π.χ. `"v1"`).
2. Η δεύτερη μετατροπή (`%s`) **δεν έχει καθοριστή μήκους**, επομένως το `sscanf` θα συνεχίσει να αντιγράφει **μέχρι το πρώτο NUL byte**.
3. Επειδή το `endpoint` βρίσκεται στη **στοίβα** και έχει μήκος **0x800 bytes**, η παροχή ενός μονοπατιού μεγαλύτερου από 0x800 bytes διαφθείρει τα πάντα που βρίσκονται μετά το buffer συμπεριλαμβανομένου του **stack canary** και της **αποθηκευμένης διεύθυνσης επιστροφής**.
Μια απόδειξη-έννοια μίας γραμμής είναι αρκετή για να προκαλέσει την κατάρρευση **πριν από την αυθεντικοποίηση**:
```python
import requests, warnings
warnings.filterwarnings('ignore')
url = "https://TARGET/__api__/v1/" + "A"*3000
requests.get(url, verify=False)
```
Ακόμα και αν οι stack canaries τερματίζουν τη διαδικασία, ένας επιτιθέμενος αποκτά ακόμα ένα **Denial-of-Service** primitive (και, με επιπλέον διαρροές πληροφοριών, πιθανώς εκτέλεση κώδικα). Το μάθημα είναι απλό:
* Πάντα να παρέχετε ένα **μέγιστο πλάτος πεδίου** (π.χ. `%511s`).
* Προτιμήστε ασφαλέστερες εναλλακτικές όπως `snprintf`/`strncpy_s`.
## References
* [watchTowr Labs Stack Overflows, Heap Overflows and Existential Dread (SonicWall SMA100)](https://labs.watchtowr.com/stack-overflows-heap-overflows-and-existential-dread-sonicwall-sma100-cve-2025-40596-cve-2025-40597-and-cve-2025-40598/)
{{#include ../../banners/hacktricks-training.md}}