bl/old.4d.bof.c
2022-03-21 18:00:48 +00:00

88 lines
3.4 KiB
C

/*
* bof.c
*
* A quick, simple, buffer overflow example.
*
* std / c89
* cflags / -z execstack -ggdb -fno-stack-protector -no-pie
*/
#include <stdio.h> /* printf, gets */
#define BUF_SZ 8 /* Something small, easy to exploit */
/*
* The function `get_rich_fast` is the function we are going to try to jump to.
* - paddr = 0x1136
* - vaddr = 0x401136
*/
void get_rich_fast(void) {
/* The following instruction at (vaddr = 0x40113a). */
printf("woohoo!!! free money");
}
void get_input(void) {
/* Declare the buffer we want to put the input in. */
char buf[BUF_SZ];
/*
* Table of the parts of `rsp` we want to pay attention to at this point.
*
* Address start: 0x7fffffffe590
*
* ------------------------------------------------------------------------------------------------
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f |
* |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
* | | | | | | | buf ---> | [------- -------] |
* |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
* | ? | ? | ? | ? | ? | ? | ? | ? | 9a | 11 | 40 | <--- (1) | | | |
* |____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
*
* (1) Saved base pointer, but also is the return address back into the function main.
* We know that 0x40119a is where the program will jump back to at the end of this function.
* However, we want it to jump to 0x40115a. This is where we want to attack.
*
* Simply, in a debugger (lldb), we can do the following:
*
* - [ break set -name get_input ] <--- ( set a breakpoint at the function name get_input )
* - [ run ]
* - [ step ] until the current line is AFTER the `gets` call and before we jump back to main.
* - [ mem write 0x7fffffffdf78 0x5a ] <--- ( writing 0x5a to replace 0x9a, so that we jump to the printf statement )
*
* In the debugger, if we did not change that value, it should show something like the following:
*
* ________________________
* | |
* | ---> return 0; |
* |_______________________|
*
* However, since we changed the address we wanted to jump to, we should see:
*
* ________________________
* | |
* | ----> printf(.....) |
* | } |
* |_______________________|
*
*
* Testing this, we know we want to fill our buffer with some character (such as a). We can see in memory that there
* is data stored between addresses 0x7ffffffffa5a0-7, and we want to keep that the same. We may come up with a payload
* such as: 'aaaaaaaa' + '\x00\xe3\xff\xff\xff\x7f\x00\x00' + '\x3a\x11\x40' and send that data into stdin using something like
* `printf`.
*
* In one compilation of the program where the vaddr of `get_rich_fast(void)` is 0x401156, the chunk of data after is
* [0xffffe300, 0x00007fff], we can overwrite the saved base pointer (where we would like to return to at the end of the
* `get_input` function by piping 'aaaaaaaa\x00\xe3\xff\xff\xff\x7f\x00\x00\x56\x11\x40' into our execution of [this] binary.
*
* Reference: https://localhost22.com/ref/bofpl.png
*
*/
gets(buf);
}
int main(void) {
/* Call the `get_input` function, which gives us access to our buffer and the `gets` call. */
get_input();
/* Exit code 0. */
return 0;
}