Insomnihack Teaser 2017 Bender_safe Writeup

Solved by 4rbit3r

This was the first of a 3 part challenge that contained flags for each part.

The first part is a  reversing challenge. The given files are a MIPS-32 bit executable and an emulator for the same. I had to refresh a what was left from my memory on MIPS architecture. And then a lot of googling also took place. But in the end, it was a challenge that I enjoyed doing.

Going through the code of main function, we see that there are a lot of functions being called. Of those, a few functions are of importance to us. Namely:

  1. doshuffle.
  2. validate.
  3. get_first_flag.

Obviously, we need to get to the get_first_flag function. So now let’s try and figure out what the binary actually does.

It calls opens /dev/urandom and reads 8 bytes from it and stores it in a buffer. This buffer is then used by the doshuffle function to create a string of lenth 16. I spent a lot of time trying to figure out what the doshuffle function did (and eventually developed a pseudo-code). I had thought that we needed to figure out the value of the 8 byte random value from the string being printed out to us. I was too lazy to actually reverse the functionality of the doshuffle function. So instead I patched the binary. I changed the string ‘/dev/urandom’ to a file that I created and filled with 8 ‘A’s. So now, the random value read in and the string generated by the doshuffle function will be constant. And then, trying the input of 8 “A”‘s, we find that it’s not what we need to pass the validate function.

So after that, I moved on to the validate function. In spite of being a very large function, what it does is very simple. It multiplies a lot of constants around and finally stores a value at a particular location. Since none of our input comes into the equation, we can say that those values will be constant in every execution. So, then the validate function boils down to a simple comparison between the user input and the string printed out.

Using a debugger, we can easily set breakpoints at those locations, and identify the constraints on our input with respect to the string being printed out. Once, we’ve finished that, we can easily write a script that creates a string that can pass all the checks of the validate function.

And well, here’s the script:

from pwn import *

mychars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
HOST,PORT = 'bender_safe.teaser.insomnihack.ch',31337

def findstr(chall):
	final_str=''
	final_str+=chall[0]
	final_str+=chall[15]
	if chall[7] >= 'A':
		a=ord(chall[7])^ord('K')^0x61^10
		final_str+=str(chr(a))
	elif chall[7] < 'A':
a=ord(chall[7])^(0xffffffa6)^(0xffffff99)^(0x7f)
final_str+=str(chr(a))
if chall[3] >= 'A':
		a=mychars.index(chall[3])+10
		final_str+=mychars[a]
	elif chall[3] < 'A':
a=mychars.index(chall[3])-10
final_str+=mychars[a]
if chall[4] >= 'A':
		final_str+=mychars[mychars.index(chall[4])+10]
	elif chall[4] < 'A':
final_str+=mychars[mychars.index(chall[4])-10]

val = abs(ord(chall[1])-ord(chall[2]))
final_str+=mychars[val%(len(mychars)-1)]
val = abs(ord(chall[5])-ord(chall[6]))
final_str+=mychars[val%(len(mychars)-1)]
if chall[8]>='A':
		val = ord(chall[8])^0x4b^0x61^0xa
		final_str+=str(chr(val))
	elif chall[8]<'A':
		val=ord(chall[8])^0xffffffa6^0xffffff99&0x7f
		final_str+=str(chr(val))
	return final_str

p=remote(HOST,PORT)
p.recvuntil(':')
p.recvline()
msg = p.recvline().strip()
retval = findstr(msg)
p.sendline(retval)
print p.recvall(timeout=1)

And well, running that gave the flag
Here it is : INS{Angr_is_great!_Oh_angr_is_great!_Angr_angr_angr}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create a free website or blog at WordPress.com.

Up ↑

%d bloggers like this: