# Easy Writer : [Laikaさん](https://twitter.com/ki4l_) [Wanictf2021 top](https://hackmd.io/bHFMMX0PQIqhd6IjAv5Otg) Problem --- 手始めに `encrypto.py` ```python= with open("flag.txt") as f: flag = f.read().strip() A = REDACTED B = REDACTED plaintext_space = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_{}" assert all(x in plaintext_space for x in flag) def encrypt(plaintext: str, a: int, b: int) -> str: ciphertext = "" for x in plaintext: if "A" <= x <= "Z": x = ord(x) - ord("A") x = (a * x + b) % 26 x = chr(x + ord("A")) ciphertext += x return ciphertext if __name__ == "__main__": ciphertext = encrypt(flag, a=A, b=B) print(ciphertext) ``` Output --- ```=txt HLIM{OCLSAQCZASPYFZASRILLCVMC} ``` Solve --- 暗号化処理を行うプログラムとFLAGを暗号化した結果が得られるので復号処理をしてFLAGを得る プログラムを見ると`x=(a*x+b)%26`が重要な部分であり、線形変換なので逆変換すれば良さそう! しかし、逆変換するには`a`と`b`が分からないと復号できない そこで、aとbについて全探索する `(a*x+b)`に対して`%26`しているのでaもbも0~25の範囲を探索すれば良い 線形のシフト暗号なのでシフトし続ければ元に戻る。 つまりencrypt関数がそのまま使える! ```python= # main内に追記する形 if __name__="__main__": c='HLIM{OCLSAQCZASPYFZASRILLCVMC}' for a in range(26): for b in range(26): print(encrypt(c,a,b)) ``` 全探索すると候補が沢山出てきてFLAGを探すのが大変なので ``` $ python3 encrpt.py | grep FLAG ``` のようにすると`FLAG`という文字列を含む行だけを抜き出してくれる Flag --- `FLAG{WELCOMETOCRYPTOCHALLENGE}` ###### tags: `CTF` `WANICTF2021`