ASIS CTF Quals 2019 - A delicious soup Writeup

暗号化されたflagであるflag.encとflagを暗号化するsimple_and_delicious.py が与えられる。

simple_and_delicious.pyでは次のような処理をしている。

  1. 先頭の文字を末尾に移動(abcd -> bcda)
  2. 文字列を奇数番目の文字と偶数番目の文字に分け、奇数番目、偶数番目の順で連結(bcda -> bdca)
  3. 先頭の文字を末尾に移動(bdca -> dcab)
  4. 長さ7の変換テーブルに従い文字列をシャッフル(テーブルが[2, 3, 0, 1]の場合、dcab -> abdc)
  5. 1.から4.を1337回以下の規定の回数繰り返す

ここで、4.と5.は暗号化処理の実行のタイミングでランダムに決まる。上記の処理の逆を実装し、変換テーブルとイテレーションの回数を総当たりで試すことでflagが手に入る。

import itertools

enc_flag = "11d.3ilVk_d3CpIO_4nlS.ncnz3e_0S}M_kn5scpm345n3nSe_u_S{iy__4EYLP_aAAall"


def decrypt(msg, perm):
    res = []
    W = len(perm)
    for j in range(0, len(msg), W):
        for k in range(W):
            res.append(msg[j:j+W][perm[k]])
    res = list(res[-1]) + res[:-1]
    s = []
    for i in range(len(res) // 2):
        s.append(res[i])
        s.append(res[i + len(res) // 2])
    res = s
    res = list(res[-1]) + res[:-1]
    return "".join(res)


perm = range(7)
for p in itertools.permutations(perm):
    print(p)
    flag = enc_flag
    for _ in range(1338):
        flag = decrypt(flag, p)
        if flag[:5] == "ASIS{":
            print(flag)
            exit()

ASIS{1n54n3ly_Simpl3_And_d3lic1Ous_5n4ckS_eVEn_l4zY_Pe0pL3_Can_Mak3}