hacktricks/binary-exploitation/heap/house-of-force.md

73 lines
7.7 KiB
Markdown
Raw Normal View History

# フォースハウス
<details>
<summary><strong>htARTEHackTricks AWS Red Team Expert</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>を使って、ゼロからヒーローまでAWSハッキングを学ぶ</strong></a><strong></strong></summary>
HackTricks をサポートする他の方法:
* **HackTricks で企業を宣伝したい** または **HackTricks をPDFでダウンロードしたい** 場合は [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop) をチェックしてください!
* [**公式PEASSHackTricksスワッグ**](https://peass.creator-spring.com)を手に入れる
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family) を発見し、独占的な [**NFTs**](https://opensea.io/collection/the-peass-family) のコレクションを見つける
* **💬 [**Discordグループ**](https://discord.gg/hRep4RUj7f) に参加するか、[**telegramグループ**](https://t.me/peass) に参加するか、**Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live) をフォローする**
* **ハッキングテクニックを共有するために、** [**HackTricks**](https://github.com/carlospolop/hacktricks) と [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) のGitHubリポジトリにPRを提出する
</details>
## 基本情報
### コード
* このテクニックはパッチされました([**こちら**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=30a17d8c95fbfb15c52d1115803b63aaa73a285c) そしてこのエラーを生成します: `malloc(): corrupted top size`
* テストしたい場合は、[**こちらからコードを取得**](https://guyinatuxedo.github.io/41-house\_of\_force/house\_force\_exp/index.html) できます。
### ゴール
* この攻撃の目標は、特定のアドレスにチャンクを割り当てることです。
### 必要条件
* ヘッダーのトップチャンクサイズを上書きできるオーバーフロー(例: -1
* ヒープ割り当てのサイズを制御できること
### 攻撃
攻撃者が特定のアドレスPにチャンクを割り当てて値を上書きしたい場合、まずトップチャンクサイズを `-1` で上書きしますおそらくオーバーフローを使用。これにより、malloc がトップチャンクをその位置に移動させるため、mmap を使用しないことが保証されます。
次に、トップチャンクのアドレスと割り当てるターゲットスペースの間の距離を計算します。このサイズでmallocが実行されるため、トップチャンクがその位置に移動されます。差分/サイズを簡単に計算できるのはこのためです:
```c
// From https://github.com/shellphish/how2heap/blob/master/glibc_2.27/house_of_force.c#L59C2-L67C5
/*
* The evil_size is calulcated as (nb is the number of bytes requested + space for metadata):
* new_top = old_top + nb
* nb = new_top - old_top
* req + 2sizeof(long) = new_top - old_top
* req = new_top - old_top - 2sizeof(long)
* req = target - 2sizeof(long) - old_top - 2sizeof(long)
* req = target - old_top - 4*sizeof(long)
*/
```
したがって、`target - old_top - 4*sizeof(long)`のサイズをアロケートすること4つのlongは、トップチャンクと新しいチャンクのメタデータのためですにより、トップチャンクを上書きしたいアドレスに移動させることができます。\
その後、データの先頭にあるチャンクを含むチャンクを取得するために別のmallocを行います。
### 参考文献と他の例
* [https://github.com/shellphish/how2heap/tree/master](https://github.com/shellphish/how2heap/tree/master?tab=readme-ov-file)
* [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_force/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_force/)
* [https://heap-exploitation.dhavalkapil.com/attacks/house\_of\_force](https://heap-exploitation.dhavalkapil.com/attacks/house\_of\_force)
* [https://github.com/shellphish/how2heap/blob/master/glibc\_2.27/house\_of\_force.c](https://github.com/shellphish/how2heap/blob/master/glibc\_2.27/house\_of\_force.c)
* [https://guyinatuxedo.github.io/41-house\_of\_force/house\_force\_exp/index.html](https://guyinatuxedo.github.io/41-house\_of\_force/house\_force\_exp/index.html)
* [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_force/#hitcon-training-lab-11](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_force/#hitcon-training-lab-11)
* このシナリオの目標は、ret2winであり、呼び出される関数のアドレスをret2win関数のアドレスに変更する必要があります
* バイナリには、トップチャンクのサイズを変更できるオーバーフローがあり、これを-1またはp64(0xffffffffffffffff)に変更します
* 次に、上書きするポインタが存在する場所へのアドレスが計算され、現在のトップチャンクの位置からそこまでの差が`malloc`でアロケートされます
* 最後に、この望ましいターゲットを含む新しいチャンクがアロケートされ、ret2win関数によって上書きされます
* [https://shift--crops-hatenablog-com.translate.goog/entry/2016/03/21/171249?\_x\_tr\_sl=es&\_x\_tr\_tl=en&\_x\_tr\_hl=en&\_x\_tr\_pto=wapp](https://shift--crops-hatenablog-com.translate.goog/entry/2016/03/21/171249?\_x\_tr\_sl=es&\_x\_tr\_tl=en&\_x\_tr\_hl=en&\_x\_tr\_pto=wapp)
* `Input your name:`には、ヒープからアドレスをリークさせる初期の脆弱性があります
* 次に、`Org:`および`Host:`機能では、**org name**として求められる64Bの`s`ポインタを埋めることができ、スタック上では`v2`のアドレスが続き、その後に指定された**host name**が続きます。その後、strcpyがsの内容をサイズ64Bのチャンクにコピーしようとするため、**host name**に入れられたデータでトップチャンクのサイズを**上書き**することができます。
* 今、任意の書き込みが可能になったので、`atoi`のGOTをprintfのアドレスに上書きしました。`%24$p`で`IO_2_1_stderr`のアドレスをリークさせることができ、このlibcリークを使用して`atoi`のGOTを再度`system`のアドレスに上書きし、パラメータとして`/bin/sh`を渡して呼び出すことができました。
* [この他の解説で提案されている代替方法](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_force/#2016-bctf-bcloud)は、`free`を`puts`で上書きし、後で解放されるポインタに`atoi@got`のアドレスを追加してリークさせ、このリークを使用して再度`atoi@got`を`system`で上書きし、`/bin/sh`で呼び出すことができます。
* [https://guyinatuxedo.github.io/41-house\_of\_force/bkp16\_cookbook/index.html](https://guyinatuxedo.github.io/41-house\_of\_force/bkp16\_cookbook/index.html)
* ポインタをクリアせずに解放されたチャンクを再利用できるUAFがあります。いくつかの読み取りメソッドがあるため、ここでGOTに解放関数へのポインタを書き込み、その後read関数を呼び出すことでlibcアドレスをリークさせることができます。
* 次に、UAFを悪用して、左側のスペースのサイズを-1で上書きし、解放フックに到達するのに十分な大きさのチャンクを割り当て、その後、解放フックを含む別のチャンクを割り当てます。その後、フックに`system`のアドレスを書き込み、チャンクに`"/bin/sh"`を書き込み、最後にその文字列内容でチャンクを解放します。