この大会は2023/3/11 17:00(JST)~2023/3/13 5:00(JST)に開催されました。
今回もチームで参戦。結果は301点で285チーム中106位でした。
自分で解けた問題をWriteupとして書いておきます。
Welcome (Misc)
Discordに入り、#announcementsチャネルのメッセージを見ると、フラグが書いてあった。
dvCTF{Welcome_to_the_DVCTF2023!}
Principiante (Prog)
各音階がアルファベットで提示されるので、鍵盤のアスキーアートで該当する箇所を"X"にして回答する。各音階は以下のようになり、#はその音階の右肩の黒鍵盤を指す。
ド C ド# C# レ D レ# D# ミ E ファ F ファ# F# ソ G ソ# G# ラ A ラ# A# シ B
何番目かというのも提示されるので、その左までは固定で構成する。該当する鍵盤を場合分けして構成する。構成した鍵盤の図を答えていけば、フラグが得られる。
#!/usr/bin/env python3 import socket def recvuntil(s, tail): data = b'' while True: if tail in data: return data.decode() data += s.recv(1) def display(index, key): outp = '' outp += '____________________________' * index + '_' + '\n' outp += '| | | | | | | | | | | | ' * index + '|' + '\n' outp += '| | | | | | | | | | | | ' * index + '|' + '\n' if key[-1] == "#": outp += '| | | | | | | | | | | | ' * (index - 1) if key[0] == 'C': outp += '| |X| | | | | | | | | | |' + '\n' elif key[0] == 'D': outp += '| | | |X| | | | | | | | |' + '\n' elif key[0] == 'F': outp += '| | | | | | |X| | | | | |' + '\n' elif key[0] == 'G': outp += '| | | | | | | | |X| | | |' + '\n' elif key[0] == 'A': outp += '| | | | | | | | | | |X| |' + '\n' else: outp += '| | | | | | | | | | | | ' * index + '|' + '\n' outp += '| |_| |_| | |_| |_| |_| ' * index + '|' + '\n' outp += '| | | | | | | ' * index + '|' + '\n' if key[-1] == "#": outp += '| | | | | | | ' * index + '|' + '\n' else: outp += '| | | | | | | ' * (index - 1) if key[0] == 'C': outp += '| X | | | | | | |' + '\n' elif key[0] == 'D': outp += '| | X | | | | | |' + '\n' elif key[0] == 'E': outp += '| | | X | | | | |' + '\n' elif key[0] == 'F': outp += '| | | | X | | | |' + '\n' elif key[0] == 'G': outp += '| | | | | X | | |' + '\n' elif key[0] == 'A': outp += '| | | | | | X | |' + '\n' elif key[0] == 'B': outp += '| | | | | | | X |' + '\n' outp += '|___|___|___|___|___|___|___' * index + '|' + '\n' print(outp) return outp.encode() s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('prog.dvc.tf', 7751)) for _ in range(12): data = recvuntil(s, b'\n').rstrip() print(data) data = recvuntil(s, b'\n').rstrip() print(data) index = int(data.split(' ')[3][0]) key = data.split(' ')[4] ans = display(index, key) s.sendall(ans) data = recvuntil(s, b'\n').rstrip() print(data)
実行結果は以下の通り。
n° 1 Give me the 3rd G# plz _____________________________________________________________________________________ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |X| | | | | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___| n° 2 D:\CTF\大会\22_DaVinciCTF\09_Prog\02_Principiante> D:\CTF\大会\22_DaVinciCTF\09_Prog\02_Principiante>python3 solve.py n° 1 Give me the 4th G# plz _________________________________________________________________________________________________________________ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |X| | | | | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___| n° 2 Give me the 1st D plz _____________________________ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |_| |_| | |_| |_| |_| | | | | | | | | | | | X | | | | | | |___|___|___|___|___|___|___| n° 3 Give me the 4th C plz _________________________________________________________________________________________________________________ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | X | | | | | | | |___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___| n° 4 Give me the 4th C# plz _________________________________________________________________________________________________________________ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |X| | | | | | | | | | | | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___| n° 5 Give me the 2nd A# plz _________________________________________________________ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |X| | | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |___|___|___|___|___|___|___|___|___|___|___|___|___|___| n° 6 Give me the 2nd G plz _________________________________________________________ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | | | | | | | | | | | | | | | | | | | | | | | | | | | | X | | | |___|___|___|___|___|___|___|___|___|___|___|___|___|___| n° 7 Give me the 2nd D# plz _________________________________________________________ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |X| | | | | | | | | | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |___|___|___|___|___|___|___|___|___|___|___|___|___|___| n° 8 Give me the 1st F plz _____________________________ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |_| |_| | |_| |_| |_| | | | | | | | | | | | | | X | | | | |___|___|___|___|___|___|___| n° 9 Give me the 1st B plz _____________________________ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |_| |_| | |_| |_| |_| | | | | | | | | | | | | | | | | X | |___|___|___|___|___|___|___| n° 10 Give me the 3rd E plz _____________________________________________________________________________________ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | X | | | | | |___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___| n° 11 Give me the 3rd F# plz _____________________________________________________________________________________ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |X| | | | | | | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___| n° 12 Give me the 3rd A plz _____________________________________________________________________________________ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | |_| |_| | |_| |_| |_| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | X | | |___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___| Noice, here is your flag : dvCTF{4r3_Y0U_7H3_N3X7_M0Z4r7?}
dvCTF{4r3_Y0U_7H3_N3X7_M0Z4r7?}
Vigenere XOR (Cryptography)
2進数としてデコードしたものをファイルに保存する。これをXOR Crackerでクラックする。一番の候補となるものの鍵の長さは6であるとわかる。最有力候補のファイルを保存する。
文中にフラグが崩れたような形式のデータがあるので、そのファイルを使って、調整するスクリプトで復号する。
#!/usr/bin/env python3 def is_printables(s): for c in s: if ord(c) < 32 or ord(c) > 126: return False return True with open('message', 'r') as f: codes = f.read() enc = b'' for i in range(0, len(codes), 8): enc += bytes([int(codes[i:i+8], 2)]) with open('enc', 'wb') as f: f.write(enc) flag_head = b'dvCTF{' with open('f21f33a5-033e-45c8-b12b-f69794be04d1', 'rb') as f: enc = f.read() index = enc.index(b'{') - 5 assert index % 6 == 0 key = b'' for i in range(len(flag_head)): key += bytes([enc[i+index] ^ flag_head[i]]) msg = '' for i in range(len(enc)): msg += chr(enc[i] ^ key[i % len(key)]) print(msg)
復号結果は以下の通り。
You did it! The flag is dvCTF{80R3D_K3Y_15_K3Y_MY_FR13ND}. Well done !
dvCTF{80R3D_K3Y_15_K3Y_MY_FR13ND}
Desintegrated RSA (Cryptography)
2048ビットのpが2ビット間違っているので、総当たりで反転し、nを割り切れるものを探す。p, qがわかれば、あとは通常通り復号する。
#!/usr/bin/env python3 from Crypto.Util.number import * with open('my_paper', 'r') as f: params = f.read().splitlines() e = int(params[0].split(' ')[-1]) N = int(params[1].split(' ')[-1]) c = int(params[2].split(' ')[-1]) str_p = eval(params[3].split(' ')[-1]) found = False for i in range(len(str_p)): for j in range(i + 1, len(str_p)): s = list(str_p) s[i] = str(int(s[i]) ^ 1) s[j] = str(int(s[j]) ^ 1) p = int(''.join(s), 2) if N % p == 0: found = True break if found: break q = N // p phi = (p - 1) * (q - 1) d = inverse(e, phi) m = pow(c, d, N) flag = long_to_bytes(m).decode() flag = 'dvCTF{%s}' % flag print(flag)
dvCTF{L30n4rd_M19ht_B3_0ld_But_5t1ll_Cunn1n9}