Problem
N/A. Something about QR and anagrams.
Solution
Connect to a server and get a bunch of ascii and ansi QR codes, then are supposed to reply with a text and some numbers.
I solved it using qrtools
, png
and an anagram solver I found using Google. The anagram solver needs a dictionary to work, so I had to find a sorted word list by frequency (N-gram, the hint in the challenge name).
I generate a png image with the qrcode and then feed it to qrtools to decode a string. This string is an anagram that I then solve with the anagram solver previously mentioned.
Sorry about the mess but here’s the code.
Change to the anaram solver:
def process(words, word):
jumbledWord = word
filteredWords = [filterWordsBasedOnLength(jumbledWord,word) for word in words]
filteredWords = filter(None,filteredWords)
for dictionaryWord in filteredWords:
if computeValuForEachWord(dictionaryWord,jumbledWord):
print dictionaryWord
return dictionaryWord
Solution
from pwn import *
import qrtools
import png
import ana
#context.log_level = 0
r = remote('pool.pwn2win.party', 31337)
global g_i
g_i = 0
def decodeascii(data, fname):
width = len(data[0]) * 5
height = len(data) * 5
f = open(fname, 'wb')
w = png.Writer(width, height, greyscale=True)
rows = []
for i in range(len(data)):
row = []
for x in data[i]:
col = 255 if x == '0' else 0
row += [col]*5
rows += [row] * 5
w.write(f, rows)
f.close()
def decode(data):
global g_i
g_i += 1
fname = 'qr-%d.png' % g_i
data = data.split('\n')
if data[0][0] == '0' or data[0][0] == '1':
print "ASCII"
decodeascii(data, fname)
else:
print "ANSI"
newdata = []
# Mmmm, ctf code is beautiful.
for line in data:
line = line.replace(unhex('1b5b376d20201b5b306d'), 'O')
line = line.replace(unhex('1b5b34396d20201b5b306d'), 'I')
line = line.replace('O', '0')
line = line.replace('I', '1')
newdata.append(line)
#print "[%s]" % line
decodeascii(newdata, fname)
x = qrtools.QR(filename=fname)
x.decode()
print x.data
return x.data
words = [x.strip() for x in open("google-10000-english-usa.txt", "r").read().split()]
words += [x.strip() for x in open("wordsEn.txt", "r").read().split()]
postfix = []
answers = []
part = ""
r.recvuntil('\n')
hax = True
while hax:
ret = r.recv()
if ret.find('Phrase') > -1:
print "Phrase!"
hax = False
part += ret
#print part
nn = part.find('\n\n')
if nn >= 0:
x = part[:nn].strip()
part = part[nn+2:]
elif not hax:
nn = part.find('Phrase')
x = part[:nn].strip()
else:
continue
append = ""
print "qr: [%s]" % x
if x == '': continue
y = decode(x)
try:
int(y)
postfix.append(y)
except:
pass
rep="0123456789"
for ch in y:
if ch in rep:
y=y.replace(ch,'')
if y == '': continue
cap = False
rep="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
for ch in y:
if ch in rep:
cap = True
y = y.lower()
if y.find('.') >= 0:
y = y.replace(".", "")
append = "."
if y.find(',') >= 0:
y = y.replace(",", "")
append = ","
if y.find('!') >= 0:
y = y.replace("!", "")
append = "!"
if y.find('?') >= 0:
y = y.replace("?", "")
append = "?"
if y.find(';') >= 0:
y = y.replace(";", "")
append = ";"
decoded = ana.process(words, y) + append
if cap:
if len(decoded) > 1:
decoded = decoded[0].upper() + decoded[1:]
else:
decoded = decoded[0].upper()
print y, decoded
answers += [decoded]
print "progress: [%s]" % ' '.join(answers)
xx = ' '.join(answers)
print xx
xx = xx + " " + postfix[0] + " " + postfix[1]
print xx
r.sendline(xx)
print r.recv()
print r.recv()