#!/usr/bin/env nix-shell #!nix-shell -i python -p python3 # NOTE: the colors are used to keep track of which letters have been # already substituted, and which are still unknown. def green(s): return f"\033[42m{s}\033[0m" def red(s): return f"\033[41m{s}\033[0m" def substitute(cipher_text, substitution_map): for letter in cipher_text: if letter.lower() in substitution_map: if letter.isupper(): x = substitution_map[letter.lower()].upper() else: x = substitution_map[letter] print(green(x), end="") else: print(red(letter), end="") with open('message.txt', 'r') as file: enc = file.read() # Here, I will be slowly substituting the letters in the ciphertext # based on what I believe the words to be. I have commented out the # invocations of substitute, and commented the newly found letters # after each invocation. # Starting off, "sxzqZNV{...}" looks like "picoCTF{...}" substitution_map = { '0': '0', '1': '1', '2': '2', '3': '3', '4': '4', '5': '5', '6': '6', '7': '7', '8': '8', '9': '9', '_': '_', '{': '{', '}': '}', 's': 'p', 'x': 'i', 'z': 'c', 'q': 'o', 'n': 't', 'v': 'f', } # substitute(enc, substitution_map) # Using frequency analysis (https://www.dcode.fr/frequency-analysis), we find that: # F 175× 13.87% # N 125× 9.9% # X 103× 8.16% # Q 102× 8.08% # L 98× 7.77% # E 83× 6.58% # T 68× 5.39% # Z 63× 4.99% # Y 61× 4.83% # A 56× 4.44% # P 46× 3.65% # W 42× 3.33% # V 39× 3.09% # G 35× 2.77% # B 34× 2.69% # S 28× 2.22% # R 24× 1.9% # U 20× 1.58% # H 19× 1.51% # K 16× 1.27% # M 9× 0.71% # C 9× 0.71% # O 5× 0.4% # I 2× 0.16% # Based on this, and the frequency of letters in the english alphabet, we can guess for 'e' substitution_map['f'] = 'e' # 13.87% ~= 12.7% # 'petitiol' -> 'petition' substitution_map['l'] = 'n' # 'incpwbinr' -> 'including' # 'effectiue' -> 'effective' substitution_map['p'] = 'l' substitution_map['w'] = 'u' substitution_map['b'] = 'd' substitution_map['r'] = 'g' # 'encountey' -> 'encounter' substitution_map['y'] = 'r' # 'eecurith' -> 'security' substitution_map['e'] = 's' substitution_map['h'] = 'y' # 'effectiuely' -> 'effectively' substitution_map['u'] = 'v' # 'cogputer' -> 'computer' substitution_map['g'] = 'm' # 'catllenge' -> 'challenge' substitution_map['a'] = 'h' substitution_map['t'] = 'a' # 'thinc' -> 'think' substitution_map['c'] = 'k' # 'valuakle' -> 'valuable' substitution_map['k'] = 'b' # 'thereeoists' -> 'there exists' substitution_map['o'] = 'x' # 'homever' -> 'however' substitution_map['m'] = 'w' # 'techniiue' -b 'technique' substitution_map['i'] = 'q' substitute(enc, substitution_map)