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

74 lines
7.5 KiB
Markdown
Raw Permalink Normal View History

# フォースハウス
{% hint style="success" %}
AWSハッキングの学習と練習:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
GCPハッキングの学習と練習: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>HackTricksのサポート</summary>
* [**サブスクリプションプラン**](https://github.com/sponsors/carlospolop)をチェック!
* 💬 [**Discordグループ**](https://discord.gg/hRep4RUj7f)に参加するか、[**telegramグループ**](https://t.me/peass)に参加するか、**Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**をフォロー**してください。
* **HackTricks**と**HackTricks Cloud**のGitHubリポジトリにPRを提出して**ハッキングトリックを共有**してください。
</details>
{% endhint %}
## 基本情報
### コード
* このテクニックは修正されました ([**こちら**](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**を求められたときに`s`ポインタの64Bを埋めることができ、スタック上では`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にfree関数へのポインタを書き込み、その後read関数を呼び出すことでlibcアドレスをリークさせることができます。
* 次に、UAFを悪用してHouse of forceを使用して、左側のスペースのサイズを-1で上書きし、freeフックに到達するのに十分な大きさのチャンクを割り当て、その後、freeフックを含む別のチャンクを割り当てます。その後、フックに`system`のアドレスを書き込み、チャンクに`"/bin/sh"`を書き込み、最後にその文字列内容でチャンクを解放します。