接下来,我们将在上文的基础上,进一步完善shellcode的提取。
前面关于main和execve的分析,同“基本shellcode提取方法”中相应部分的讲解。
如果execve()调用失败的话,程序将会继续从堆栈中获取指令并执行,而此时堆栈中的数据时随机的,通常这个程序会core dump。如果我们希望在execve()调用失败时,程序仍然能够正常退出,那么我们就必须在execve()调用之后增加一个exit系统调用。它的C语言程序如下:
root@linux:~/pentest# cat shellcode_exit.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
exit(0);
}
root@linux:~/pentest# gdb shellcode_exit
GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/pentest/shellcode_exit...done.
(gdb) disass exit
Dump of assembler code for function exit@plt:
0x080482f0 <+0>: jmp *0x804a008
0x080482f6 <+6>: push {1}x10
0x080482fb <+11>: jmp 0x80482c0
End of assembler dump.
(gdb)
通过gdb反汇编可以看到现在的gcc编译器向我们隐藏了exit系统调用的实现细节。但是,通过翻阅以前版本gdb反汇编信息,仍然可以得到exit系统调用的实现细节。
[scz@ /home/scz/src]> gdb shellcode_exit
GNU gdb 4.17.0.11 with Linux support
This GDB was configured as "i386-RedHat-linux"...
(gdb) disas _exit
Dump of assembler code for function _exit:
0x804b970 <_exit>: movl %ebx,%edx
0x804b972 <_exit+2>: movl 0x4(%esp,1),%ebx
0x804b976 <_exit+6>: movl {1}x1,%eax
0x804b97b <_exit+11>: int {1}x80
0x804b97d <_exit+13>: movl %edx,%ebx
0x804b97f <_exit+15>: cmpl {1}xfffff001,%eax
0x804b984 <_exit+20>: jae 0x804bc60 <__syscall_error>
End of assembler dump.