SECCON ctf4b 2022
22 CoughingFox Write up
クソ雑魚ナメクジエンジニアによる CoughingFox の解法を...
問題
from random import shuffle
flag = b"ctf4b{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}"
cipher = []
for i in range(len(flag)):
f = flag[i]
c = (f + i)**2 + i
cipher.append(c)
shuffle(cipher)
print("cipher =", cipher)
cipher = [ 12147, 20481, 7073, 10408, 26615, 19066, 19363, 10852, 11705, 17445, 3028, 10640, 10623, 13243, 5789, 17436, 12348, 10818, 15891, 2818, 13690, 11671, 6410, 16649, 15905, 22240, 7096, 9801, 6090, 9624, 16660, 18531, 22533, 24381, 14909, 17705, 16389, 21346, 19626, 29977, 23452, 14895, 17452, 17733, 22235, 24687, 15649, 21941, 11472]
なるほど、
- Byteとしてflagを読み込む
-
i
番目の文字f
を
(f + i)**2 + i
しているらしい。 - 最後にシャッフルして順番をめちゃくちゃにするらしい
回答
与えられた数列を(f + i)**2 + i
の逆の手順で行えばいい。
具体的には
(c-i)**0.5 -i
すると、f
がでてくる。
平方根とってぴったりと整数で出てくるバイトはほぼクロだから、該当するバイトを復号し、複合に使用したi
の順でソートすればよい
import math
cipher = [
12147, 20481, 7073, 10408, 26615, 19066, 19363, 10852, 11705, 17445, 3028, 10640, 10623, 13243, 5789, 17436, 12348, 10818, 15891, 2818, 13690, 11671, 6410, 16649, 15905, 22240, 7096, 9801, 6090, 9624, 16660, 18531, 22533, 24381, 14909, 17705, 16389, 21346, 19626, 29977, 23452, 14895, 17452, 17733, 22235, 24687, 15649, 21941, 11472
]
flag = []
s = []
dic = dict()
for j in range(len(cipher)):
for i in range(len(cipher)):
f = (cipher[j] - i )** 0.5 - i
if f == math.floor(f):
ch = int(f).to_bytes(2, 'big').decode()
flag.append(ch)
dic[i] = ch
for i in range(len(dic)):
print(dic[i], end="")
復号に使用したi
で並び替えることにまったく気が付かなくてかなり時間をとられてしまったので反省。