Ret2win
基本情報
Ret2win チャレンジは、特に バイナリエクスプロイト を含むタスクにおいて、Capture The Flag (CTF) コンペティションで人気のあるカテゴリーです。目的は、特定の未呼び出しの関数を実行するために、与えられたバイナリ内の脆弱性を悪用することです。この関数は通常、win
、flag
などの名前が付けられています。この関数が実行されると、通常はフラグや成功メッセージが出力されます。チャレンジは通常、スタック上の リターンアドレス を上書きして、実行フローを目的の関数に転送することを含みます。以下は、例を交えた詳細な説明です。
Cの例
脆弱性を持つシンプルなCプログラムと、呼び出すことを意図している win
関数を考えてみましょう:
このプログラムをスタック保護なしで、ASLR を無効にしてコンパイルするには、次のコマンドを使用できます:
-m32
: プログラムを32ビットバイナリとしてコンパイルします(これはオプションですが、CTFチャレンジでは一般的です)。-fno-stack-protector
: スタックオーバーフローに対する保護を無効にします。-z execstack
: スタック上のコードの実行を許可します。-no-pie
: 位置独立実行可能ファイルを無効にして、win
関数のアドレスが変更されないようにします。-o vulnerable
: 出力ファイルの名前をvulnerable
にします。
Python Exploit using Pwntools
エクスプロイトには、エクスプロイトを書くための強力なCTFフレームワークであるpwntoolsを使用します。エクスプロイトスクリプトは、バッファをオーバーフローさせ、戻りアドレスをwin
関数のアドレスで上書きするペイロードを作成します。
win
関数のアドレスを見つけるには、gdb、objdump、またはバイナリファイルを検査できる他のツールを使用できます。例えば、objdump
を使用して次のようにできます:
このコマンドは、win
関数のアセンブリを表示し、その開始アドレスを含みます。
Python スクリプトは、vulnerable_function
によって処理されると、バッファをオーバーフローさせ、スタック上のリターンアドレスを win
のアドレスで上書きするように巧妙に作成されたメッセージを送信します。vulnerable_function
が戻ると、main
に戻るのではなく、win
にジャンプし、メッセージが表示されます。
保護
PIE は無効にするべきです。そうしないと、アドレスが実行ごとに信頼できなくなり、関数が格納されるアドレスが常に同じではなくなり、
win
関数がどこにロードされているかを把握するために何らかの leak が必要になります。オーバーフローを引き起こす関数がread
やそれに類似するものである場合、リターンアドレスをwin
関数に変更するために 1 または 2 バイトの 部分上書き を行うことができます。ASLR の動作のため、最後の 3 つの16進数ニブルはランダム化されないため、正しいリターンアドレスを取得する確率は 1/16(1 ニブル)です。スタックカナリア も無効にするべきです。そうしないと、侵害された EIP リターンアドレスは決して追跡されません。
その他の例と参考文献
32ビット、ASLRなし
ASLRありの64ビット、バイナリアドレスの leak あり
64ビット、ASLRなし
32ビット、ASLRなし、ダブル小オーバーフロー、最初にスタックをオーバーフローさせ、2回目のオーバーフローのサイズを拡大
32ビット、relro、カナリアなし、nx、pieなし、
fflush
のアドレスをwin
関数(ret2win)で上書きするフォーマット文字列32ビット、nx、他に何もなし、
win
関数を呼び出すための EIP の部分上書き(1バイト)32ビット、nx、他に何もなし、
win
関数を呼び出すための EIP の部分上書き(1バイト)プログラムは、入力のサイズをチェックするために数値の最後のバイトのみを検証しているため、最後のバイトが許可された範囲内であれば、任意のサイズを追加することが可能です。その後、入力は ret2win を利用したバッファオーバーフローを引き起こします。
64ビット、relro、カナリアなし、nx、pie。
win
関数(ret2win)を呼び出すための部分上書きarm64、PIE、
win
関数は実際には 2 つの関数であるため、2 つの関数を呼び出す ROP ガジェットARM64、オフバイワンで
win
関数を呼び出す
ARM64 の例
Ret2win - arm64Last updated