バランスを取りたい

よくCTFの記事を書きます

RuCTF 2014 Writeup (Crypto 200)

200. Mary Queen

Mary Queen of Scots goes chinese. We capture secret message from prison where Mary Queen stands. Help us figure out what message means.

ファイルを開くとE4 xx yyな文字とスペースが並んでいることがわかります。
何が何だかさっぱりわからなかったのですが、xx yyが結構被っていること、スペースが英語っぽい位置にあることから、とりあえず頻度分析を回してみました。


その結果、53種類の文字とスペースがあることがわかり、アルファベットの大文字小文字なんじゃないかと検討をつけました。
適当なサイトから英字の頻度表を持ってきて、とりあえず頻度が高い26文字を置換。
残りは適当に大文字のアルファベットで埋めたりしてそれっぽく処理してます。


置換した結果、英文っぽいけどなんか違う文章が生成されたのでそれを換字式暗号のソルバーに突っ込んだところ、文章の最初の部分が"lewis carroll alices adventures"だということがわかりました。


フラグは"Alice's Adventures in Wonderland"でこの時既に解けているはずだったのですが、
まさか物語のタイトルが答えだと思わず、全文を復元しようと原文と照らしあわせてました。


結局答えが分からず放置してたのですが、
@akiymさんがhttps://www.youtube.com/watch?v=_htopuN4pCkを見つけてきてくれたおかげで、実は既に暗号は解けていてそれ以上の謎はないことが判明。

さらに、IRCでcrypto200の答えについて、「case-insensitiveだけどpunctuationは重要」っていう運営の発言があったのをふと思い出し、"Alice's Adventures in Wonderland"をsubmitしたところ200ptを獲得できました。

import struct

dic = {
  "b890": "e",
  "b994": "t",
  "b9a7": "a",
  "b8b7": "o",
  "b891": "i",
  "b99e": "s",
  "baab": "n",
  "b898": "r",
  "b9ab": "h",
  "b9a5": "l",
  "b9a4": "d",
  "b89d": "u",
  "b9a0": "?",
  "bbaa": "g",
  "bba1": "c",
  "bb90": "w",
  "b8a8": "y",
  "b8bc": "m",
  "babc": "the",
  "b8a1": "p",
  "ba9f": "b",
  "bb83": "f",
  "b8ad": "k",
  "b8ac": "v",
  "b8ae": "and",
  "b893": "of",
  "ba86": "in",
  "b9a9": "q",
  "bbb2": "that",
  "bbb8": "x",
  "baba": "E",
  "b885": "as",
  "baa3": "G",
  "b981": "j",
  "b996": "I",
  "b9be": "J",
  "bb84": "z",
  "b998": "with",
  "bb9e": "but",
  "bbbb": "for",
  "bb94": "so",
  "b983": "not",
  "b991": "what",
  "baac": "this",
  "bab6": "is",
  "bab9": "if",
  "b8b2": "when",
  "ba83": "there",
  "b89e": "me",
  "b8a4": "my",
  "ba94": "on",
  "bb8b": "from",
  "bb88": "where"
}

f = open('d8cb57bf1b34bf8c58836724ee2b0b71', 'rb')

sample = ""

while True:
  op = f.read(1)
  if op == ' ':
    sample += " "
    continue
  elif op == "":
    break
  
  code = struct.unpack(">H", f.read(2))
  s = "%x" % code

  sample += dic[s]

print sample