0. 一个弹出shell的小程序
bump_shell.c:
#include<unistd.h>
#include<stdlib.h>
char *buf[]={"/bin/sh",NULL};
void main(){
execve("/bin/sh",buf,0);
exit(0);
}
gcc -static -o bump_shell bump_shell.c
编译后执行./bump_shell
:
root@kali:~/shellcode# ./bump_shell
# pwd
/root/shellcode
# exit
root@kali:~/shellcode#
1. gdb调试分析bump_shell
默认gdb反汇编语法是A&T,看起来有点别扭,所以先把语法设置为Intel格式:
root@kali:~/shellcode# echo "set disassembly-flavor intel" > ~/.gdbinit
对汇编不熟的话可以先看看汇编基础,对gdb调试不熟的话可以先看看GDB十分钟教程。
-q(quik)
启动gdb:
root@kali:~/shellcode# gdb bump_shell -q
Reading symbols from bump_shell...(no debugging symbols found)...done.
(gdb) disas main
Dump of assembler code for function main:
0x080489cc <+0>: lea ecx,[esp+0x4]
0x080489d0 <+4>: and esp,0xfffffff0
0x080489d3 <+7>: push DWORD PTR [ecx-0x4]
0x080489d6 <+10>: push ebp
0x080489d7 <+11>: mov ebp,esp
0x080489d9 <+13>: push ecx
0x080489da <+14>: sub esp,0x4
0x080489dd <+17>: sub esp,0x4
0x080489e0 <+20>: push 0x0
0x080489e2 <+22>: push 0x80eb068
0x080489e7 <+27>: push 0x80bc2a8
0x080489ec <+32>: call 0x806d650 <execve>
0x080489f1 <+37>: add esp,0x10
0x080489f4 <+40>: sub esp,0xc
0x080489f7 <+43>: push 0x0
0x080489f9 <+45>: call 0x804e660 <exit>
End of assembler dump.
(gdb) disas 0x806d650
Dump of assembler code for function execve:
0x0806d650 <+0>: push ebx
0x0806d651 <+1>: mov edx,DWORD PTR [esp+0x10]
0x0806d655 <+5>: mov ecx,DWORD PTR [esp+0xc]
0x0806d659 <+9>: mov ebx,DWORD PTR [esp+0x8]
0x0806d65d <+13>: mov eax,0xb
0x0806d662 <+18>: call DWORD PTR ds:0x80eb9f0
0x0806d668 <+24>: pop ebx
0x0806d669 <+25>: cmp eax,0xfffff001
0x0806d66e <+30>: jae 0x8071140 <__syscall_error>
0x0806d674 <+36>: ret
End of assembler dump.
(gdb) disas *0x80eb9f0
Dump of assembler code for function _dl_sysinfo_int80:
0x08070030 <+0>: int 0x80
0x08070032 <+2>: ret
End of assembler dump.
(gdb) b *0x0806d662
Breakpoint 1 at 0x806d662
(gdb) r
Starting program: /root/shellcode/bump_shell
Breakpoint 1, 0x0806d662 in execve ()
(gdb) disas 0x806d650
Dump of assembler code for function execve:
0x0806d650 <+0>: push ebx
0x0806d651 <+1>: mov edx,DWORD PTR [esp+0x10]
0x0806d655 <+5>: mov ecx,DWORD PTR [esp+0xc]
0x0806d659 <+9>: mov ebx,DWORD PTR [esp+0x8]
0x0806d65d <+13>: mov eax,0xb
=> 0x0806d662 <+18>: call DWORD PTR ds:0x80eb9f0
0x0806d668 <+24>: pop ebx
0x0806d669 <+25>: cmp eax,0xfffff001
0x0806d66e <+30>: jae 0x8071140 <__syscall_error>
0x0806d674 <+36>: ret
End of assembler dump.
(gdb) i r
eax 0xb 11
ecx 0x80eb068 135180392
edx 0x0 0
ebx 0x80bc2a8 134988456
esp 0xbffff358 0xbffff358
ebp 0xbffff378 0xbffff378
esi 0x80eb00c 135180300
edi 0x49656e69 1231384169
eip 0x806d662 0x806d662 <execve+18>
eflags 0x296 [ PF AF SF IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) p /x $eax
$1 = 0xb
(gdb) x /10c $ebx
0x80bc2a8: 47 '/' 98 'b' 105 'i' 110 'n' 47 '/' 115 's' 104 'h' 0 ' 00'
0x80bc2b0: 46 '.' 46 '.'
(gdb) x /10x $ebx
0x80bc2a8: 0x2f 0x62 0x69 0x6e 0x2f 0x73 0x68 0x00
0x80bc2b0: 0x2e 0x2e
(gdb) x /2wx $ecx
0x80eb068 <buf>: 0x080bc2a8 0x00000000
(gdb) p $edx
$2 = 0
(gdb)
2. 编写shellcode
先比照上述gdb反汇编,抠出可用汇编代码,调通后结合shellcode开发基础精神,精简如下:
shellcode.asm:
section .text
global _start
_start:
xor eax,eax
push eax
push 0x68732f2f
push 0x6e69622f
mov ebx,esp
push eax
push ebx
xor edx,edx
mov ecx,esp
mov al,0xb ; mov eax,0xb causes too many zero bytes.
int 0x80
编译验证:
root@kali:~/shellcode/asm# nasm -f elf shellcode.asm
root@kali:~/shellcode/asm# ld -o shellcode shellcode.o
root@kali:~/shellcode/asm# ./shellcode
# pwd
/root/shellcode/asm
# exit
root@kali:~/shellcode/asm#
提取二进制:
oot@kali:~/shellcode/asm# objdump -d shellcode
shellcode: file format elf32-i386
Disassembly of section .text:
08048060 <_start>:
8048060: 31 c0 xor %eax,%eax
8048062: 50 push %eax
8048063: 68 2f 2f 73 68 push $0x68732f2f
8048068: 68 2f 62 69 6e push $0x6e69622f
804806d: 89 e3 mov %esp,%ebx
804806f: 50 push %eax
8048070: 53 push %ebx
8048071: 31 d2 xor %edx,%edx
8048073: 89 e1 mov %esp,%ecx
8048075: b0 0b mov $0xb,%al
8048077: cd 80 int $0x80
root@kali:~/shellcode/asm#
放到C代码里验证:
shellcode.c:
void main(){
char shellcode[]=
"x31xc0"
"x50"
"x68x2fx2fx73x68"
"x68x2fx62x69x6e"
"x89xe3"
"x50"
"x53"
"x31xd2"
"x89xe1"
"xb0x0b"
"xcdx80";
void (*fp)(void);
fp=(void*)shellcode;
fp();
}
效果此处略(注意须开启栈空间可执行权限,gcc -z execstack -o shellcode shellcode.c
)