【问题标题】:Testing Shellcode With GDB [duplicate]使用 GDB 测试 Shellcode [重复]
【发布时间】:2017-01-11 05:14:21
【问题描述】:

如果我只是执行shell代码程序它会产生这样的分段错误

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

但是,当我用 GDB 调试这个程序时,这个程序执行 /bin/sh 成功

(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) 

用GDB调试后,这个程序运行良好... 我找不到它们之间的区别

为什么我不能在调试前通过sh02程序运行/bin/sh?

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 架构

【问题讨论】:

  • 我阅读了那个问题和答案。但我认为我的情况有点不同。在使用 GDB 调试期间和调试 sh02 程序后,成功执行 /bin/sh。但是只有在调试之前,它才会导致分段错误。
  • 虽然它似乎不是上面提到的重复,但问题本身有点模糊。我的理解是您想知道为什么程序在以调试模式运行之前无法运行,但之后又可以正常运行?

标签: c segmentation-fault gdb shellcode


【解决方案1】:

当调用未定义的行为时,程序可能会崩溃或不崩溃(靠运气)。程序不会空终止发送给 exec 的字符串,结果是未定义的。

试试这个:

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

请注意,我删除了额外的“/”并在字符串末尾添加了“\0”。

我能够通过使用 gdb 确定问题。

这里是会话,也许这将有助于您学习汇编调试。

parallels@ubuntu:/tmp$ gcc -g  -fno-stack-protector -z execstack -o shellcode shellcode2.c
parallels@ubuntu:/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 终止符。一个简单的两个字符修复,一切都很好。

【讨论】:

    猜你喜欢
    • 2016-12-17
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多