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:

  1. def process(words, word):
  2. jumbledWord = word
  3. filteredWords = [filterWordsBasedOnLength(jumbledWord,word) for word in words]
  4. filteredWords = filter(None,filteredWords)
  5. for dictionaryWord in filteredWords:
  6. if computeValuForEachWord(dictionaryWord,jumbledWord):
  7. print dictionaryWord
  8. return dictionaryWord

Solution

  1. from pwn import *
  2. import qrtools
  3. import png
  4. import ana
  5. #context.log_level = 0
  6. r = remote('pool.pwn2win.party', 31337)
  7. global g_i
  8. g_i = 0
  9. def decodeascii(data, fname):
  10. width = len(data[0]) * 5
  11. height = len(data) * 5
  12. f = open(fname, 'wb')
  13. w = png.Writer(width, height, greyscale=True)
  14. rows = []
  15. for i in range(len(data)):
  16. row = []
  17. for x in data[i]:
  18. col = 255 if x == '0' else 0
  19. row += [col]*5
  20. rows += [row] * 5
  21. w.write(f, rows)
  22. f.close()
  23. def decode(data):
  24. global g_i
  25. g_i += 1
  26. fname = 'qr-%d.png' % g_i
  27. data = data.split('\n')
  28. if data[0][0] == '0' or data[0][0] == '1':
  29. print "ASCII"
  30. decodeascii(data, fname)
  31. else:
  32. print "ANSI"
  33. newdata = []
  34. # Mmmm, ctf code is beautiful.
  35. for line in data:
  36. line = line.replace(unhex('1b5b376d20201b5b306d'), 'O')
  37. line = line.replace(unhex('1b5b34396d20201b5b306d'), 'I')
  38. line = line.replace('O', '0')
  39. line = line.replace('I', '1')
  40. newdata.append(line)
  41. #print "[%s]" % line
  42. decodeascii(newdata, fname)
  43. x = qrtools.QR(filename=fname)
  44. x.decode()
  45. print x.data
  46. return x.data
  47. words = [x.strip() for x in open("google-10000-english-usa.txt", "r").read().split()]
  48. words += [x.strip() for x in open("wordsEn.txt", "r").read().split()]
  49. postfix = []
  50. answers = []
  51. part = ""
  52. r.recvuntil('\n')
  53. hax = True
  54. while hax:
  55. ret = r.recv()
  56. if ret.find('Phrase') > -1:
  57. print "Phrase!"
  58. hax = False
  59. part += ret
  60. #print part
  61. nn = part.find('\n\n')
  62. if nn >= 0:
  63. x = part[:nn].strip()
  64. part = part[nn+2:]
  65. elif not hax:
  66. nn = part.find('Phrase')
  67. x = part[:nn].strip()
  68. else:
  69. continue
  70. append = ""
  71. print "qr: [%s]" % x
  72. if x == '': continue
  73. y = decode(x)
  74. try:
  75. int(y)
  76. postfix.append(y)
  77. except:
  78. pass
  79. rep="0123456789"
  80. for ch in y:
  81. if ch in rep:
  82. y=y.replace(ch,'')
  83. if y == '': continue
  84. cap = False
  85. rep="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  86. for ch in y:
  87. if ch in rep:
  88. cap = True
  89. y = y.lower()
  90. if y.find('.') >= 0:
  91. y = y.replace(".", "")
  92. append = "."
  93. if y.find(',') >= 0:
  94. y = y.replace(",", "")
  95. append = ","
  96. if y.find('!') >= 0:
  97. y = y.replace("!", "")
  98. append = "!"
  99. if y.find('?') >= 0:
  100. y = y.replace("?", "")
  101. append = "?"
  102. if y.find(';') >= 0:
  103. y = y.replace(";", "")
  104. append = ";"
  105. decoded = ana.process(words, y) + append
  106. if cap:
  107. if len(decoded) > 1:
  108. decoded = decoded[0].upper() + decoded[1:]
  109. else:
  110. decoded = decoded[0].upper()
  111. print y, decoded
  112. answers += [decoded]
  113. print "progress: [%s]" % ' '.join(answers)
  114. xx = ' '.join(answers)
  115. print xx
  116. xx = xx + " " + postfix[0] + " " + postfix[1]
  117. print xx
  118. r.sendline(xx)
  119. print r.recv()
  120. print r.recv()