Author: argot
Pub: 2022-12-18
495 words

# 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), fullList)

for el in fullList:
if el not in b:
return el

def findMissing2(b):
fullList = []
recur2(len(b), 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__":
port = 20000

data = r.recvuntil(b'> ')
data = str(data)
data = data.split('"')
prefix = data.split('+').replace(' ', '')
shaSum = data

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}
``````