この大会は2023/6/17 0:30(JST)~2023/6/18 0:30(JST)に開催されました。
今回もチームで参戦。結果は3059点で605チーム中6位でした。
自分で解けた問題をWriteupとして書いておきます。
Sanity Check (Misc)
Discordに入り、#main-announcementsチャネルのメッセージを見ると、フラグが書いてあった。
BSidesIndore{mogaMb00_w3lcOmeS_y0u_to_CTF!!!}
Operation Cipher Vault, (Web)
入力文字列が短いと、以下のように表示される。
Error: Length too short
少しずつ長くしていく。
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Error: Length too short aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Error: Length too short aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Congratulations! You found the flag: BSidesIndore{br4v0_y0u_cr4ck3d_17}
BSidesIndore{br4v0_y0u_cr4ck3d_17}
Can you WIN from EVT? (Forensics)
ログイン失敗の数と、最後にログイン成功した日時を答える必要がある。ログイン成功、失敗のイベントログについては、Security.evtxを見ればよい。
ログイン失敗のイベントIDは4625なので、その条件でフィルタリングする。
その数は6であることがわかる。
ログイン成功のイベントIDは4624なので、その条件でフィルタリングし、日付と時刻でソートする。
最終時刻は2022/08/23 19:56:09であることがわかる。UTCの時刻にすると、2022/08/23 10:56:09。
BSidesIndore{6_8/23/2022_10:56:09AM}
Hide and Seek (Forensics)
$ zsteg challenge.png extradata:imagedata .. 00000000: 01 2f 23 00 ff 0a 0c 00 00 14 17 00 00 24 2e 03 |./#..........$..| 00000010: 00 ff 01 fe 00 f4 f1 00 00 d6 d3 ff 00 f1 ef 00 |................| 00000020: 00 03 01 00 00 0f 0f 00 00 1a 19 07 00 14 15 04 |................| 00000030: 00 f4 fd f9 00 fa fc 01 00 f9 fd 00 00 f2 f0 fc |................| 00000040: 00 f9 f6 ff 00 01 fb 05 00 f3 f0 fb 00 f7 f8 00 |................| 00000050: 00 fc fd 00 00 f1 f2 00 00 00 00 00 00 f5 f5 00 |................| 00000060: 00 06 06 00 00 2f 36 05 00 12 18 06 00 09 0b fe |...../6.........| 00000070: 00 fa f7 f7 00 00 fd 06 00 f5 ef fa 00 ef e8 00 |................| 00000080: 00 ff fe 00 00 fb fd 00 00 f4 f4 00 00 01 01 00 |................| 00000090: 00 0d 0d 01 00 20 20 08 00 0d 0c 02 00 02 03 fd |..... .........| 000000a0: 00 f3 f9 fd 00 f9 fb 02 00 eb eb fa 00 ee f0 01 |................| 000000b0: 00 fd fc ff 00 00 fe ff 00 0f 12 00 00 0b 0c 03 |................| 000000c0: 00 f9 fa fd 00 1a 16 0c 00 0e 0d 0a 00 fe fc f9 |................| 000000d0: 00 f1 f4 f1 00 fc fd 00 00 01 02 0a 00 eb ee ff |................| 000000e0: 00 f4 f3 fb 00 f6 f5 fc 00 f2 ee 00 00 05 03 00 |................| 000000f0: 00 11 12 00 00 26 2b 12 00 f3 f8 f4 00 f3 f4 fa |.....&+.........| imagedata .. file: Tower/XP rel 2 object not stripped b1,g,msb,xy .. file: OpenPGP Secret Key b1,rgb,lsb,xy .. text: "eTB1X2YwdW5kX20zISEhISEhISEhIX0" b1,bgr,lsb,xy .. text: "q<\"niS\tg" b4,b,lsb,xy .. file: PDP-11 kernel overlay b4,rgb,lsb,xy .. text: "\ta'\nA\" 2"
lsbにbase64らしき文字列がある。
$ echo eTB1X2YwdW5kX20zISEhISEhISEhIX0= | base64 -d y0u_f0und_m3!!!!!!!!!!}
IHDRチャンクにある画像の高さを大きくする。
画像の下にフラグの初めの部分が現れた。
BSidesIndore{H3y
"_"を追加して連結してフラグにする。
BSidesIndore{H3y_y0u_f0und_m3!!!!!!!!!!}
DiffieHellman (Cryptography)
暗号化の処理概要は以下の通り。
・p: 1024ビット素数 ・a, b, s: p未満ランダム整数 ・na, nb: p未満ランダム整数 ・A = compose_f(s, na) ・na回以下繰り返し ・z = f(z) ・z = (a * z + b) % p ・zを返却 ・B = compose_f(s, nb) ・shared_secret = compose_f(A, nb) ・m: flagの数値化したもの ・hint = (shared_secret * m) % p ・p, a, b, s, A, B, hintを表示
compose_f関数で2回までの計算は以下のようになっている。
s1 = (a * s0 + b) % p s2 = (a * s1 + b) % p
上記から以下の式が成り立つ。
s2 - s1 = a * (s1 - s0)
さらに汎用化し以下の式になる。
sn+1 - sn = a**n * (s1 - s0)
このことから次が言える。
(a * A + b - A) % p = a**na * (a * s + b - s) % p (a * B + b - B) % p = a**nb * (a * s + b - s) % p
以上からshared_secretをxと置くと、次の式が成り立つ。
(a * x + b - x) % p = a**(na + nb) * (a * s + b - s) % p = a**na * a**nb * (a * s + b - s) % p = (a * A + b - A) * (a * B + b - B) * inverse(a * s + b - s, p) % p
つまりxは以下の式で算出できる。
x = ((a * A + b - A) * (a * B + b - B) * inverse(a * s + b - s, p) - b) * inverse(a - 1, p) % p ||< あとはhintにxのinverseを掛ければflagになる。 >|python| #!/usr/bin/env python3 from Crypto.Util.number import * with open('output.txt', 'r') as f: params = f.read().splitlines() p = int(params[0].split(' ')[-1]) a = int(params[1].split(' ')[-1]) b = int(params[2].split(' ')[-1]) s = int(params[3].split(' ')[-1]) A = int(params[4].split(' ')[-1]) B = int(params[5].split(' ')[-1]) hint = int(params[6].split(' ')[-1]) shared_secret = ((a * A + b - A) * (a * B + b - B) * inverse(a * s + b - s, p) \ - b) * inverse(a - 1, p) % p m = hint * inverse(shared_secret, p) % p flag =long_to_bytes(m).decode() print(flag)
BSidesIndore{yOu_5hou1D_7ry_S0M3ThIn9_elSe_o7h3r_TH4n_lcg}
FeedBack (Misc)
アンケートに答えたら、フラグが表示された。
BSidesIndore{Sayonara}