House of Orange

Reading time: 10 minutes

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をサポートする

基本情報

コード

目標

  • malloc_printerr 関数を悪用する

要件

  • トップチャンクサイズを上書きする
  • Libc とヒープのリーク

背景

この例からの必要な背景:

古いバージョンの libc では、malloc_printerr 関数が呼び出されると、_IO_list_all に格納された _IO_FILE 構造体のリストを反復処理し、実際にその構造体内の命令ポインタを実行していました。
この攻撃では、偽の _IO_FILE 構造体を作成し、_IO_list_all に書き込み、malloc_printerr を実行させます。
その後、_IO_FILE 構造体のジャンプテーブルに格納された任意のアドレスを実行し、コード実行を得ることができます。

攻撃

攻撃は、未ソートビン内のトップチャンクを取得することから始まります。これは、現在のトップチャンクサイズより大きいが、mmp_.mmap_threshold(デフォルトは128K)より小さいサイズで malloc を呼び出すことで達成されます。そうしないと、mmap アロケーションがトリガーされます。トップチャンクサイズが変更されるときは、トップチャンク + サイズがページアラインされていること、そしてトップチャンクのprev_inuseビットが常に設定されていることを確認することが重要です。

未ソートビン内のトップチャンクを取得するには、トップチャンクを作成するためにチャンクを割り当て、トップチャンクサイズを変更(割り当てられたチャンク内のオーバーフローを使用)して、トップチャンク + サイズがページアラインされ、prev_inuseビットが設定されていることを確認します。その後、新しいトップチャンクサイズより大きいチャンクを割り当てます。free は未ソートビンにトップチャンクを取得するために決して呼び出されないことに注意してください。

古いトップチャンクは現在未ソートビンにあります。内部のデータを読み取ることができると仮定すると(おそらくオーバーフローを引き起こした脆弱性のため)、そこから libc アドレスをリークし、_IO_list_all のアドレスを取得することが可能です。

未ソートビン攻撃は、オーバーフローを悪用して topChunk->bk->fwd = _IO_list_all - 0x10 と書き込むことで実行されます。新しいチャンクが割り当てられると、古いトップチャンクが分割され、未ソートビンへのポインタが**_IO_list_all** に書き込まれます。

次のステップは、古いトップチャンクのサイズを小さなビンに収まるように縮小し、特にそのサイズを0x61に設定することです。これには二つの目的があります:

  1. 小さなビン4への挿入: malloc が未ソートビンをスキャンし、このチャンクを見つけると、その小さなサイズのために小さなビン4に挿入しようとします。これにより、チャンクが**_IO_list_all**のFDポインタの位置である小さなビン4リストの先頭に配置されます。
  2. Malloc チェックのトリガー: このチャンクサイズの操作により、malloc が内部チェックを実行します。偽のフォワードチャンクのサイズがゼロであるとき、エラーがトリガーされ、malloc_printerr が呼び出されます。

小さなビンの操作により、チャンクのフォワードポインタを制御できるようになります。_IO_list_allとのオーバーラップを使用して、偽の**_IO_FILE**構造体を作成します。この構造体は、_IO_write_base_IO_write_ptr などの重要なフィールドを含むように慎重に作成され、libc の内部チェックを通過する値に設定されます。さらに、偽の構造体内にジャンプテーブルが作成され、命令ポインタが任意のコード(例:system 関数)を実行できるアドレスに設定されます。

技術の残りの部分を要約すると:

  • 古いトップチャンクを縮小: 古いトップチャンクのサイズを0x61に調整して小さなビンに収めます。
  • 偽の _IO_FILE 構造体を設定: 古いトップチャンクと偽の**_IO_FILE**構造体をオーバーラップさせ、フィールドを適切に設定して実行フローをハイジャックします。

次のステップは、未ソートビンに現在ある古いトップチャンクとオーバーラップする偽の**_IO_FILE**構造体を作成することです。この構造体の最初のバイトは、実行されるコマンド(例:"/bin/sh")へのポインタを含むように慎重に作成されます。

偽の**_IO_FILE**構造体の重要なフィールド、例えば _IO_write_base_IO_write_ptr は、libc の内部チェックを通過する値に設定されます。さらに、偽の構造体内にジャンプテーブルが作成され、命令ポインタが任意のコードを実行できるアドレスに設定されます。通常、これは system 関数のアドレスやシェルコマンドを実行できる他の関数のアドレスになります。

攻撃は、malloc の呼び出しが操作された**_IO_FILE**構造体を通じてコードの実行をトリガーすることで culminates します。これにより、任意のコード実行が可能になり、通常はシェルが生成されるか、他の悪意のあるペイロードが実行されます。

攻撃の要約:

  1. トップチャンクを設定: チャンクを割り当て、トップチャンクサイズを変更します。
  2. トップチャンクを未ソートビンに強制的に入れる: より大きなチャンクを割り当てます。
  3. libc アドレスをリーク: 脆弱性を利用して未ソートビンから読み取ります。
  4. 未ソートビン攻撃を実行: オーバーフローを使用して**_IO_list_all**に書き込みます。
  5. 古いトップチャンクを縮小: 小さなビンに収まるようにサイズを調整します。
  6. 偽の _IO_FILE 構造体を設定: 制御フローをハイジャックするために偽のファイル構造体を作成します。
  7. コード実行をトリガー: チャンクを割り当てて攻撃を実行し、任意のコードを実行します。

このアプローチは、ヒープ管理メカニズム、libc 情報リーク、およびヒープオーバーフローを利用して、free を直接呼び出すことなくコード実行を達成します。偽の**_IO_FILE**構造体を慎重に作成し、適切な位置に配置することで、攻撃は標準のメモリアロケーション操作中に制御フローをハイジャックできます。これにより、任意のコードの実行が可能になり、シェルや他の悪意のある活動が発生する可能性があります。

参考文献

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をサポートする