guess what
Challenge
guess what! Exactly.. what?
nc guess_what.ctf.knping.pl 20000
Overview
A programming challenge with some brute forcing and auto solving. Connecting the to socket we obtain the first challenge:
Odd man out
After “cracking” the hash by brute forcing the 3 bytes, a list of all combinations over a set of 2 (“A”,“B”) is given of varying length. The answer is the sole permutation is missing.
This occurs for 17 times, then a set of all combinations over a set of 4 (“A”, “B”, “C”, “D”). Do this four more times, and you get a dump of permutations over a set of 10 characters. Find the odd one out and find the flag.
Solution
The following script was used to solve it. Its probably not the best way.
import pwn
from hashlib import sha256
chars = ['0','1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f']
def findMissing(b):
fullList = []
recur(len(b[0]), fullList)
for el in fullList:
if el not in b:
return el
def findMissing2(b):
fullList = []
recur2(len(b[0]), fullList)
for el in fullList:
if el not in b:
return el
def recur(n, dictA, s = ''):
if n-1:
recur(n-1, dictA, s + 'A')
recur(n-1, dictA, s + 'B')
else:
dictA.append('A'+s)
dictA.append('B'+s)
def recur2(n, dictA, s=''):
if n-1:
recur2(n-1, dictA, s+'A')
recur2(n-1, dictA, s+'B')
recur2(n-1, dictA, s+'C')
recur2(n-1, dictA, s+'D')
else:
dictA.append('A' + s)
dictA.append('B' + s)
dictA.append('C' + s)
dictA.append('D' + s)
def makeHashDict(prefix):
ans = ''
dictAns = {}
for a in chars:
for b in chars:
for c in chars:
for d in chars:
for e in chars:
for f in chars:
ans = a+b+c+d+e+f
guessHash = sha256((prefix+ans).encode()).hexdigest()
dictAns[guessHash] = ans
return dictAns
def makeList(data):
out = []
data = data.split(b'\n')
collect = False
for line in data:
if line == b'DONE PRINTING':
collect = False
if collect:
out.append(str(line, 'ascii'))
if line == b'PRINTING...':
collect = True
return out
if __name__ == "__main__":
addr = 'guess_what.ctf.knping.pl'
port = 20000
r = pwn.remote(addr, port)
data = r.recvuntil(b'> ')
data = str(data)
data = data.split('"')
prefix = data[1].split('+')[0].replace(' ', '')
shaSum = data[3]
print('Prefix = %s' % (prefix))
print('Sum = %s' % (shaSum))
hashDict = makeHashDict(prefix)
ans = hashDict.get(shaSum)
print("Ans = %s" % (ans))
r.sendline(bytes(ans, 'ascii'))
out = r.recvuntil(b'...')
r.sendline(b'')
data = r.recvuntil(b'> ')
for i in range(2, 18):
b = makeList(data)
ans = findMissing(b)
print('Ans = %s' % (ans))
r.sendline(bytes(ans, 'ascii'))
if i < 17:
data = r.recvuntil(b'> ')
else:
r.recvuntil(b'...')
r.sendline(b'')
data = ''
data = r.recvuntil(b'> ')
for i in range(0, 4):
b = makeList(data)
ans = findMissing2(b)
print('Ans = %s' %(ans))
r.sendline(bytes(ans, 'ascii'))
if i < 3:
data = r.recvuntil(b'> ')
else:
r.recvuntil(b'...')
r.sendline(b'')
raw = r.recvuntil(b'DONE')
data = str(raw, 'ascii')
f = open('spooky-raw.txt', 'wb')
f.write(raw)
f.close()
f = open('spooky.txt', 'w')
f.write(data)
f.close()
Flag
Once we get the spooky dump, we just generate a list of all permutations of the characters included and find the odd one out. Similar solution from the combo generation. I removed a few of the solutions, so I obtained two “possible” flags here.
ping{2nF8ai2e9d}