この大会は2017/2/25 18:00(JST)~2017/2/26 0:00(JST)に開催されました。
今回もチームで参戦。結果は335点で292チーム中6位でした。
自分で解けた問題をWriteupとして書いておきます。
Now you see me (Crypto 150)
スクリプトと暗号化されたPNGファイルが添付されている。
スクリプトを読むと、IDATのデータ部が4バイトごとに暗号化されていることがわかる。CRC部に鍵を暗号化しているので、まず鍵を復号して、その鍵を使って復号するコードを書く。
def bytes2reg(m): L = 8 pol = [] dic = {'1' : 1, '0' : 0} for i in m: b = bin(ord(i)).split('b') b = b[1] b = '0'*(L - len(b)) + b for c in b: pol.append(dic[c]) return pol def reg2bytes(pol): res = "" if len(pol) % 8 != 0: pol.extend([0 for _ in range(8 - (len(pol) % 8))]) b = [int(i) for i in pol] for i in range(4): ch = 0 pw = 7 for _ in range(8): ch += b.pop(0) * (2**pw) pw -= 1 res += chr(ch) return res def decrypt(c, k): dec = [0] * 32 + [i for i in c] for i in range(31, -1, -1): dec[i] = dec[32+i] ^ dec[31+i] ^ dec[16+i] ^ dec[1+i] ^ k[i] return dec[:32] def key_decrypt(c): dec = [0] * 32 + [i for i in c] for i in range(31, -1, -1): dec[i] = dec[31+i] ^ dec[30+i] ^ dec[15+i] return dec[:32] with open('file.png', 'rb') as f: file = f.read() flag = file[:file.find('IDAT')] flag += 'IDAT' p = file.find('IDAT') length = int(file[p-4:p].encode('hex'), 16) l = length - (length % 4) cnt = p + 4 + length + 4 e_key = file[cnt - 4:cnt] key = key_decrypt(bytes2reg(e_key)) data = file[p+4:p+length+4] for i in range(0, l, 4): block = data[i:i+4] block = bytes2reg(block) d = decrypt(block, key) flag += reg2bytes(d) flag += file[p + 4 + l:p + 4 + length] flag += reg2bytes(key) flag += file[cnt:] with open('flag.png', 'wb') as f: f.write(flag)
復号すると、画像にフラグが書いてある。
VolgaCTF{Th3r3_4r3_tw0_kind5_0f_crypt0gr4phy_in_7his_w0r1d}
Quiz (Joy 10)
クイズというかVolgaCTF 2017 Qualsの大会参加の意思表明みたいなものだった。
Yes