hacktricks/binary-exploitation/heap/large-bin-attack.md

5.9 KiB
Raw Blame History

Επίθεση Large Bin

Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το htARTE (Ειδικός Red Team του HackTricks AWS)!

Άλλοι τρόποι υποστήριξης του HackTricks:

Βασικές Πληροφορίες

Για περισσότερες πληροφορίες σχετικά με το τι είναι ένα μεγάλο bin ελέγξτε αυτήν τη σελίδα:

{% content-ref url="bins-and-memory-allocations.md" %} bins-and-memory-allocations.md {% endcontent-ref %}

Είναι δυνατό να βρείτε ένα εξαιρετικό παράδειγμα στο how2heap - επίθεση μεγάλου bin.

Βασικά εδώ μπορείτε να δείτε πώς, στην τελευταία "τρέχουσα" έκδοση του glibc (2.35), δεν ελέγχεται: P->bk_nextsize επιτρέποντας την τροποποίηση μιας αυθαίρετης διεύθυνσης με την τιμή ενός κομματιού μεγάλου bin αν πληρούνται συγκεκριμένες συνθήκες.

Σε εκείνο το παράδειγμα μπορείτε να βρείτε τις ακόλουθες συνθήκες:

  • Ένα μεγάλο κομμάτι είναι εκχωρημένο
  • Ένα μεγάλο κομμάτι μικρότερο από το πρώτο αλλά στον ίδιο δείκτη εκχωρείται
  • Πρέπει να είναι μικρότερο ώστε στο bin να πάει πρώτο
  • (Δημιουργείται ένα κομμάτι για να αποτρέψει τη συγχώνευση με το κομμάτι κορυφής)
  • Στη συνέχεια, το πρώτο μεγάλο κομμάτι απελευθερώνεται και εκχωρείται ένα νέο κομμάτι μεγαλύτερο από αυτό -> Το Κομμάτι1 πηγαίνει στο μεγάλο bin
  • Στη συνέχεια, το δεύτερο μεγάλο κομμάτι απελευθερώνεται
  • Τώρα, η ευπάθεια: Ο επιτιθέμενος μπορεί να τροποποιήσει το chunk1->bk_nextsize σε [target-0x20]
  • Στη συνέχεια, εκχωρείται ένα μεγαλύτερο κομμάτι από το κομμάτι 2, έτσι το κομμάτι2 εισάγεται στο μεγάλο bin αντικαθιστώντας τη διεύθυνση chunk1->bk_nextsize->fd_nextsize με τη διεύθυνση του κομματιού 2

{% hint style="success" %} Υπάρχουν και άλλα πιθανά σενάρια, το θέμα είναι να προστεθεί στο μεγάλο bin ένα κομμάτι που είναι μικρότερο από ένα τρέχον κομμάτι X στο bin, έτσι ώστε να εισαχθεί ακριβώς πριν από αυτό στο bin, και πρέπει να μπορούμε να τροποποιήσουμε το bk_nextsize του X καθώς εκεί θα γραφτεί η διεύθυνση του μικρότερου κομματιού. {% endhint %}

Αυτός είναι ο σχετικός κώδικας από το malloc. Έχουν προστεθεί σχόλια για καλύτερη κατανόηση του πώς έγινε η αντικατάσταση της διεύθυνσης:

{% code overflow="wrap" %}

/* if smaller than smallest, bypass loop below */
assert (chunk_main_arena (bck->bk));
if ((unsigned long) (size) < (unsigned long) chunksize_nomask (bck->bk))
{
fwd = bck; // fwd = p1
bck = bck->bk; // bck = p1->bk

victim->fd_nextsize = fwd->fd; // p2->fd_nextsize = p1->fd (Note that p1->fd is p1 as it's the only chunk)
victim->bk_nextsize = fwd->fd->bk_nextsize; // p2->bk_nextsize = p1->fd->bk_nextsize
fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim; // p1->fd->bk_nextsize->fd_nextsize = p2
}

{% endcode %}

Αυτό θα μπορούσε να χρησιμοποιηθεί για να αντικαταστήσετε την παγκόσμια μεταβλητή global_max_fast της libc για να εκμεταλλευτείτε έπειτα μια επίθεση fast bin με μεγαλύτερα κομμάτια.

Μπορείτε να βρείτε μια άλλη εξαιρετική εξήγηση αυτής της επίθεσης στο guyinatuxedo.