💭
picoCTF-writeup Vigenere
問題
cipher.txt
rgnoDVD{O0NU_WQ3_G1G3O3T3_A1AH3S_f85729e7}
解答
暗号文と鍵が与えられているため、暗号化アルゴリズムを特定する問題である。
暗号文の3文字目(n)と5文字目(D)が異なっている。
解答形式はpicoCTF{}であることから、アルファベットを一文字ごとに異なる変化量で暗号化していることがわかる。
rgnoDVDはpicoCTFに変換されるものとして、各文字の変化量を求める。
p > r (2)
i > g (24)
c > n (11)
o > o (0)
c > d (1)
t > v (2)
f > d (24)
p,iとt,fの変化量が一致している。
7文字しか確認できていないため不確定ではあるが、5文字で変化量がループしていそうなことが分かる。
変化量のワンループが5文字とすると、鍵として与えられている"CYLAB"の文字数と一致する。
鍵のaを基準とした変化量を求める。
c:2
y:24
l:11
a:0
b:1
これが暗号文の変化量と一致したため、この暗号は平文一文字ずつに対して鍵一文字をずらしながらの相対距離分アルファベットをシフトするアルゴリズムであることがわかる。
そのため暗号文一文字ずつに鍵を一文字ずつずらしながらアルファベットを鍵の数値分マイナス方向にシフトする。
picoCTF{O0LW_WP3_V1F3Q3T3_C1AG3U_f85729d7}
それらしい文字列になったが間違い。
asciicodeに変換してシフトするかとも考えたが{}部分もずれるため却下。
鍵をずらすタイミングをアルファベットをシフトしたときのみに変更して変換を試したところ、flagが得られた。
import string
ALPHABET=string.ascii_uppercase
alphabet=string.ascii_lowercase
number=string.digits
key="cylab"
text=input("crypt:")
result=""
i=0
for c in text:
if(c in ALPHABET):
result+=ALPHABET[(ALPHABET.index(c)-alphabet.index(key[i%len(key)]))%26]
i+=1
elif(c in alphabet):
result+=alphabet[(alphabet.index(c)-alphabet.index(key[i%len(key)]))%26]
i+=1
else:
result+=c
print(result)
picoCTF{D0NT_US3_V1G3N3R3_C1PH3R_d85729g7}
Discussion