私はコンピューター セキュリティのクラスを受講していますが、実行可能コードをバッファー オーバーフローに挿入するための追加クレジットが割り当てられています。操作しようとしているターゲット プログラムの C ソース コードがあり、現在の関数スタック フレームの eip を正常に上書きできるところまで来ました。ただし、提供するアドレスが常に間違っているため、常にセグメンテーション違反が発生します。問題は、現在の関数が pthread 内にあるため、スタックのアドレスがプログラムの実行ごとに常に変化しているように見えることです。pthread 内のスタック アドレスを見つける方法 (または pthread 内のスタック アドレスを推定する方法) はありますか? (注: pthread_create の 2 番目の引数は null であるため、手動でスタック アドレスを割り当てていません)
3 に答える
Smashing The Stack For Fun And Profit のバッファ オーバーフロー脆弱性の悪用に関する優れた (少し古い場合) 記事/チュートリアルを読むことをお勧めします。
以下に簡単な抜粋を示します。
問題は、悪用しようとしているコード (およびそれに続く文字列) がプログラムのメモリ空間のどこに配置されるかわからないことです。これを回避する 1 つの方法は、JMP と CALL 命令を使用することです。JMP および CALL 命令は IP 相対アドレス指定を使用できます。つまり、ジャンプ先のメモリ内の正確なアドレスを知らなくても、現在の IP からのオフセットにジャンプできます。
少しインライン アセンブリを使用して、スタック ポインターの現在の値を取得できます。Smashing The Stack For Fun And Profit のすべての例は、 でバッファーmain
をオーバーフローさせますが、pthread から呼び出される関数で同じ手法を使用してバッファーをオーバーフローさせることも簡単にできます。以下のコードは、記事 ( overflow1.c )の例に基づいて構築されており、同じ手法が pthread を使用して機能することを示しています。実際に使用する手法は、悪用しようとしているターゲット プログラムによって異なります。
/* get value of sp off the stack - not essential to example */
unsigned long get_sp()
{
__asm__("movl %esp,%eax"); /* equiv. of 'return esp;' in C */
}
int foo()
{
char buffer[96];
/* overflow buffer to overwrite return address */
/* and place code to be executed into buffer. */
...
return 0;
}
void *thread(void *arg)
{
printf("thread stack 0x%x\n", get_sp());
foo();
return NULL;
}
int main(int argc, char **argv)
{
printf("main stack 0x%x\n", get_sp());
pthread_t t;
pthread_create(&t, NULL, thread, NULL);
pthread_join(t, NULL);
return 0;
}
私の以前の答えに加えて、あなたはまた、以下を読むことをお勧めします:
次の記事では、ヒープオーバーフローに焦点を当てています。
アプリケーションについて詳しく知らなければ、少しわかりにくいですが、最初に頭に浮かぶのはヒープ スプレーです。