単純なスタックオーバーフローの脆弱性を利用しようとしています。私はcに基本的なコードがあります:
#include <cstring>
int main( int argc, char** argv )
{
char buffer[500];
strcpy(buffer, argv[1]);
return 0;
}
-fno-stack-protector
を使用してコンパイル。バッファの長さはすでにわかっており、EBPおよびEIPレジスタを正常に上書きしました。大量のNOPを挿入し、続いて このシェルコード を挿入して、最後に、挿入されたNOPがあるアドレスを挿入してコードを実行しました。
今問題。添付の画像では、gdbの出力を確認できます。悪意のある入力でプログラムを実行すると、SIGSEGVが表示されます。アドレス0xbffff880
をダンプすると、多くのNOPの後にシェルコード(ピンク色のボックス)が続き、最後にアドレス(青色のボックス)が続きます。
これは次のように機能すると考えていました。最初は0x90909090
sとシェルコードは単純なデータと見なされます。これらの後に(ピンク色のボックスを過ぎて)アドレス0xbffff880
があります。私はcpuに「ちょっと、今、0xbffff880
の内容を実行してください」と言っています。 cpuはアドレスの内容を取得し、すべてのNOPとシェルコード自体を実行します。しかし、それは起こっておらず、SIGSEGVが発生します。
どこが間違っているのですか?
ASLRがオフになっている32ビットUbuntu 14.04 Linux 3.13.0-39-generic i686のVirtualboxインスタンスでこれを達成しようとしています。
メモリアドレス_0xbffff880
_は実行できない可能性がありますが、読み取り/書き込みのみです。これを克服する方法はいくつかあります。
-z execstack
_を使用できます。これにより、基本的にスタックメモリ全体が実行可能になります。たとえば、次の行はアドレス_0xbffff880
_を読み取り/書き込み/実行可能としてマークします。
mprotect((void*) 0xbffff880, buffer_len, PROT_READ | PROT_WRITE | PROT_EXEC);
_-fno-stack-protector
_ は、スタックが実行可能であることを意味しません。カナリアや スタックCookie などの他のセキュリティ機能を無効にするだけです。チェック時にこれらの値が上書きされると(バッファオーバーフローにより)、プログラムは失敗します。これはではなくあなたのバッファの実行を可能にします。
RoraZが言ったように、スタックは実行可能ではありません。さらに詳しく言えば、バイナリがそのような悪意を許容するようにコンパイルされていない限り、そのようなバッファオーバーフローエクスプロイトは最新のLinuxボックスでは機能しません。多くのセキュリティ機能を無効にする必要があります。 RELRO、STACK CANARY、NX、PIE。
Checksec.sh( http://www.trapkit.de/tools/checksec.html )と呼ばれるnice bashスクリプトがあり、バイナリのチェックに役立ちます。次に例を示します。
X86バッファーオーバーフローテスト用にバイナリをコンパイルする方法:
gcc -m32 -g -mpreferred-stack-boundary=2 -no-pie -fno-stack-protector -Wl,-z,norelro -z execstack ./program.c
そして便宜のために:
-g:デバッグを追加
-mpreferred-stack-bounary = 2:スタックを4バイト境界に揃えます