I am trying to inject a piece of shellcode inside a 32-bit ELF executable. I am running Ubuntu 14.04 64-bit. Hence, all the commands I have run require explicit switches to produce 32-bit code. I am using elf-infector to inject my shellcode.
C source of the host binary is given below:
/* 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;
}
First I tried with a "Hello World" ASM payload:
; 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:
Compiled both the host and the parasite and injected the shellcode at the end.
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)
But, I expect the program should gracefully exit. Because, the infector inserts a jump to the OEP at the end of the shellcode. I tried the same with a different payload. But, in this case, the program runs in an infinite loop a never exits.
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:
This is what the infected file produces.
./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
With GDB, I can see the shellcode is executed first and then the program jumps to OEP. The crash occurs thereafter. Can anybody please give me any clue what is going wrong?
-O0 -g
andgdb
it. Run it; when it gets the signal, inspecteip
(info registers)
and the stack backtrace (bt
). If that doesn't get you anywhere, set a breakpoint at thereturn
in main (break simple_if.c:16
, double check the line number), run, single step through what happens after that (stepi
and maybenexti
over functions like exit handlers).