在 ELF 二进制文件中注入 shellcode

逆向工程 部件 小精灵 修补 外壳代码 纳姆
2021-07-03 05:35:33

我正在尝试在 32 位 ELF 可执行文件中注入一段 shellcode。我正在运行 Ubuntu 14.04 64 位。因此,我运行的所有命令都需要显式开关来生成 32 位代码。我正在使用elf-infector来注入我的 shellcode。

主机二进制文件的 C 源代码如下:

/* simple_if.c */

#include <stdio.h>
#include "s2e.h"

int main()
{
  int var_cond;
  printf("Enter 0/1: ");
  scanf("%d", &var_cond);
  if(!var_cond)
    printf("Entered value: 0\n");
  else
    printf("Entered value: 1\n");

  return 0;
}

首先,我尝试使用“Hello World”ASM 负载:

; hello.asm
global _start
section .text

_start:
    jmp MESSAGE      ; 1) lets jump to MESSAGE

GOBACK:
    mov eax, 0x4
    mov ebx, 0x1
    pop ecx          ; 3) we are poping into `ecx`, now we have the
                     ; address of "Hello, World!\r\n" 
    mov edx, 0xF
    int 0x80
    jmp end          ; Injector will insert a jump to original entry point

    ;mov eax, 0x1    ; Intentionally not returning the control
    ;mov ebx, 0x0
    ;int 0x80

MESSAGE:
    call GOBACK       ; 2) we are going back, since we used `call`, that means
                      ; the return address, which is in this case the address 
                      ; of "Hello, World!\r\n", is pushed into the stack.
    db "Hello, World!", 0dh, 0ah    
end:

编译宿主和寄生虫并在最后注入shellcode。

gcc -m32 simple_if.c -o simple_if
nasm -f elf hello.asm -o hello.o
ld -m elf_i386 hello.o -o hello

# Test the assembled code
./hello
Hello, World!
Segmentation fault (core dumped)
# Segfault is natural, we are not gracefully returning to OS

# Now extract the shellcode
for i in `objdump -d ./hello | tr '\t' ' ' | tr ' ' '\n' | egrep '^[0-9a-f]{2}$' `; do echo -n "\\\\x$i" ; done | paste -d '' -s | sed 's/^/"/' | sed 's/$/"/g'
"\xeb\x14\xb8\x04\x00\x00\x00\xbb\x01\x00\x00\x00\x59\xba\x0f\x00\x00\x00\xcd\x80\xeb\x14\xe8\xe7\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21\x0d\x0a"

# Update parasite.h
make
./infector simple_if

Run the infected file
./simple_if
Hello, World!
Enter 0/1: 8
Entered value: 1
Segmentation fault (core dumped)

但是,我希望程序应该优雅地退出。因为,感染者会在 shellcode 的末尾插入一个跳转到 OEP。我用不同的有效载荷尝试了同样的方法。但是,在这种情况下,程序在无限循环中运行,永远不会退出。

global     _start    
section    .text

_start:
    mov    ecx,0x23f0
    mov    edx,0x804869c
    jmp    prog_name

stub:
    pop    eax
    push   ebx
    mov    ebx,edx
    ;db     0x0f,0x3f,0x00,0xaa,0x00,0x00,0x00,0x00,0x00,0x00
    pop    ebx
    xor    eax,eax
    jmp    jump_start

prog_name:
    call   stub
    db "simple_if",0x00,0x90

jump_start:

这就是受感染文件产生的结果。

./simple_if
Enter 0/1: 9
Entered value: 1
Enter 0/1: 7
Entered value: 1
Enter 0/1: 6
Entered value: 1
Enter 0/1: 5
Entered value: 1
Enter 0/1: ^C

使用GDB,我可以看到先执行shellcode,然后程序跳转到OEP。此后发生崩溃。任何人都可以给我任何线索吗?

1个回答

正如@goodies 在评论中所说,这里发生的事情是您正在破坏一些寄存器值,从而导致崩溃。

像这样pusha/扩展你的有效载荷popa

_start:
  pusha
  jmp MESSAGE

和这里

int 0x80
popa
jmp end     

如果您现在执行所有步骤,您将获得请求的结果:

./simple_if 
Hello, World!
Enter 0/1: 9
Entered value: 1

这通常是处理有效负载以维护寄存器状态的最佳方法,除非您特别希望通过修改 regs 来发生某些行为。