SECCON Beginners CTF 2022 writeup
6月4日の14時から24時間開催されていたSECCON Beginners CTF 2022にWani Hackase で参戦して5位でした。 普段のreversing担当が不在だったので、reversingとcryptoを担当しました。 WinTLS [reversing, 102 solved] Windowsというだけで忌避していたこの手の問題に、久しぶりに挑戦しました。 .rdataを漁っていると香ばしい文字列(c4{f..., tfb%...)があったのでxrefで参照元を見に行きます。 2つのスレッドで文字列を処理していて、flagのインデックスに応じて2つの文字列に振り分けているようです。 操作は単純なので逆の操作をしてあげると、文字列を復元できます。 1t1 = b"c4{fAPu8#FHh2+0cyo8$SWJH3a8X" 2t2 = b"tfb%s$T9NvFyroLh@89a9yoC3rPy&3b}" 3 4flag = [] 5k1, k2 = 0, 0 6for i in range(len(t1+t2)): 7 if i % 3 == 0 or i % 5 == 0: 8 flag.append(t1[k1]) 9 k1 += 1 10 else: 11 flag.append(t2[k2]) 12 k2 += 1 13 14print(bytes(flag)) Flag: ctf4b{f%sAP$uT98Nv#FFHyrh2o+Lh0@8c9yoa98$ySoCW3rJPH3y&a83Xb} ところで、UndefinedFunctionがめちゃくちゃ見にくい…… Recursive [reversing, 127 solved] 再帰で文字列をぐちゃぐちゃにしてあります。 少しreversingをすると文字列長が書いてあるので、処理前の文字列が処理後にどこに配置されるかが分かれば、逆操作で元に戻せます。 1from string import printable 2 3table = b"ct`*f4(+bc95\".81b{hmr3c/}r@:{&;514od*<h,n'dmxw?leg(yo)ne+j-{(`q/rr3|($0+5s.z{_ncaur${s1v5%!p)h!q't<=l@_8h93_woc4ld%>?cba<dagx|l<b/y,y`k-7{=;{&8,8u5$kkc}@7q@<tm03:&,f1vyb'8%dyl2(g?717q#u>fw()voo$6g):)_c_+8v.gbm(%$w(<h:1!c'ruv}@3`ya!r5&;5z_ogm0a9c23smw-.i#|w{8kepfvw:3|3f5<e@:}*,q>sg!bdkr0x7@>h/5*hi<749'|{)sj1;0,$ig&v)=t0fnk|03j\"}7r{}ti}?_<swxju1k!l&db!j:}!z}6*`1_{f1s@3d,vio45<_4vc_v3>hu3>+byvq##@f+)lc91w+9i7#v<r;rr$u@(at>vn:7b`jsmg6my{+9m_-rypp_u5n*6.}f8ppg<m-&qq5k3f?=u1}m_?n9<|et*-/%fgh.1m(@_3vf4i(n)s2jvg0m4" 4 5FLAG_LEN = 0x28 6t = printable[: FLAG_LEN - 2] 7flag = [0 for _ in range(FLAG_LEN)] 8 9def check(s, i): 10 n = len(s) 11 if n == 1: 12 flag[t.index(s)] = table[i] 13 return 14 else: 15 m = n // 2 16 check(s[:m], i) 17 check(s[m:], m * m + i) 18 19check(t, 0) 20print(bytes(flag)) Flag: ctf4b{r3curs1v3_c4l1_1s_4_v3ry_u53fu1} ...