RCTF 2017 Writeup(供養)
RCTF2017にチーム:Harekazeの一員として参加してました。チームとしては8問解き2060点、そのうち1問を私が解きました。
[Misc] baby enc 434pts
unzipするとOutuput.txtとenc.pyが渡される
hintにWindowsでやらないと結果が少し違うみたいなことが書かれてあるのでWindowsでスクリプトを組む
enc.pyの中身は
import codecs def enc(s, t): if t: l = list(map(ord, s)) return enc(''.join(list(map(chr, [l[i]^l[i+1] for i in range(len(l)-1)]))), t-1) else: return s with open('in.txt') as f: s = enc(f.read(), 5) with open('out.txt', 'w') as f: f.write(s)
となっており、in.txtの中身を暗号化してout.txtに出力している。
この暗号化一見復号は無理そうだが、flagに限ってのみ復号が可能である。
最終的な出力結果についてだが入力をl[]の配列とすると
return s = [l[0]^l[4]^l[1]^l5], l[1]^l[5]^l[2]^l[6], .....]
のようになる。flagの形式がRCTF{…..}でRCTF{
のここから5文字がわかることにより
l[0] = R l[4] = { l[1] = C l[5] = ?
のように考えればl[5]がわかる。l[5]がわかればl[6]がわかる。最後に}が現れることを考えてコードを組む。
あとはどこからRCTFの文字列が始まるかを探すだけだがそれは総当りしておけば良い
そんなわけでソルバ
import codecs def enc(s, t): if t: l = list(map(ord, s)) return enc(''.join(list(map(chr, [l[i]^l[i+1] for i in range(len(l)-1)]))), t-1) else: return s tmp="" with open('out.txt','r') as f: tmp=f.read() test = list(map(ord,tmp)) for i in range(len(test)-5): lis = list(map(ord,"RCTF{")) tmpi = i for j in range(len(test)-5-i): tmp = lis[j]^lis[j+1]^lis[j+4]^test[tmpi] tmpi+=1 if chr(tmp) == "}": lis.append(tmp) print(str(i)+" results: "+''.join(map(chr,lis))) break elif chr(tmp) == "\n": break elif tmp < 43: break else: lis.append(tmp)
変数名の付け方はひどいが気にするな!!
flag:RCTF{te1l_mE_tHe_wAy_you_so1ve_thIs}