# 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) * 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' or data == '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("wordsEn.txt", "r").read().split()]

postfix = []
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.upper() + decoded[1:]
else:
decoded = decoded.upper()

print y, decoded