mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
113 lines
7.0 KiB
Markdown
113 lines
7.0 KiB
Markdown
# House of Roman
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## 基本情報
|
||
|
||
これは、フェイクファストビン、アンソートビン攻撃、相対的オーバーライトを介してリークなしでRCEを可能にする非常に興味深い技術でした。しかし、これは[**パッチが当てられました**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c)。
|
||
|
||
### コード
|
||
|
||
- 例は[https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)で見つけることができます。
|
||
|
||
### 目標
|
||
|
||
- 相対ポインタを悪用してRCEを実現すること
|
||
|
||
### 要件
|
||
|
||
- ファストビンとアンソートビンのポインタを編集する
|
||
- 12ビットのランダム性をブルートフォースする必要がある(成功する確率は0.02%)
|
||
|
||
## 攻撃手順
|
||
|
||
### パート1: Fastbinチャンクが\_\_malloc_hookを指す
|
||
|
||
いくつかのチャンクを作成します:
|
||
|
||
- `fastbin_victim` (0x60, オフセット 0): 後でヒープポインタをLibC値を指すように編集するUAFチャンク。
|
||
- `chunk2` (0x80, オフセット 0x70): 良好なアライメントのため。
|
||
- `main_arena_use` (0x80, オフセット 0x100)
|
||
- `relative_offset_heap` (0x60, オフセット 0x190): 'main_arena_use'チャンクの相対オフセット
|
||
|
||
次に`free(main_arena_use)`を実行すると、このチャンクがアンソートリストに配置され、`fd`と`bk`ポインタの両方に`main_arena + 0x68`へのポインタが得られます。
|
||
|
||
今、新しいチャンク`fake_libc_chunk(0x60)`が割り当てられます。これは、`fd`と`bk`に`main_arena + 0x68`へのポインタを含むためです。
|
||
|
||
その後、`relative_offset_heap`と`fastbin_victim`が解放されます。
|
||
```c
|
||
/*
|
||
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_victim` は `relative_offset_heap` を指す `fd` を持っています。
|
||
- `relative_offset_heap` は `fake_libc_chunk` からの距離のオフセットで、`main_arena + 0x68` へのポインタを含んでいます。
|
||
- `fastbin_victim.fd` の最後のバイトを変更することで、`fastbin_victim` が `main_arena + 0x68` を指すようにすることが可能です。
|
||
|
||
前述の操作を行うためには、攻撃者は `fastbin_victim` の fd ポインタを変更できる必要があります。
|
||
|
||
次に、`main_arena + 0x68` はそれほど興味深くないので、ポインタを **`__malloc_hook`** を指すように変更しましょう。
|
||
|
||
`__memalign_hook` は通常 `0x7f` で始まり、その前にゼロが続くため、`0x70` のファストビン内の値として偽装することが可能です。アドレスの最後の4ビットは **ランダム** であるため、興味のある場所に最終的に指す値の可能性は `2^4=16` です。したがって、ここで BF 攻撃が行われ、チャンクは次のようになります: **`0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23)`**。
|
||
|
||
(残りのバイトについての詳細は、[how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[の例](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)の説明を確認してください)。BF が機能しない場合、プログラムは単にクラッシュします(動作するまで再試行してください)。
|
||
|
||
その後、2つの malloc が実行され、最初の2つのファストビンチャンクが削除され、3つ目が **`__malloc_hook:`** にチャンクを取得するために割り当てられます。
|
||
```c
|
||
malloc(0x60);
|
||
malloc(0x60);
|
||
uint8_t* malloc_hook_chunk = malloc(0x60);
|
||
```
|
||
### Part 2: Unsorted_bin 攻撃
|
||
|
||
詳細については、次を確認できます:
|
||
|
||
{{#ref}}
|
||
unsorted-bin-attack.md
|
||
{{#endref}}
|
||
|
||
基本的には、`chunk->bk`で指定された任意の場所に`main_arena + 0x68`を書き込むことを可能にします。そして、攻撃のために`__malloc_hook`を選択します。その後、上書きした後に相対的な上書きを使用して`one_gadget`を指すようにします。
|
||
|
||
これを行うために、チャンクを取得し、**unsorted bin**に入れ始めます:
|
||
```c
|
||
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);
|
||
```
|
||
このチャンクでUAFを使用して、`unsorted_bin_ptr->bk`を`__malloc_hook`のアドレスにポイントします(これは以前にブルートフォースしました)。
|
||
|
||
> [!CAUTION]
|
||
> この攻撃は未整理ビンを破損させることに注意してください(したがって小と大も)。したがって、**今はファストビンからの割り当てのみを使用できます**(より複雑なプログラムは他の割り当てを行い、クラッシュする可能性があります)、そしてこれをトリガーするためには、**同じサイズを割り当てる必要があります。さもなければプログラムはクラッシュします。**
|
||
|
||
したがって、`__malloc_hook`に`main_arena + 0x68`の書き込みをトリガーするために、`unsorted_bin_ptr->bk`に`__malloc_hook`を設定した後、単に**`malloc(0x80)`**を実行する必要があります。
|
||
|
||
### ステップ3: \_\_malloc_hookをsystemに設定
|
||
|
||
ステップ1では、`__malloc_hook`を含むチャンクを制御することができ(変数`malloc_hook_chunk`内)、ステップ2ではここに`main_arena + 0x68`を書き込むことに成功しました。
|
||
|
||
今、`malloc_hook_chunk`内の部分的な上書きを悪用して、そこに書き込んだlibcアドレス(`main_arena + 0x68`)を**`one_gadget`アドレスにポイントさせます**。
|
||
|
||
ここで**12ビットのランダム性をブルートフォースする必要があります**(詳細は[how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[の例](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)を参照してください)。
|
||
|
||
最後に、正しいアドレスが上書きされたら、**`malloc`を呼び出して`one_gadget`をトリガーします**。
|
||
|
||
## 参考文献
|
||
|
||
- [https://github.com/shellphish/how2heap](https://github.com/shellphish/how2heap)
|
||
- [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c](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/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_roman/)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|