web-dev-qa-db-ja.com

バッファオーバーフローを悪用するとsegfaultが発生する

単純なスタックオーバーフローの脆弱性を利用しようとしています。私は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の後にシェルコード(ピンク色のボックス)が続き、最後にアドレス(青色のボックス)が続きます。

これは次のように機能すると考えていました。最初は0x90909090sとシェルコードは単純なデータと見なされます。これらの後に(ピンク色のボックスを過ぎて)アドレス0xbffff880があります。私はcpuに「ちょっと、今、0xbffff880の内容を実行してください」と言っています。 cpuはアドレスの内容を取得し、すべてのNOPとシェルコード自体を実行します。しかし、それは起こっておらず、SIGSEGVが発生します。

どこが間違っているのですか?

gdb output

ASLRがオフになっている32ビットUbuntu 14.04 Linux 3.13.0-39-generic i686のVirtualboxインスタンスでこれを達成しようとしています。

22
tsusanka

メモリアドレス_0xbffff880_は実行できない可能性がありますが、読み取り/書き込みのみです。これを克服する方法はいくつかあります。

  1. スタックアドレスの場合は、コンパイル中に_-z execstack_を使用できます。これにより、基本的にスタックメモリ全体が実行可能になります。
  2. より堅牢なソリューションとして、シェルコードを記述して、書き込み先のアドレスで mprotect を呼び出すことができます。

たとえば、次の行はアドレス_0xbffff880_を読み取り/書き込み/実行可能としてマークします。

mprotect((void*) 0xbffff880, buffer_len, PROT_READ | PROT_WRITE | PROT_EXEC);

_-fno-stack-protector_ は、スタックが実行可能であることを意味しません。カナリアや スタックCookie などの他のセキュリティ機能を無効にするだけです。チェック時にこれらの値が上書きされると(バッファオーバーフローにより)、プログラムは失敗します。これはではなくあなたのバッファの実行を可能にします。

24
RoraΖ

RoraZが言ったように、スタックは実行可能ではありません。さらに詳しく言えば、バイナリがそのような悪意を許容するようにコンパイルされていない限り、そのようなバッファオーバーフローエクスプロイトは最新のLinuxボックスでは機能しません。多くのセキュリティ機能を無効にする必要があります。 RELRO、STACK CANARY、NX、PIE。

Checksec.sh( http://www.trapkit.de/tools/checksec.html )と呼ばれるnice bashスクリプトがあり、バイナリのチェックに役立ちます。次に例を示します。

enter image description here

X86バッファーオーバーフローテスト用にバイナリをコンパイルする方法:

gcc -m32 -g -mpreferred-stack-boundary=2 -no-pie -fno-stack-protector -Wl,-z,norelro -z execstack ./program.c
  1. -no-pie:PIE(位置に依存しない実行ファイル)を無効にします
  2. -z execstack:NXを無効にする(スタックを実行可能にする)
  3. -Wl、-z、norelro:RELRO(読み取り専用の再配置)を無効にします
  4. -fno-stack-protector:スタック保護を削除します(スタックオーバーフローセキュリティチェック)

そして便宜のために:

-g:デバッグを追加

-mpreferred-stack-bounary = 2:スタックを4バイト境界に揃えます

1
sf_admin