Stack Overflow

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

What is a Stack Overflow

スタックオーバーフローは、プログラムがスタックに割り当てられたよりも多くのデータを書き込むときに発生する脆弱性です。この余分なデータは隣接するメモリ空間を上書きし、正当なデータの破損、制御フローの混乱、そして潜在的には悪意のあるコードの実行を引き起こします。この問題は、入力に対して境界チェックを行わない安全でない関数の使用によってしばしば発生します。

この上書きの主な問題は、保存された命令ポインタ (EIP/RIP)保存されたベースポインタ (EBP/RBP) が前の関数に戻るためにスタックに保存されていることです。したがって、攻撃者はそれらを上書きし、プログラムの実行フローを制御できるようになります。

この脆弱性は通常、関数がスタックに割り当てられた量よりも多くのバイトをコピーするために発生し、したがってスタックの他の部分を上書きすることができます。

この脆弱性に対して一般的な関数には、strcpy, strcat, sprintf, getsなどがあります。また、fgetsread & memcpyのように長さ引数を取る関数も、指定された長さが割り当てられたものより大きい場合に脆弱な方法で使用される可能性があります。

例えば、以下の関数は脆弱である可能性があります:

c
void vulnerable() {
char buffer[128];
printf("Enter some text: ");
gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}

スタックオーバーフローのオフセットを見つける

スタックオーバーフローを見つける最も一般的な方法は、非常に大きな入力の As を与えることです(例: python3 -c 'print("A"*1000)')そして、アドレス 0x41414141 にアクセスしようとしたことを示す Segmentation Fault を期待します

さらに、スタックオーバーフローの脆弱性があることがわかったら、リターンアドレスを上書きするために必要なオフセットを見つける必要があります。これには通常、De Bruijn シーケンスが使用されます。これは、サイズ k のアルファベットと長さ n の部分列に対して、長さ n のすべての可能な部分列がちょうど一度だけ連続した部分列として現れる循環シーケンスです。

この方法により、手動で EIP を制御するために必要なオフセットを特定する代わりに、これらのシーケンスの1つをパディングとして使用し、上書きされたバイトのオフセットを見つけることが可能です。

これには pwntools を使用することができます:

python
from pwn import *

# Generate a De Bruijn sequence of length 1000 with an alphabet size of 256 (byte values)
pattern = cyclic(1000)

# This is an example value that you'd have found in the EIP/IP register upon crash
eip_value = p32(0x6161616c)
offset = cyclic_find(eip_value)  # Finds the offset of the sequence in the De Bruijn pattern
print(f"The offset is: {offset}")

または GEF:

bash
#Patterns
pattern create 200 #Generate length 200 pattern
pattern search "avaaawaa" #Search for the offset of that substring
pattern search $rsp #Search the offset given the content of $rsp

スタックオーバーフローの悪用

オーバーフロー中(オーバーフローサイズが十分大きいと仮定すると)、スタック内のローカル変数の値を上書きすることができ、保存されたEBP/RBPおよびEIP/RIP(またはそれ以上)に達することができます。
この種の脆弱性を悪用する最も一般的な方法は、戻りアドレスを変更することで、関数が終了すると
制御フローがユーザーが指定したポインタの場所にリダイレクトされる
ことです。

しかし、他のシナリオでは、スタック内のいくつかの変数の値を上書きするだけで悪用が可能な場合もあります(簡単なCTFチャレンジのように)。

Ret2win

この種のCTFチャレンジでは、バイナリ内に 決して呼び出されない 関数があり、勝つために呼び出す必要があります。これらのチャレンジでは、戻りアドレスを上書きするオフセットを見つけ、呼び出す関数のアドレスを見つけるだけで済みます(通常、ASLRは無効になります)ので、脆弱な関数が戻ると、隠れた関数が呼び出されます:

Ret2win

スタックシェルコード

このシナリオでは、攻撃者はスタックにシェルコードを配置し、制御されたEIP/RIPを悪用してシェルコードにジャンプし、任意のコードを実行することができます:

Stack Shellcode

ROP & Ret2... テクニック

このテクニックは、前のテクニックの主要な保護を回避するための基本的なフレームワークです:実行可能なスタックなし(NX)。そして、バイナリ内の既存の命令を悪用して任意のコマンドを実行する他のいくつかのテクニック(ret2lib、ret2syscall...)を実行することを可能にします:

ROP - Return Oriented Programing

ヒープオーバーフロー

オーバーフローは常にスタック内で発生するわけではなく、例えばヒープ内で発生することもあります:

Heap Overflow

保護の種類

脆弱性の悪用を防ぐためのいくつかの保護があります。詳細は以下を確認してください:

Common Binary Exploitation Protections & Bypasses

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