Stack Overflow

htARTE(HackTricks AWS Red Team Expert) を通じて、ゼロからヒーローまでAWSハッキングを学ぶ

HackTricks をサポートする他の方法:

スタックオーバーフローとは

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

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

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

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

たとえば、次の関数は脆弱な可能性があります:

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

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

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

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

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

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

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

#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は無効になっている)、脆弱な関数が戻るときには、隠された関数が呼び出されます:

pageRet2win

スタックシェルコード

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

pageStack Shellcode

ROPおよびRet2...テクニック

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

pageROP - Return Oriented Programing

ヒープオーバーフロー

オーバーフローが必ずしもスタックにあるわけではなく、ヒープにあることもあります。例えば:

pageHeap Overflow

保護の種類

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

pageCommon Binary Exploitation Protections & Bypasses

Last updated