6.2 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	House of Roman
{{#include ../../banners/hacktricks-training.md}}
Grundinformationen
Dies war eine sehr interessante Technik, die RCE ohne Lecks über gefälschte Fastbins, den unsorted_bin-Angriff und relative Überschreibungen ermöglichte. Es wurde jedoch gepatcht.
Code
- Ein Beispiel finden Sie unter https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c
Ziel
- RCE durch Missbrauch relativer Zeiger
Anforderungen
- Bearbeiten Sie die Zeiger für Fastbin und unsorted bin
- 12 Bits Zufälligkeit müssen brute-forced werden (0,02% Chance), um zu funktionieren
Angriffs Schritte
Teil 1: Fastbin Chunk zeigt auf __malloc_hook
Erstellen Sie mehrere Chunks:
- fastbin_victim(0x60, Offset 0): UAF-Chunk, um später den Heap-Zeiger auf den LibC-Wert zu bearbeiten.
- chunk2(0x80, Offset 0x70): Für gute Ausrichtung
- main_arena_use(0x80, Offset 0x100)
- relative_offset_heap(0x60, Offset 0x190): relativer Offset auf den 'main_arena_use'-Chunk
Dann free(main_arena_use), was diesen Chunk in die unsorted-Liste platziert und einen Zeiger auf main_arena + 0x68 in den fd- und bk-Zeigern erhält.
Jetzt wird ein neuer Chunk fake_libc_chunk(0x60) zugewiesen, da er die Zeiger auf main_arena + 0x68 in fd und bk enthalten wird.
Dann werden relative_offset_heap und fastbin_victim freigegeben.
/*
Current heap layout:
0x0:   fastbin_victim       - size 0x70
0x70:  alignment_filler     - size 0x90
0x100: fake_libc_chunk      - size 0x70 (contains a fd ptr to main_arena + 0x68)
0x170: leftover_main        - size 0x20
0x190: relative_offset_heap - size 0x70
bin layout:
fastbin:  fastbin_victim -> relative_offset_heap
unsorted: leftover_main
*/
-  fastbin_victimhat einenfd, der aufrelative_offset_heapzeigt
-  relative_offset_heapist ein Offset von der Distanz zufake_libc_chunk, das einen Zeiger aufmain_arena + 0x68enthält
- Durch das Ändern des letzten Bytes von fastbin_victim.fdist es möglich, dassfastbin_victimaufmain_arena + 0x68zeigt
Für die vorherigen Aktionen muss der Angreifer in der Lage sein, den fd-Zeiger von fastbin_victim zu modifizieren.
Dann ist main_arena + 0x68 nicht so interessant, also lassen Sie uns es ändern, damit der Zeiger auf __malloc_hook zeigt.
Beachten Sie, dass __memalign_hook normalerweise mit 0x7f beginnt und davor Nullen hat, dann ist es möglich, es als einen Wert im 0x70 Fast Bin zu fälschen. Da die letzten 4 Bits der Adresse zufällig sind, gibt es 2^4=16 Möglichkeiten, dass der Wert dort endet, wo wir interessiert sind. Daher wird hier ein BF-Angriff durchgeführt, sodass der Chunk endet wie: 0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23).
(Für weitere Informationen zu den restlichen Bytes überprüfen Sie die Erklärung im how2heap Beispiel). Wenn der BF nicht funktioniert, stürzt das Programm einfach ab (also starten Sie erneut, bis es funktioniert).
Dann werden 2 Mallocs durchgeführt, um die 2 initialen Fast Bin Chunks zu entfernen, und ein dritter wird alloziert, um einen Chunk in __malloc_hook: zu erhalten.
malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);
Teil 2: Unsorted_bin-Angriff
Für weitere Informationen können Sie überprüfen:
{{#ref}} unsorted-bin-attack.md {{#endref}}
Aber im Grunde ermöglicht es, main_arena + 0x68 an jeden Ort zu schreiben, der in chunk->bk angegeben ist. Und für den Angriff wählen wir __malloc_hook. Dann, nachdem wir es überschrieben haben, verwenden wir eine relative Überschreibung, um auf ein one_gadget zu zeigen.
Dafür beginnen wir, einen Chunk zu erhalten und ihn in den unsorted bin zu legen:
uint8_t* unsorted_bin_ptr = malloc(0x80);
malloc(0x30); // Don't want to consolidate
puts("Put chunk into unsorted_bin\n");
// Free the chunk to create the UAF
free(unsorted_bin_ptr);
Verwenden Sie ein UAF in diesem Chunk, um unsorted_bin_ptr->bk auf die Adresse von __malloc_hook zu zeigen (wir haben dies zuvor brute-forced).
Caution
Beachten Sie, dass dieser Angriff den unsortierten Bin (und damit auch den kleinen und großen) beschädigt. Daher können wir jetzt nur Allokationen aus dem schnellen Bin verwenden (ein komplexeres Programm könnte andere Allokationen durchführen und abstürzen), und um dies auszulösen, müssen wir die gleiche Größe allokieren, sonst wird das Programm abstürzen.
Um also den Schreibvorgang von main_arena + 0x68 in __malloc_hook auszulösen, führen wir nach dem Setzen von __malloc_hook in unsorted_bin_ptr->bk einfach aus: malloc(0x80)
Schritt 3: Setzen Sie __malloc_hook auf system
Im ersten Schritt haben wir einen Chunk kontrolliert, der __malloc_hook enthält (in der Variablen malloc_hook_chunk), und im zweiten Schritt haben wir es geschafft, main_arena + 0x68 hier zu schreiben.
Jetzt missbrauchen wir eine partielle Überschreibung in malloc_hook_chunk, um die libc-Adresse, die wir dort geschrieben haben (main_arena + 0x68), zu einer one_gadget-Adresse zu zeigen.
Hier ist es notwendig, 12 Bits Zufälligkeit zu brute-forcen (weitere Informationen im how2heap Beispiel).
Schließlich, sobald die korrekte Adresse überschrieben ist, rufen Sie malloc auf und lösen Sie die one_gadget aus.
Referenzen
- https://github.com/shellphish/how2heap
- https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c
- https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_roman/
{{#include ../../banners/hacktricks-training.md}}