First Fit
First Fit
Wenn Sie im Programm Speicher freigeben, der glibc verwendet, werden verschiedene "Bins" verwendet, um die Speicherblöcke zu verwalten. Hier ist eine vereinfachte Erklärung von zwei häufigen Szenarien: unsorted bins und fastbins.
Unsorted Bins
Wenn Sie einen Speicherblock freigeben, der kein schneller Block ist, wird er in den unsorted bin verschoben. Dieser Bin fungiert wie eine Liste, in die neue freigegebene Blöcke vorne (dem "Kopf") hinzugefügt werden. Wenn Sie einen neuen Speicherblock anfordern, schaut der Allocator am Ende des unsorted bin (dem "Schwanz"), um einen ausreichend großen Block zu finden. Wenn ein Block aus dem unsorted bin größer ist als das, was Sie benötigen, wird er aufgeteilt, wobei der vordere Teil zurückgegeben wird und der verbleibende Teil im Bin verbleibt.
Beispiel:
Sie allozieren 300 Bytes (
a
), dann 250 Bytes (b
), gebena
frei und fordern erneut 250 Bytes an (c
).Wenn Sie
a
freigeben, wird es in den unsorted bin verschoben.Wenn Sie dann erneut 250 Bytes anfordern, findet der Allocator
a
am Ende und teilt ihn auf, gibt den Teil zurück, der Ihrer Anforderung entspricht, und behält den Rest im Bin.c
wird auf das vorherigea
zeigen und mit dena's
gefüllt sein.
Fastbins
Fastbins werden für kleine Speicherblöcke verwendet. Im Gegensatz zu unsortierten Bins fügen Fastbins neue Blöcke am Anfang hinzu, was ein Last-In-First-Out (LIFO)-Verhalten erzeugt. Wenn Sie einen kleinen Speicherblock anfordern, wird der Allocator diesen vom Kopf des Fastbins abrufen.
Beispiel:
Sie allozieren vier Blöcke von jeweils 20 Bytes (
a
,b
,c
,d
).Wenn Sie sie in beliebiger Reihenfolge freigeben, werden die freigegebenen Blöcke am Anfang des Fastbins hinzugefügt.
Wenn Sie dann einen 20-Byte-Block anfordern, wird der Allocator den zuletzt freigegebenen Block vom Kopf des Fastbins zurückgeben.
Weitere Referenzen & Beispiele
ARM64. Use after free: Erstellen eines Benutzerobjekts, Freigeben, Erstellen eines Objekts, das den freigegebenen Chunk erhält und das Schreiben darauf ermöglicht, Überschreiben der Position von user->password aus dem vorherigen. Wiederverwendung des Benutzers, um die Passwortprüfung zu umgehen
Das Programm ermöglicht das Erstellen von Notizen. Eine Notiz enthält die Notizinformationen in einem malloc(8) (mit einem Zeiger auf eine Funktion, die aufgerufen werden könnte) und einen Zeiger auf ein weiteres malloc(<size>) mit dem Inhalt der Notiz.
Der Angriff würde darin bestehen, 2 Notizen (note0 und note1) mit größeren malloc-Inhalten als der Notizinfo-Größe zu erstellen und sie dann freizugeben, damit sie in den Fast Bin (oder Tcache) gelangen.
Erstellen Sie dann eine weitere Notiz (note2) mit einer Inhaltsgröße von 8. Der Inhalt wird in note1 sein, da der Chunk wiederverwendet wird, wo wir den Funktionszeiger ändern könnten, um auf die Gewinnfunktion zu zeigen, und dann Use-After-Free die note1 aufrufen, um den neuen Funktionszeiger aufzurufen.
Es ist möglich, etwas Speicher zuzuweisen, den gewünschten Wert zu schreiben, ihn freizugeben, ihn neu zuzuweisen und da die vorherigen Daten noch vorhanden sind, wird er gemäß der neuen erwarteten Struktur im Chunk behandelt, was es ermöglicht, den Wert zu setzen oder die Flagge zu erhalten.
In diesem Fall muss die Zahl 4 in einem bestimmten Chunk geschrieben werden, der als erster zugewiesen wird (auch nachdem alle zwangsweise freigegeben wurden). Bei jedem neuen zugewiesenen Chunk wird seine Nummer im Arrayindex gespeichert. Dann 4 Chunks (+ der anfänglich zugewiesene) zuweisen, der letzte wird 4 enthalten, sie freigeben und die erneute Zuweisung des ersten erzwingen, der den zuletzt freigegebenen Chunk verwenden wird, der den Wert 4 enthält.
Last updated