12 KiB
ベーシックバイナリエクスプロイテーション手法
{% 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とHackTricks CloudのGitHubリポジトリにPRを提出して、ハッキングトリックを共有してください。
ELF基本情報
何かをエクスプロイトする前に、ELFバイナリの構造の一部を理解することが興味深いです:
{% content-ref url="elf-tricks.md" %} elf-tricks.md {% endcontent-ref %}
エクスプロイトツール
{% content-ref url="tools/" %} tools {% endcontent-ref %}
スタックオーバーフロー手法
多くのテクニックがあるため、各テクニックがいつ役立つかを把握するスキームを持っていると良いです。同じ保護が異なるテクニックに影響を与えることに注意してください。保護のセクションごとに保護をバイパスする方法を見つけることができますが、この手法ではありません。
フローの制御
プログラムのフローを制御する方法はいくつかあります:
- スタックオーバーフロー:スタックからリターンポインタまたはEBP -> ESP -> EIPを上書きします。
- オーバーフローを引き起こすために整数オーバーフローを悪用する必要があるかもしれません
- または任意の書き込み + 書き込む場所への実行
- フォーマット文字列:
printf
を悪用して、任意のアドレスに任意のコンテンツを書き込みます。 - 配列インデックス:設計が不十分なインデックスを悪用して、いくつかの配列を制御し、任意の書き込みを取得できるようにします。
- オーバーフローを引き起こすために整数オーバーフローを悪用する必要があるかもしれません
- bof to WWW via ROP:バッファオーバーフローを悪用してROPを構築し、WWWを取得できるようにします。
Write What Where to Executionの手法は以下で見つけることができます:
{% content-ref url="../arbitrary-write-2-exec/" %} arbitrary-write-2-exec {% endcontent-ref %}
永続的なループ
考慮すべきことの1つは、通常脆弱性の単一のエクスプロイトだけでは十分でないことです。特にいくつかの保護をバイパスする必要がある場合があります。したがって、単一の脆弱性を同じバイナリの実行中に複数回エクスプロイト可能にするいくつかのオプションを検討することが興味深いです:
- ROPチェーンに**
main
関数のアドレスまたは脆弱性が発生しているアドレス**を書き込む - 適切なROPチェーンを制御することで、そのチェーン内のすべてのアクションを実行できるかもしれません
exit
アドレスをGOT(または終了前にバイナリで使用される他の関数)に書き込んで、脆弱性に戻るアドレスを指定します- .fini_arrayで説明されているように、ここに2つの関数を保存し、脆弱性を再度呼び出すためのものと、
.fini_array
から再度関数を呼び出す**__libc_csu_fini
**を呼び出すためのものを保存します。
エクスプロイトの目標
目標: 既存の関数を呼び出す
- ret2win:呼び出す必要のあるコード内の関数(おそらく特定のパラメータを使用して)があります。
- PIE および canary なしの通常のbofでは、スタックに格納されたリターンアドレスにアドレスを書き込むだけで済みます。
- PIEを使用するbofの場合、バイパスする必要があります
- canaryを使用するbofの場合、バイパスする必要があります
- ret2win関数を正しく呼び出すために複数のパラメータを設定する必要がある場合は、次のようにできます:
- 十分なガジェットがある場合は、ROP チェーンを使用してすべてのパラメータを準備します
- SROP(このシステムコールを呼び出すことができる場合)を使用して、多くのレジスタを制御します
- ret2csuおよびret2vdsoからのガジェットを使用して、複数のレジスタを制御します
- Write What Whereを介して、他の脆弱性(bof以外)を悪用して**
win
**関数を呼び出すことができます。 - ポインタのリダイレクト:スタックに関数へのポインタが含まれている場合、そのアドレスを上書きすることができます。
- ASLRまたはPIEはアドレスに影響を与える可能性があります。
- 未初期化変数:わからないことがあります。
目標: RCE
nxが無効になっている場合やシェルコードとROPを混在させる場合:
- (スタック) シェルコード:スタックにシェルコードを保存してから、リターンポインタを上書きする前または後にジャンプして実行します:
- 通常のbofで canaryがある場合、バイパス(リーク)する必要があります
- ASLR および nx なしの場合、スタックのアドレスにジャンプできます(変更されないため)
- **ASLR**がある場合、ret2esp/ret2regなどのテクニックを使用してジャンプする必要があります
- **nx**がある場合、ROPを使用して
memprotect
を呼び出し、ページをrwx
に変更してから(たとえばreadを呼び出して)そこにシェルコードを保存し、そこにジャンプする必要があります。 - これにより、シェルコードがROPチェーンと混在します。
シスコール経由
- Ret2syscall:
execve
を呼び出して任意のコマンドを実行するのに便利です。特定のシスコールを呼び出すためのガジェットを見つける必要があります。 - もしASLRまたはPIEが有効になっている場合、バイナリやライブラリからのROPガジェットを使用するためには、それらを打破する必要があります。
- SROPはret2execveを準備するのに役立ちます。
- ret2csuやret2vdsoから複数のレジスタを制御するためのガジェット
libc経由
- Ret2lib: 通常は**
libc
からの関数(通常はsystem
)を呼び出すのに便利です。準備された引数(例:'/bin/sh'
)と共に。呼び出したい関数を含むライブラリをバイナリがロードする必要があります**。 - 静的にコンパイルされておりPIEがない場合、
system
と/bin/sh
のアドレスは変わらないため、それらを静的に使用できます。 - ASLRが無効で、ロードされたlibcのバージョンを知っている場合、
system
と/bin/sh
のアドレスは変わらないため、それらを静的に使用できます。 - ASLRが有効でもPIEが無い場合、libcを知っていてバイナリが
system
を使用している場合、'/bin/sh'
のアドレスと共に**GOT内のsystemのアドレスにret
**することが可能です(これを解明する必要があります)。 - ASLRが有効でもPIEが無い場合、libcを知っていてバイナリが
system
を使用していない場合: ret2dlresolve
を使用してsystem
のアドレスを解決し、それを呼び出す- ASLRをバイパスして、メモリ内の
system
と'/bin/sh'
のアドレスを計算します。 - ASLRとPIEが有効で、libcを知らない場合:以下が必要です:
- PIEをバイパスする
- 使用されている**
libc
バージョン**を見つける(いくつかの関数アドレスをリークさせる) - 続行するためにASLRの前述のシナリオを確認します。
EBP/RBP経由
- Stack Pivoting / EBP2Ret / EBP Chaining: スタック内の保存されたEBPを介してESPを制御してRETを制御します。
- オフバイワンスタックオーバーフローに便利
- EIPを制御する代替方法として役立ち、EIPを悪用してメモリ内でペイロードを構築し、それをEBP経由でジャンプする方法
その他
- Pointers Redirecting: スタックに呼び出される関数へのポインタや、興味深い関数(systemやprintf)で使用される文字列へのポインタが含まれている場合、そのアドレスを上書きすることが可能です。
- ASLRまたはPIEがアドレスに影響を与える可能性があります。
- 未初期化変数: 決してわかりません