向 shellcode 添加指令

逆向工程 数据库 登记
2021-07-08 09:52:49

我有以下shellcode:

xor  eax, eax   ; eax = 0
push eax        ; 0 (end of the string)
push 0x68732f2f ; //sh
push 0x6e69622f ; /bin
mov  ebx, esp   ; ebx = &(/bin//sh)
xor  ecx, ecx   ; ecx = 0
mov  al, 0xb    ; execve
int  0x80

其中,转换为十六进制用于以下 C 程序:

const char shellcode[] =
     "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xb0\x0b\xcd\x80";

int main(){
    (*(void(*)()) shellcode)();
    return 0;
}

这工作得很好,但是当我单步执行有效负载时,gdb我看到在 shellcode 中添加了一条额外的指令:

$ gdb shellcode
(gdb) disass main
Dump of assembler code for function main:
   0x080483ed <+0>:     push   %ebp
   0x080483ee <+1>:     mov    %esp,%ebp
   0x080483f0 <+3>:     and    $0xfffffff0,%esp
   0x080483f3 <+6>:     mov    $0x80484a0,%eax
   0x080483f8 <+11>:    call   *%eax
   0x080483fa <+13>:    mov    $0x0,%eax
   0x080483ff <+18>:    leave
   0x08048400 <+19>:    ret
End of assembler dump.
(gdb)  x/14i 0x80484a0
   0x80484a0 <shellcode>:       xor    %eax,%eax
   0x80484a2 <shellcode+2>:     push   %eax
   0x80484a3 <shellcode+3>:     push   $0x68732f2f
   0x80484a8 <shellcode+8>:     push   $0x6e69622f
   0x80484ad <shellcode+13>:    mov    %esp,%ebx
   0x80484af <shellcode+15>:    xor    %ecx,%ecx
   0x80484b1 <shellcode+17>:    mov    $0xb,%al
   0x80484b3 <shellcode+19>:    int    $0x80
   0x80484b7 <shellcode+21>:    add    %al,(%ecx)
   ... (gibberish)

你可以看到shellcode+23是一个额外的行,添加到 shellcode 中。这里寻找答案时我发现它使 shellcode 崩溃,我不得不ecx在调用中断之前清除寄存器。

你知道这个额外的命令是什么吗?

2个回答

最初的 shellcode 只包含 8 条指令,但是因为您要求 gdb 反汇编 14 条指令,它继续执行您的要求。由于您要求反汇编比实际更多,它反汇编了变量后面碰巧存在的任何字节(可能是零填充,但也可能是可执行文件的其他部分)。

所以没有“添加”指令,你只是在拆解一些碰巧在它之后的内存中的垃圾。

Igor 是对的...原始shellcode 不包含任何ret( 0xc3),因此反编译的asm 中没有任何( )。问题是,当您要求gdb反汇编 14 条指令时,它会反汇编 14 条指令,将内存的内容解释为指令。

为了证明我所说的,这里是指令的反汇编add %al,(%ecx)

$ rasm2 -a x86 -C 'add %al,(%ecx)'
"\xc0\x00"

事实上,这是"\x00\xc0"(因为字节序),第一个"\x00"实际上是 shellcode 字符串的最后一个字符。

以下字符很可能是该main函数的代码或此位置内存中的任何内容。

无论如何,更仔细地重读伊戈尔的回答(他是对的!)。