bridge of death
What is the air-speed velocity of an unladen swallow?
2 min read
[ + ]Overview
Taking a high-level look at the binary after running it we see we are prompted with a series of 5 questions ;).
Lets dig deeper.
[ + ]Reversing and Solution
The idea for this challenge is that there are 3 questions to answer.
To solve the first one, the following must return true:
The solution to question1
:
def q1():
return b'My name is Sir Lancelot of Camelot.\n'
The call to the second question must return false, and the sub routine is split as follows:
The idea here is to find two numbers such that the return value of the func2 call is equal to the second value.
As shown above, v5
is equal to 10
when initialized, and hitting the second if
statement would return v5
. So by passing 10
as the first value, we can ensure that 10
is returned from func2
. Next we must make sure that both values are the same so the second value is also 10.
The solution to question2
:
def q2():
return b'10\n10\n'
For the third question, you have to pass two values at each iteration and make sure that forestOfEwing[(256 * val_1) + val_2]
is equal to the index of the loop.
To solve this, I exported the array and pickled it so that I didn't have to keep it hard coded in the file. Then looped from 1
to 9
and found where the loop index's value was stored in the list, then divided the index by 256
and taking the min
, and subtracting
that from the index of forestOfEwing
list.
The solution to question3
:
def q3():
res = b''
# list of bytes from the binary
with open('q3.pkl', 'rb') as f:
q3_list = pickle.load(f)
for i in range(1, 10):
index = q3_list.index(bytes.fromhex(str(i).zfill(2)).decode('utf-8'))
print(index)
num1 = index // 256
num2 = index % 256
res += str(num1).encode('utf-8') + b'\n' + str(num2).encode('utf-8') + b'\n'
return res
Solver
import pickle
from pwn import *
from pwnlib.util.packing import *
# Context
context.arch = 'amd64'
context.log_level = 'DEBUG'
# Main vars
NETID = ''
HOST, PORT = 'host', 8005
def q1():
return b'My name is Sir Lancelot of Camelot.\n'
def q2():
return b'10\n10\n'
def q3():
res = b''
# list of bytes from the binary
with open('q3.pkl', 'rb') as f:
q3_list = pickle.load(f)
for i in range(1, 10):
index = q3_list.index(bytes.fromhex(str(i).zfill(2)).decode('utf-8'))
print(index)
num1 = index // 256
num2 = index % 256
res += str(num1).encode('utf-8') + b'\n' + str(num2).encode('utf-8') + b'\n'
return res
def pwn():
conn = remote(HOST, PORT)
conn.recvuntil(b'(something like abc123): ')
conn.sendline(NETID)
conn.recvuntil(b'What is your name?')
conn.send(q1())
conn.recvuntil(b'What is your quest?')
conn.send(q2())
conn.recvuntil(b'What is the air-speed velocity of an unladen swallow?')
conn.send(q3())
conn.recvuntil(b'flag{')
response = conn.recvline()
conn.close()
print("flag{" + response.decode().strip())
if __name__ == "__main__":
pwn()