/* 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发生某些行为,否则这通常是处理有效负载以维持寄存器状态的最佳方法。
评论
无限循环版本还会无限运行shellcode吗?看起来好像重复到达了shellcode,并且每次都将控制权返回到程序的开始。用-O0 -g编译程序,然后gdb编译它。运行;当它收到信号时,检查eip(信息寄存器)和堆栈回溯(bt)。如果仍然无法解决问题,请在main的返回处设置一个断点(break simple_if.c:16,仔细检查行号),运行,一步一步地检查之后的情况(stepi以及nexti等退出函数)处理程序)。
寄存器和/或标志可能已从先前的值更改。分别在shellcode的开头和结尾处尝试pushad / popad和pushfd / popfd。这将恢复原始寄存器和EFlags。如果没有其他问题,那么我们就可以排除问题。