GDB

2016-09-03 13 views
0

でのテストシェルコード私はちょうどシェルコードプログラムを実行する場合は、このGDB

desktop:~$ ./sh02 
Segmentaion fault (core dumped) 

のようにセグメンテーション違反になります。しかし、私はGDBでこのプログラムをデバッグするときに、このプログラムが実行される/ binに/成功し

(gdb) disass 0x4005a0 
No function contains specified address. 
(gdb) shell ps 
    PID TTY   TIME CMD 
4075 pts/4 00:00:00 bash 
4099 pts/4 00:00:00 gdb 
4101 pts/4 00:00:00 sh 
4107 pts/4 00:00:00 ps 
(gdb) 
shを私はデバッグする前SH02プログラムを介して、/ binに/ shを実行することはできませんなぜ私は

それらの違いを見つけることができませんGDBでデバッグした後、このプログラムはうまく機能

... ギング?

const char str[]= 
"\x55" 
"\x48\x89\xe5" 
"\x48\x31\xff" 
"\x57" 
"\x57" 
"\x5e" 
"\x5a" 
"\x48\xbf\x2f\x2f\x62\x69\x6e" 
"\x2f\x73\x68" 
"\x57" 
"\x54" 
"\x5f" 
"\x6a\x3b" 
"\x58" 
"\x0f\x05" 
"\x90" 
"\x5d" 
"\xc3"; 

int main() 
{ 
    int (*func)(); 

    func = (int (*)()) str; 

    (int)(*func)(); 
} 

上記はsh02.cコードです。

私はその質問と回答を読んだ。しかし、私のケースは少し違うと思います。 GDBを使ったデバッグ中とデバッグ後sh02プログラムは/ bin/shを実行します。しかし唯一、デバッグの前に、それは未定義の動作は、プログラムが(運で)クラッシュクラッシュしたりしないことがあり呼び出されるとセグメンテーションフォールト

が、私はUbuntuの16.04とx64アーキテクチャ

+3

[C-Busエラー10からのテストシェルコード](http://stackoverflow.com/questions/17822771/testing-shellcode-from-c-bus-error-10)または[シェルコードのテスト]( http://stackoverflow.com/questions/2797974/testing-a-shellcode?rq=1) –

+0

私はその質問と回答を読んだ。しかし、私のケースは少し違うと思います。 GDBを使ったデバッグ中とデバッグ後sh02プログラムは/ bin/shを実行します。ただし、デバッグする前にのみ、セグメンテーション・フォールトが発生します。 – Damotorie

+0

上記の内容と重複しているようではありませんが、質問自体は少し曖昧です。私が理解しているのは、なぜプログラムがデバッグモードで実行される前に動作しないのですが、それ以降はうまくいかないかを知りたいのですか? – hotzst

答えて

0

を使用します。プログラムは、execに送られた文字列をnullで終了しません。結果は未定義です。

"\x48\xbf\x2f\x62\x69\x6e" 
"\x2f\x73\x68\x00" 

私は余分な「/」を落とし、文字列の末尾に「\ 0」を追加しました注:

はこれを試してみてください。

gdbを使用して問題を特定できました。

これは、おそらくアセンブリのデバッグを学ぶのに役立つセッションです。

[email protected]:/tmp$ gcc -g -fno-stack-protector -z execstack -o shellcode shellcode2.c 
[email protected]:/tmp$ gdb ./shellcode 
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1 
... 
Reading symbols from ./shellcode...done. 
(gdb) b main 
Breakpoint 1 at 0x4004f5: file shellcode2.c, line 25. 
(gdb) r 
Starting program: /tmp/shellcode 

Breakpoint 1, main() at shellcode2.c:25 
25  func = (int (*)()) str; 
(gdb) n 
27  (int)(*func)(); 
(gdb) stepi 
0x0000000000400501 27  (int)(*func)(); 
(gdb) stepi 
0x0000000000400506 27  (int)(*func)(); 
(gdb) stepi 
0x00000000004005c0 in str() 
(gdb) disass 
Dump of assembler code for function str: 
=> 0x00000000004005c0 <+0>: push %rbp 
    0x00000000004005c1 <+1>: mov %rsp,%rbp 
    0x00000000004005c4 <+4>: xor %rdi,%rdi 
    0x00000000004005c7 <+7>: push %rdi 
    0x00000000004005c8 <+8>: push %rdi 
    0x00000000004005c9 <+9>: pop %rsi 
    0x00000000004005ca <+10>: pop %rdx 
    0x00000000004005cb <+11>: movabs $0x68732f6e69622f2f,%rdi 
    0x00000000004005d5 <+21>: push %rdi 
    0x00000000004005d6 <+22>: push %rsp 
    0x00000000004005d7 <+23>: pop %rdi 
    0x00000000004005d8 <+24>: pushq $0x3b 
    0x00000000004005da <+26>: pop %rax 
    0x00000000004005db <+27>: syscall 
    0x00000000004005dd <+29>: nop 
    0x00000000004005de <+30>: pop %rbp 
    0x00000000004005df <+31>: retq 
    0x00000000004005e0 <+32>: add %al,(%rax) 
End of assembler dump. 
(gdb) b *0x4005db 
Breakpoint 2 at 0x4005db 
(gdb) c 
Continuing. 

Breakpoint 2, 0x00000000004005db in str() 
(gdb) info reg 
rax   0x3b 59 
rbx   0x0 0 
rcx   0x0 0 
rdx   0x0 0 
rsi   0x0 0 
rdi   0x7fffffffdef8 140737488346872 
rbp   0x7fffffffdf00 0x7fffffffdf00 
rsp   0x7fffffffdef8 0x7fffffffdef8 
r8    0x7ffff7dd4e80 140737351863936 
r9    0x7ffff7dea560 140737351951712 
r10   0x7fffffffddb0 140737488346544 
r11   0x7ffff7a36dd0 140737348070864 
r12   0x400400 4195328 
r13   0x7fffffffe000 140737488347136 
r14   0x0 0 
r15   0x0 0 
rip   0x4005db 0x4005db <str+27> 
eflags   0x246 [ PF ZF IF ] 
cs    0x33 51 
ss    0x2b 43 
ds    0x0 0 
es    0x0 0 
fs    0x0 0 
gs    0x0 0 
(gdb) p (char*) $rdi 
$1 = 0x7fffffffdef8 "//bin/sh \337\377\377\377\177" 

ご覧のとおり、文字列には「/」とNULL終端記号がありません。単純な2文字の修正とすべてがうまくいきます。