11 KiB
Unsorted Bin Attack
{% hint style="success" %}
AWSハッキングの学習と練習:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングの学習と練習:HackTricks Training GCP Red Team Expert (GRTE)
HackTricksをサポートする
- サブスクリプションプランをチェック!
- 💬 Discordグループに参加するか、telegramグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricks](https://github.com/carlospolop/hacktricks)とHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
基本情報
アンソートされたリストは、チャンクのbk
アドレスにunsorted_chunks (av)
のアドレスを書き込むことができます。したがって、攻撃者がアンソートされたビン内のチャンクのbk
ポインタのアドレスを変更できる場合、任意のアドレスにそのアドレスを書き込むことができる可能性があり、これはGlibcアドレスをリークしたり、いくつかの防御をバイパスするのに役立つかもしれません。
したがって、基本的にこの攻撃は、任意のアドレスに大きな数値を設定することを可能にします。この大きな数値はアドレスであり、ヒープアドレスまたはGlibcアドレスである可能性があります。典型的なターゲットは**global_max_fast
**であり、これにより、より大きなサイズの高速ビンビンを作成できるようになります(アンソートされたビン攻撃から高速ビン攻撃に移行できます)。
{% hint style="success" %}
https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principleで提供された例を見て、0x400と0x500の代わりに0x4000と0x5000を使用して(Tcacheを回避するため)、現在エラー**malloc(): unsorted double linked list corrupted
**がトリガーされることがわかります。
したがって、このアンソートされたビン攻撃は(他のチェックと共に)ダブルリンクリストを修正できる必要があるため、これがバイパスされるようにする必要があります。victim->bk->fd == victim
またはvictim->fd == av (arena)
、つまり、書き込みたいアドレスは、そのfd
位置に偽のチャンクのアドレスを持ち、偽のチャンクのfd
がアリーナを指している必要があります。
{% endhint %}
{% hint style="danger" %} この攻撃はアンソートされたビン(小さなビンと大きなビンも)を破壊します。したがって、今後は高速ビンからの割り当てのみを使用できます(より複雑なプログラムは他の割り当てを行い、クラッシュする可能性があります)、これをトリガーするには同じサイズを割り当てる必要があります。
**global_max_fast
**を上書きすると、この場合に役立つかもしれません。高速ビンが完了するまで他のすべての割り当てを処理できるようになります。
{% endhint %}
guyinatuxedoのコードは非常にわかりやすく説明していますが、mallocを変更してTcacheに終わらないように十分なメモリを割り当てると、先に述べたエラーが発生し、このテクニックが防がれます:malloc(): unsorted double linked list corrupted
アンソートされたビン情報リーク攻撃
これは実際には非常に基本的な概念です。アンソートされたビン内のチャンクにはポインタがあります。アンソートされたビン内の最初のチャンクは、fd
とbk
リンクがメインアリーナ(Glibc)の一部を指すようになります。
したがって、アンソートされたビン内にチャンクを配置し、それを読み取る(使用後に解放)か、少なくとも1つのポインタを上書きせずに再度割り当てしてから読み取ることができれば、Glibc情報リークを得ることができます。
このライトアップで使用された攻撃は、4つのチャンク構造(A、B、C、D - Dはトップチャンクとの統合を防ぐためだけ)を悪用し、Bのヌルバイトオーバーフローを使用してCにBが未使用であることを示すようにしました。また、Bでは、prev_size
データが変更され、サイズがBのサイズではなくA+Bになりました。
その後、Cが解放され、A+Bと統合されました(ただし、Bはまだ使用中でした)。サイズAの新しいチャンクが割り当てられ、その後、リークしたlibcアドレスがBに書き込まれ、そこからリークされました。
参照およびその他の例
- https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap
- グローバル変数を4869より大きい値で上書きすることが目標であり、PIEが有効になっていない。
- 任意のサイズのチャンクを生成し、望ましいサイズのヒープオーバーフローが発生します。
- 攻撃は、3つのチャンクを作成して開始します:オーバーフローを悪用するためのchunk0、オーバーフローされるchunk1、前のチャンクが統合されないようにするためのchunk2。
- 次に、chunk1が解放され、chunk0がオーバーフローされ、chunk1の
bk
ポインタがbk = magic - 0x10
を指すようになります。 - 次に、chunk3がchunk1と同じサイズで割り当てられ、アンソートされたビン攻撃がトリガーされ、グローバル変数の値が変更され、フラグを取得できるようになります。
- https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html
- マージ関数は脆弱であり、渡された両方のインデックスが同じ場合、それに対してreallocし、それを解放してからその解放された領域へのポインタを返すことができます。
- したがって、2つのチャンクが作成されます:chunk0は自分自身とマージされ、トップチャンクと統合されるのを防ぐためのchunk1。その後、マージ関数がchunk0で2回呼び出され、使用後に解放されることになります。
- 次に、**
view
**関数が使用され、インデックス2(使用後に解放されたチャンクのインデックス)が呼び出され、libcアドレスが漏洩します。 - バイナリは**
global_max_fast
より大きいサイズのmallocのみを許可する保護を持っているため、fastbinは使用されず、アンソートされたビン攻撃が使用されてglobal_max_fastを上書き**し、global_max_fast-0x10
を指すようにbk
ポインタを上書きすることが可能です。その後、以前に侵害された解放アドレス(0x20)を使用して新しいチャンクを作成すると、アンソートされたビン攻撃がトリガーされ、global_max_fast
が非常に大きな値で上書きされ、今後は高速ビンでチャンクを作成できるようになります。 - 今度は高速ビン攻撃が実行されます:
- まず、**
__free_hook
の場所でサイズ200の高速チャンクを操作できることがわかります: -
gef➤ p &__free_hook
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook>
gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200
</strong>0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
</code></pre>
* もし、この場所にサイズが0x200の高速チャンクを取得できれば、実行される関数ポインタを上書きすることが可能になります
* そのために、サイズが`0xfc`の新しいチャンクが作成され、そのポインタでマージされた関数が2回呼び出され、これによりサイズが`0xfc*2 = 0x1f8`の解放されたチャンクへのポインタが高速ビンに得られます。
* 次に、このチャンクで編集関数が呼び出され、この高速ビンの**`fd`**アドレスを以前の**`__free_hook`**関数を指すように変更します。
* その後、サイズが`0x1f8`のチャンクが作成され、高速ビンから以前の無効なチャンクを取得するために、もう1つのサイズが`0x1f8`のチャンクが作成され、**`__free_hook`**に高速ビンチャンクを取得し、**`system`**関数のアドレスで上書きされます。
* 最後に、文字列`/bin/sh\x00`を含むチャンクが削除関数を呼び出して解放され、**`__free_hook`**関数がトリガーされ、`/bin/sh\x00`をパラメータとして指すsystemにポイントされます。
* **CTF** [**https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw19\_traveller/index.html**](https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw19\_traveller/index.html)
* アンソートビンでチャンクを統合し、libc情報リークを取得し、その後ファストビンアタックを実行してmallocフックをワンガジェットアドレスで上書きする1Bのオーバーフローを悪用する別の例
* [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/)
* サイズが`0x100`より大きいチャンクのみを割り当てることができます。
* アンソートビンアタックを使用して`global_max_fast`を上書きします(ASLRのため1/16回しか機能しません。12ビットを変更する必要がありますが、16ビットを変更する必要があります)。
* グローバルなチャンク配列を変更するためのファストビンアタック。これにより、任意の読み取り/書き込み原始が得られ、GOTを変更していくつかの関数を`system`にポイントすることができます。