この大会は2022/3/19 9:00(JST)~2022/3/20 21:00(JST)に開催されました。
今回もチームで参戦。結果は483点で632チーム中73位でした。
自分で解けた問題をWriteupとして書いておきます。
welcome (welcome)
Discordに入り、#announcementチャネルのメッセージを見ると、フラグが書いてあった。
zer0pts{3nj0y_th3_CTF_t0_W1N!!!!}
GitFile Explorer (web, warmup)
serviceはgithub, gitlab, bitbucketから選択できる。ソースコードを見ると、githubが単純なパス結合になっていて、該当するファイルを表示する。
URL: <Service>/<GitHub ID>/<Repository Name>/<Branch>/<File Path> ・<Service>: servceパラメータ ・<GitHub ID>: ownerパラメータ ・<Repository Name>: repoパラメータ ・<Branch>: branchパラメータ ・<File Path>: fileパラメータ
serviceには、"github"という文字列が含んでいることが必要。また、URLは^http.+\/\/.*(github|gitlab|bitbucket)にマッチしていることが必要。ディレクトリトラバーサルでこの条件を満たすようパラメータを指定する。
http://gitfile.ctf.zer0pts.com:8001/?service=https%2F%2Fgithub&owner=..%2F..&repo=..%2F..&branch=..&file=flag.txtにアクセスしたら、フラグが表示された。
zer0pts{foo/bar/../../../../../directory/traversal}
Anti-Fermat (crypto, warmup)
RSA暗号で、pは1024ビット素数、qはpのビット反転した数の次の素数。反転は以下の式で表せる。
p ^ ((1<<1024)-1) = 2**1024 - p - 1 ↓ q > 2**1024 - p - 1
qを1ずつ増やし(i=0, 1, ...)、以下の方程式を解き、整数解が得られるものを探す。
p * (2**1024 - p - 1 + i) = n
#!/usr/bin/env python3 from Crypto.Util.number import * from sympy import * n = 0x1ffc7dc6b9667b0dcd00d6ae92fb34ed0f3d84285364c73fbf6a572c9081931be0b0610464152de7e0468ca7452c738611656f1f9217a944e64ca2b3a89d889ffc06e6503cfec3ccb491e9b6176ec468687bf4763c6591f89e750bf1e4f9d6855752c19de4289d1a7cea33b077bdcda3c84f6f3762dc9d96d2853f94cc688b3c9d8e67386a147524a2b23b1092f0be1aa286f2aa13aafba62604435acbaa79f4e53dea93ae8a22655287f4d2fa95269877991c57da6fdeeb3d46270cd69b6bfa537bfd14c926cf39b94d0f06228313d21ec6be2311f526e6515069dbb1b06fe3cf1f62c0962da2bc98fa4808c201e4efe7a252f9f823e710d6ad2fb974949751 c = 0x60160bfed79384048d0d46b807322e65c037fa90fac9fd08b512a3931b6dca2a745443a9b90de2fa47aaf8a250287e34563e6b1a6761dc0ccb99cb9d67ae1c9f49699651eafb71a74b097fc0def77cf287010f1e7bd614dccfb411cdccbb84c60830e515c05481769bd95e656d839337d430db66abcd3a869c6348616b78d06eb903f8abd121c851696bd4cb2a1a40a07eea17c4e33c6a1beafb79d881d595472ab6ce3c61d6d62c4ef6fa8903149435c844a3fab9286d212da72b2548f087e37105f4657d5a946afd12b1822ceb99c3b407bb40e21163c1466d116d67c16a2a3a79e5cc9d1f6a1054d6be6731e3cd19abbd9e9b23309f87bfe51a822410a62 e = 65537 i = 0 found = False while True: p = symbols('p') q = 2**1024 - p - 1 + i eq = Eq(p * q - n, 0) sol = solve(eq, p) for p in sol: if p.is_Integer: found = True break if found: break i += 1 p = int(p) q = n // p assert p * q == n phi = (p - 1) * (q - 1) d = inverse(e, phi) m = pow(c, d, n) flag = long_to_bytes(m).decode() print(flag)
復号結果は以下の通り。
Good job! Here is the flag: +-----------------------------------------------------------+ | zer0pts{F3rm4t,y0ur_m3th0d_n0_l0ng3r_w0rks.y0u_4r3_f1r3d} | +-----------------------------------------------------------+
zer0pts{F3rm4t,y0ur_m3th0d_n0_l0ng3r_w0rks.y0u_4r3_f1r3d}
survey (survey)
アンケートに答えたら、フラグが表示された。
zer0pts{4r1g4t0_f0r_pl4y1ng_zer0pts_CTF!}