「バッファ オーバーフロー攻撃」 (p. 248) の本から直接引用した、Linux のヒープ バッファ オーバーフローの脆弱なプログラムの例を考えてみましょう。
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
char *A, *B;
A = malloc(128);
B = malloc(32);
strcpy(A, argv[1]);
free(A);
free(B);
return 0;
}
unlink() は、FD および BK ポインタをサニティ チェックで使用する最も単純な形式のエクスプロイトを防止するように変更されているため、古いバージョンの glibc (バージョン 2.3.2) で使用している非常に古いシステムを使用しています。このテストでは、MALLOC_CHECK_=0 も設定しています。
このおもちゃの例の目的は、指定した任意のアドレスに 4 バイトを書き込めるかどうかを単純に確認することです。私が考えることができる最も簡単なテストは、0x41414141 に何かを書き込もうとすることです。これは不正なアドレスであり、プログラムをクラッシュさせて、実際にこのアドレスに書き込もうとしていることを確認する必要があります (何かを観察できるはずです)。 GDB で)。
だから私は引数で実行しようとしますperl -e 'print "A"x128 . "\xf8\xff\xff\xff" . "\xf8\xff\xff\xff" . "\x41\x41\x41\x41" . "\x41\x41\x41\x41" '
ので、私は持っています:
Buffer A: 128 bytes of 0x41.
prev_size: 0xfffffff8
size: 0xfffffff8
FD: 0x41414141
BK: 0x41414141
0xfffffffc の代わりに 0xffffffff8 を使用しているのは、glibc 2.3 では 3 番目に低いビット NON_MAIN_AREA がアリーナの管理目的で使用され、0 でなければならないという注意事項があるためです。
これは 0x41414141 から 0x41414141 (より正確には + 12 ですが、それでも不正なアドレスです) を書き込もうとするはずです。正しいですか? しかし、これを実行すると、プログラムは単に正常に終了します。
ここで何が欠けていますか?これは簡単に思えるので、作業に取りかかるのはそれほど難しいことではありません。
prev_size と size の代わりに 0xfffffffc を使用したり、FD に正当なアドレス (ヒープ上のアドレス) を使用したりするなど、さまざまなことを試しました。A と B が free() されている順序を交換しようとしました。GDB で何が起こるかを確認するために free() にステップインしようとしましたが、道に迷ってしまいました。このシステムは非常に古く、NX-bit、ASLR などを備えていないため、このシステムには他のセキュリティ機能があってはならないことに注意してください (4 バイトを不正なアドレスに書き込むだけの目的では問題になりません)。 .
これを機能させる方法についてのアイデアはありますか?
MALLOC_CHECK_=3 を使用すると、次のようになります。
malloc: using debugging hooks
malloc: using debugging hooks
free(): invalid pointer 0x8049688!
Program received signal SIGABRT, Aborted.
0x4004a1b1 in kill () from /lib/libc.so.6