3

I've been working on a buffer overflow on a 64 bit Linux machine for the past few days. The code I'm attacking takes in a file. This original homework ran on a 32-bit system, so a lot is differing. I thought I'd run with it and try to learn something new along the way. I set sudo sysctl -w kernel.randomize_va_space=0 and compiled the program below gcc -o stack -z execstack -fno-stack-protector stack.c && chmod 4755 stack

    /* This program has a buffer overflow vulnerability. */
    /* Our task is to exploit this vulnerability */
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    int bof(char *str)
    {
        char buffer[12];
    
        /* The following statement has a buffer overflow problem */
        strcpy(buffer, str);
    
        return 1;
    }
    
    int main(int argc, char **argv)
    {
        char str[517];
        FILE *badfile;
    
        badfile = fopen("badfile", "r");
        fread(str, sizeof(char), 517, badfile);
        bof(str);
    
        printf("Returned Properly\n");
        return 1;
    }

I could get it to crash by making a file with 20 "A"s. I made a small script to help.

    #!/usr/bin/bash
    
    python -c 'print("A"*20)' | tr -d "\n" > badfile

So now, if I add 6 "B"s to the mix after hitting the SIGSEGV in gbd I get.

    RIP: 0x424242424242 ('BBBBBB')
    0x0000424242424242 in ?? ()

Perfect! Now we can play with the RIP and put our address in for it to jump to! This is where I'm getting a little confused.

I added some C's to the script to try to find a good address to jump to

    python -c 'print("A"*20 + "B"*6 + C*32)' | tr -d "\n" > badfile

after creating the file and getting the SEGFAULT my RIP address is no longer our B's

    RIP: 0x55555555518a (<bof+37>:  ret)
    Stopped reason: SIGSEGV
    0x000055555555518a in bof (
        str=0x7fffffffe900 'C' <repeats 14 times>)
        at stack.c:16

I thought this might be due to using C's, so I went ahead and tried to find an address. I then ran x/100 $rsp in gbd, but it looks completely different than before without the Cs

    # Before Cs
    0x7fffffffe8f0: 0x00007fffffffec08      0x0000000100000000
    0x7fffffffe900: 0x4141414141414141      0x4141414141414141
    0x7fffffffe910: 0x4242424241414141      0x0000000000004242
    
    # After Cs
    0x7fffffffe8e8: "BBBBBB", 'C' <repeats 32 times>
    0x7fffffffe90f: "AAAAABBBBBB", 'C' <repeats 32 times>
    0x7fffffffe93b: ""

I've been trying to understand why this is happening. I know after this I can supply an address plus code to get a shell like so

python -c 'print("noOPs"*20 + "address" + "shellcode")' | tr -d "\n" > badfile The only thing that has come to mind is the buffer size? I'm not too sure, though. Any help would be great. Doing this alone without help has made me learn a lot. I'm just dying to create a working exploit!

UndercoverDog
  • 612
  • 2
  • 17

1 Answers1

0

I think the reason is that you are creating an address that is invalid under x64 specification: see Canonical form addresses where the most significant 16 bits of any virtual address, bits 48 through 63, must be copies of bit 47.

So the fault is intercepted by the hardware itself and not reaching gdb (or at least not transmitting information other than faulting very hard). If you run it and look at the dmesg you can look something like

stack[506302] general protection fault ip:55555555518e sp:7fffffffddf8 error:0 in stack[555555555000+1000]

when you use an address like 0x07060504030201 and it's an error different with a "right address"

stack[506705]: segfault at 60504030201 ip 0000060504030201 sp 00007fffffffde00 error 14 in stack[555555554000+1000]
Code: Unable to access opcode bytes at RIP 0x605040301d7.

Writing exploit in modern systems is sometimes(?) a little pain.

gipi
  • 126
  • 3