この大会は2019/6/29 20:00(JST)~2019/6/30 21:00(JST)に開催されました。
今回もチームで参戦。結果は4356点で327チーム中26位でした。
自分で解けた問題をWriteupとして書いておきます。
Welcome (Welcome)
Discordに入り、ピン止めされたメッセージを見ると、フラグが書いてあった。
ISITDTU{Welcome_everyone_to_ISITDTUCTF}
Old story (Crypto)
各要素の値は2の累乗になっているようだったので、2の何乗かを出してみる。
[19, 22, 14, 10, 22, 5, 18, 21, 22, 24, 46, 51, 13, 23, 13, 52, 24, 55, 14, 41, 26, 20, 21, 54, 25, 36, 2, 34, 29, 39, 18, 32, 14, 7, 58, 37, 24, 55, 10, 52, 14, 36, 18, 62]
64以下の値で構成されている。
$ echo 'ISITDTU' | base64 SVNJVERUVQo=
Base64のインデックスになっているように見えるので、それを前提にデコードする。
import string enc = [524288, 4194304, 16384, 1024, 4194304, 32, 262144, 2097152, 4194304, 16777216, 70368744177664, 2251799813685248, 8192, 8388608, 8192, 4503599627370496, 16777216, 36028797018963968, 16384, 2199023255552, 67108864, 1048576, 2097152, 18014398509481984, 33554432, 68719476736, 4, 17179869184, 536870912, 549755813888, 262144, 4294967296, 16384, 128, 288230376151711744, 137438953472, 16777216, 36028797018963968, 1024, 4503599627370496, 16384, 68719476736, 262144, 4611686018427387904] log = {} for i in range(64): log[2**i] = i codes = [] for e in enc: codes.append(log[e]) b64tbl = string.uppercase + string.lowercase + string.digits + '+/' b64enc = '' for code in codes: b64enc += b64tbl[code - 1] flag = b64enc.decode('base64') print flag
ISITDTU{r1c3_che55b0ard_4nd_bs64}
Easy RSA 1 (Crypto)
eが非常に大きいので、Wiener's Attackで復号する。
# wiener_attack.sage def wiener(e, n): m = 12345 c = pow(m, e, n) q0 = 1 list1 = continued_fraction(Integer(e)/Integer(n)) conv = list1.convergents() for i in conv: k = i.numerator() q1 = i.denominator() for r in range(30): for s in range(30): d = r*q1 + s*q0 m1 = pow(c, d, n) if m1 == m: return d q0 = q1 return None n = 137709853388874260067664060306224801065880567280896538344708662296491187670268243771581008615887329285442080267493172576517227603581814922784005894668293664250883858847270414696279127204843462302026428548409668060539273696154323753582118715764251826181439387752900169898505518594134423187783089073450520527969 e = 85605944479801539190292577400294315989703364683792339737453887619652946907819548388390076584246192710348319524405250340541547224543819349494488596679810310694697763188201375896240755682682520811114377302206659716598003967368992125832908158096663258971132148617761060030524535044970322206572134828548118438019 c = 22066874366908131522623165919721031154048372827959879486746669804284618882326621205522887800063326155288431192110879403482210420111408801477749097399368616494107231276644736023482237804800287810317122448198973027350599454646050497733117161743355379588761228932055556016302337519814538743706899009493572298224 d = wiener(e, n) m = pow(c, d, n) flag = ('%x' % m).decode('hex') print flag
ISITDTU{Thank5_f0r_4tt3nd1ng_0ur_C0nt3st}
Chaos (Crypto)
$ nc 104.154.120.223 8085 Your cipher key: 88/cc/,,/oo 00/xx/UU/II 33/cc/OO/DD 88/mm/~~/rr 00/uu/KK/$$/,, 88/pp/DD/LL 22/ii/UU/SS 77/ee/CC/__/$$ 11/yy/KK/DD 88/77/tt 33/xx/KK/OO 44/mm/||/ii 55/ff/**/pp 55/ii/GG/??/%% 11/88/zz 77/88/oo 88/ww/^^/dd 66/kk/((/gg 33/qq/DD/<</,, 99/rr/,,/gg 33/ll/EE/VV 44/xx/__/hh 88/nn/KK/&&/++ 44/cc/CC/II 88/mm/LL/++/__ 77/oo/``/oo 11/66/ww 66/hh/((/ww 77/pp/__/vv 11/ee/RR/((/## 55/mm/II/MM 44/uu/ZZ/ZZ 55/cc/++/pp 99/pp/PP/../%% 22/vv/CC/$$/<< 22/ss/AA/,,/?? 66/11/ff 99/qq/<</jj 22/88/ww 99/mm/PP/MM 88/dd/))/hh 22/vv/PP/NN 99/66/uu 44/tt/HH/!!/== 22/cc/CC/``/++ 77/bb/ZZ/MM 33/oo/SS/BB 22/vv/OO/HH 88/ss/HH/RR 11/aa/%%/rr 22/qq/??/mm 99/nn/%%/ll 22/kk/CC/OO 77/vv/@@/ee 33/ff/YY/DD 66/ee/XX/BB 99/bb/RR/@@/(( 77/rr/$$/hh 99/dd/DD/##/## 77/ii/JJ/WW 44/hh/EE/XX 44/ff/__/tt 33/00/gg 55/pp/HH/LL WELCOME TO CHAOS TOOL: Description: This is a tool which helps you hide the content of the message Notes: - Message cannot contain whitespace characters - Message can use all characters including punctuation marks and number - Decrypt the above key to get the flag, len(key) = 64 - All punctuation marks use in plain key: ~`!@#$%^&*()_-+=<,>.?| - Key is not a meaningful sentence - Find the rule in this tool **FEATURES** <1> Encrypt message <2> Get the flag Your choice: 1 Enter your message: 123 Here is your cipher: 11/00/jj 22/77/aa 33/00/aa **FEATURES** <1> Encrypt message <2> Get the flag Your choice: 2 Please enter the key to get flag: 123 WRONG KEY
何回か試してみると、この暗号の特徴は以下のようになっていることがわかった。
"/"区切りで3つの場合は数字で、平文は"/"区切りの1番目の文字 "/"区切りで4つの場合で、4つ目が英小文字の場合は英小文字で、平文は"/"区切りの2番目の文字 "/"区切りで4つの場合で、4つ目が英大文字の場合は英大文字で、平文は"/"区切りの3番目の文字 "/"区切りで5つの場合は記号で、平文は"/"区切りの5番目の文字
これを元に復号して、キーを指定する。
import socket import string def recvuntil(s, tail): data = '' while True: if tail in data: return data data += s.recv(1) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('104.154.120.223', 8085)) data = recvuntil(s, 'Your choice: ') print data + '1' s.sendall('1\n') ct = data.split('\n')[0].split(': ')[1] ct = ct.split(' ') chars = string.letters + string.digits + '~`!@#$%^&*()_-+=<,>.?|' data = recvuntil(s, ': ') print data + chars s.sendall(chars + '\n') pt = '' for c in ct: elems = c.split('/') if len(elems) == 3: pt += elems[0][0] elif len(elems) == 4: if elems[3][0] in string.lowercase: pt += elems[1][0] else: pt += elems[2][0] else: pt += elems[4][0] data = recvuntil(s, 'Your choice: ') print data + '2' s.sendall('2\n') data = recvuntil(s, ': ') print data + pt s.sendall(pt + '\n') data = s.recv(8192) print data
実行結果は以下の通り。
Your cipher key: 44/66/yy 44/qq/HH/../&& 00/rr/~~/zz 55/ww/--/gg 77/ll/LL/JJ 55/rr/QQ/||/.. 77/dd/GG/II 55/uu/LL/YY 66/nn/II/==/## 55/44/kk 99/99/ww 22/ee/``/yy 00/tt/))/rr 11/yy/ZZ/LL 77/dd/../uu 33/rr/GG/II 33/cc/**/tt 88/11/xx 88/77/zz 77/qq/QQ/((/?? 55/xx/SS/DD 66/aa/@@/dd 00/hh/||/vv 22/33/bb 33/oo/ZZ/**/!! 66/44/bb 44/bb/__/zz 99/mm/__/mm 55/88/ww 00/rr/EE/BB 99/ii/PP/||/)) 22/rr/<</ss 00/ll/BB/XX 77/ll/++/qq 99/tt/KK/GG 55/ww/&&/yy 99/bb/DD/LL 44/jj/>>/uu 22/dd/UU/TT 44/vv/NN/??/~~ 55/aa/JJ/--/|| 77/pp/II/FF 99/cc/HH/EE 22/jj/RR/MM 55/22/rr 33/yy/MM/AA 33/bb/KK/AA 33/qq/>>/ll 88/ff/++/ee 22/oo/TT/||/** 55/88/ii 22/aa/CC/KK 11/vv/UU/JJ 44/bb/SS/||/== 66/ll/ZZ/__/^^ 33/bb/EE/NN 11/cc/SS/,,/%% 55/ii/HH/++/.. 22/ff/))/pp 99/yy/>>/yy 99/uu/KK/QQ 22/qq/~~/ee 22/uu/++/zz 00/ww/PP/<</++ WELCOME TO CHAOS TOOL: Description: This is a tool which helps you hide the content of the message Notes: - Message cannot contain whitespace characters - Message can use all characters including punctuation marks and number - Decrypt the above key to get the flag, len(key) = 64 - All punctuation marks use in plain key: ~`!@#$%^&*()_-+=<,>.?| - Key is not a meaningful sentence - Find the rule in this tool **FEATURES** <1> Encrypt message <2> Get the flag Your choice: 1 Enter your message: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`!@#$%^&*()_-+=<,>.?| Here is your cipher: 77/aa/``/vv 55/bb/~~/ii 44/cc/@@/oo 00/dd/$$/qq 99/ee/,,/ll 44/ff/--/vv 44/gg/++/zz 66/hh/||/uu 00/ii/##/ii 00/jj/__/kk 77/kk/))/ee 44/ll/!!/dd 11/mm/,,/ff 44/nn/##/tt 88/oo/!!/vv 44/pp/>>/gg 77/qq/%%/qq 55/rr/../cc 66/ss/@@/ee 66/tt/``/ii 88/uu/%%/ll 11/vv/##/yy 33/ww/,,/ff 77/xx/??/uu 11/yy/##/ee 33/zz/&&/vv 66/cc/AA/WW 77/gg/BB/LL 55/ii/CC/KK 33/cc/DD/CC 22/gg/EE/HH 66/hh/FF/XX 77/dd/GG/OO 88/pp/HH/MM 22/xx/II/PP 55/zz/JJ/TT 11/kk/KK/OO 00/hh/LL/EE 22/tt/MM/II 88/yy/NN/LL 11/qq/OO/GG 11/tt/PP/TT 55/nn/QQ/LL 55/uu/RR/GG 66/uu/SS/AA 55/ww/TT/TT 77/oo/UU/YY 33/gg/VV/VV 44/mm/WW/WW 55/yy/XX/KK 55/ss/YY/PP 55/gg/ZZ/YY 00/99/jj 11/77/xx 22/22/uu 33/22/xx 44/88/ee 55/44/aa 66/77/yy 77/22/uu 88/11/ll 99/77/qq 00/ll/KK/++/~~ 44/cc/UU/**/`` 11/cc/FF/**/!! 77/bb/WW/>>/@@ 22/aa/FF/--/## 77/nn/GG/##/$$ 99/qq/JJ/__/%% 99/hh/RR/((/^^ 11/ii/QQ/++/&& 44/aa/EE/~~/** 44/hh/EE/,,/(( 88/ww/OO/%%/)) 88/ww/MM/~~/__ 44/gg/ZZ/$$/-- 99/gg/CC/@@/++ 77/qq/PP/==/== 99/xx/JJ/--/<< 44/uu/XX/~~/,, 66/uu/RR/--/>> 11/zz/OO/++/.. 33/ff/TT/&&/?? 00/qq/KK/``/|| **FEATURES** <1> Encrypt message <2> Get the flag Your choice: 2 Please enter the key to get flag: 4&rwL.GL#59etZdGc88?Sah2!6bm5E)rBlKwDjU~|IHR5MKqf*5CU=^E%.fyKqu+ Good job! Here is your flag: ISITDTU{Hav3_y0u_had_a_h3adach3??_Forgive_me!^^}
ISITDTU{Hav3_y0u_had_a_h3adach3??_Forgive_me!^^}
decrypt to me (Crypto)
prgの生成はフラグのbit長にのみ依存する。暗号化のbit長がわかるので、それから+8bit以内で正しいprgが得られるので、逆算してフラグを導く。
from Crypto.Util.number import * def generate_prg_bit(n): state = n while True: last_bit = state & 1 yield last_bit middle_bit = state >> len(bin(n)[2:])//2 & 1 state = (state >> 1) | ((last_bit ^ middle_bit) << (len(bin(n)[2:])-1)) enc = 'OKQI+f9R+tHEJJGcfko7Ahy2AuL9c8hgtYT2k9Ig0QyXUvsj1B9VIGUZVPAP2EVD8VmJBZbF9e17' n = bytes_to_long(enc.decode('base64')) enc_bin_text = bin(n)[2:] prg_n = len(enc_bin_text) tmp_enc_bin_text = enc_bin_text while True: prg = generate_prg_bit(prg_n) flag_bits = [] for i in range(prg_n): flag_bits.append(int(tmp_enc_bin_text[i]) ^ next(prg)) plaintext = '0b' + ''.join(map(str, flag_bits)) n = int(plaintext, 2) flag = long_to_bytes(n) if 'ISITDTU{' in flag: print flag break tmp_enc_bin_text = '0' + tmp_enc_bin_text prg_n += 1
ISITDTU{Encrypt_X0r_N0t_Us3_Pseud0_Rand0m_Generat0r!!!!!}
Do you like math? (Programming)
$ nc 104.154.120.223 8083 # ##### # # ## # # # # # ## # # # # # # # # ##### # ##### ##### # # # # # # ####### # ##### # # # # # # ##### ##### # ##### >>> ASCIIアートで算数の問題が出題される。 全文字のパターンを見てみる。 $ nc 104.154.120.223 8083 # ####### ##### ##### ## # # # # # # # # # # ##### # ###### ##### ##### ##### # # # # ##### # # # # # # ##### ##### ##### ####### >>> $ nc 104.154.120.223 8083 ####### ### ##### ### # # # # # # # # # # # # # # # # # ##### ###### # # ####### ##### # # # # # # # # # # ##### # # # # # # # # # # ##### ### ##### ### >>> $ nc 104.154.120.223 8083 ##### # ##### # # # # # # # # # # # # # # # ##### ##### ####### # # ###### # # # # ####### # # ##### # # # # # # # ##### # ##### >>> $ nc 104.154.120.223 8083 # ####### # ##### # # # # # # # # # # # # # # # # # # ##### # # # ####### # # ##### ####### # # # ####### # ##### # # # # # # # # # ####### >>> $ nc 104.154.120.223 8083 ##### ##### # # # # # # # ## ## # # # # # # # # ##### ##### ###### ##### # # # # # # # ##### # # # # # # # ##### ##### ##### ##### >>>
縦にスペースが並ぶ列を区切りとして、各数字と記号のパターンを比較し、数式をパースする。あとは計算して答えていく。
import socket def recvuntil(s, tail): data = '' while True: if tail in data: return data data += s.recv(1) def get_char(s): if s == ' ### # # # ## ## # # # ### ': return '0' elif s == ' # # # ######## # #': return '1' elif s == ' # #### # ## # ## # ## # ## # # ## #': return '2' elif s == ' # # # # ## # ## # ## # ## # # ## ## ': return '3' elif s == '##### # # # # ###### # ': return '4' elif s == '#### # # # ## # ## # ## # ## # ## ## ': return '5' elif s == ' ##### # # ## # ## # ## # ## # # # ## ': return '6' elif s == '## # # #### # # # ## # ': return '7' elif s == ' ## ## # # ## # ## # ## # ## # # ## ## ': return '8' elif s == ' ## # # # ## # ## # ## # ## # # ##### ': return '9' elif s == ' # # ##### # # ': return '+' elif s == ' # # # # # ': return '-' elif s == ' # # # # ### # ### # # # # ': return '*' elif s == ' # # # # # # # # # # ': return '=' else: return '' def get_formula(lines): formula = '' char_str = '' for x in range(len(lines[0])): sp_flg = True tmp_char = '' for y in range(len(lines)): tmp_char += lines[y][x] if lines[y][x] != ' ': sp_flg = False if sp_flg: formula += get_char(char_str) char_str = '' else: char_str += tmp_char return formula s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('104.154.120.223', 8083)) for i in range(100): print '\nRound %d' % (i+1) data = '' for j in range(9): data += recvuntil(s, '\n') print data d = data.split('\n')[1:-2] formula = get_formula(d) ans = str(eval(formula.rstrip('='))) data = recvuntil(s, '>>> ') print data + ans s.sendall(ans + '\n') data = s.recv(8192) print data
100回正解したら、フラグが表示された。
ISITDTU{sub5cr1b3_b4_t4n_vl0g_4nd_p3wd13p13}
Pytecode (Reverse)
Pythonのアセンブラが添付されている。チェック処理を上から見ていく。
9 6 LOAD_GLOBAL 0 (ord) 9 LOAD_FAST 0 (flag) 12 LOAD_CONST 1 (0) 15 BINARY_SUBSCR 16 CALL_FUNCTION 1 19 LOAD_CONST 2 (52) 22 BINARY_ADD 23 LOAD_GLOBAL 0 (ord) 26 LOAD_FAST 0 (flag) 29 LOAD_CONST 3 (-1) 32 BINARY_SUBSCR 33 CALL_FUNCTION 1 36 COMPARE_OP 3 (!=) 39 POP_JUMP_IF_TRUE 78 42 LOAD_GLOBAL 0 (ord) 45 LOAD_FAST 0 (flag) 48 LOAD_CONST 3 (-1) 51 BINARY_SUBSCR 52 CALL_FUNCTION 1 55 LOAD_CONST 4 (2) 58 BINARY_SUBTRACT 59 LOAD_GLOBAL 0 (ord) 62 LOAD_FAST 0 (flag) 65 LOAD_CONST 5 (7) 68 BINARY_SUBSCR 69 CALL_FUNCTION 1 72 COMPARE_OP 3 (!=) 75 POP_JUMP_IF_FALSE 88 ord(flag[0]) + 52 = ord(flag[-1]) ord(flag[-1]) - 2 = ord(flag[7]) ★まだ具体的な文字はわからないので保留(1) 11 >> 88 LOAD_FAST 0 (flag) 91 LOAD_CONST 5 (7) 94 SLICE+2 95 LOAD_CONST 6 ('ISITDTU') 98 COMPARE_OP 3 (!=) 101 POP_JUMP_IF_FALSE 120 flag[:7] = 'ISITDTU' ここで保留(1)を考える。 ・flag[-1] == chr(73 + 52) == '}' ・flag[7] = chr(73 + 52 - 2) == '{' 11111111112222222222 012345678901234567890123456789 ISITDTU{ } 13 >> 120 LOAD_FAST 0 (flag) 123 LOAD_CONST 7 (9) 126 BINARY_SUBSCR 127 LOAD_FAST 0 (flag) 130 LOAD_CONST 8 (14) 133 BINARY_SUBSCR 134 COMPARE_OP 3 (!=) 137 POP_JUMP_IF_TRUE 180 140 LOAD_FAST 0 (flag) 143 LOAD_CONST 8 (14) 146 BINARY_SUBSCR 147 LOAD_FAST 0 (flag) 150 LOAD_CONST 9 (19) 153 BINARY_SUBSCR 154 COMPARE_OP 3 (!=) 157 POP_JUMP_IF_TRUE 180 160 LOAD_FAST 0 (flag) 163 LOAD_CONST 9 (19) 166 BINARY_SUBSCR 167 LOAD_FAST 0 (flag) 170 LOAD_CONST 10 (24) 173 BINARY_SUBSCR 174 COMPARE_OP 3 (!=) 177 POP_JUMP_IF_FALSE 193 flag[9] == flag[14] flag[14] == flag[19] flag[19] == flag[24] →"_"のことを言っているのか? 11111111112222222222 012345678901234567890123456789 ISITDTU{ _ _ _ _ } 15 >> 193 LOAD_GLOBAL 0 (ord) 196 LOAD_FAST 0 (flag) 199 LOAD_CONST 12 (8) 202 BINARY_SUBSCR 203 CALL_FUNCTION 1 206 LOAD_CONST 13 (49) 209 COMPARE_OP 3 (!=) 212 POP_JUMP_IF_TRUE 235 215 LOAD_FAST 0 (flag) 218 LOAD_CONST 12 (8) 221 BINARY_SUBSCR 222 LOAD_FAST 0 (flag) 225 LOAD_CONST 14 (16) 228 BINARY_SUBSCR 229 COMPARE_OP 3 (!=) 232 POP_JUMP_IF_FALSE 245 ord(flag[8]) == 49 flag[8] == flag[16] →flag[8] == flag[16] == '1' 11111111112222222222 012345678901234567890123456789 ISITDTU{1_ _ 1 _ _ } 17 >> 245 LOAD_FAST 0 (flag) 248 LOAD_CONST 15 (10) 251 LOAD_CONST 8 (14) 254 SLICE+3 255 LOAD_CONST 16 ('d0nT') 258 COMPARE_OP 3 (!=) 261 POP_JUMP_IF_FALSE 277 flag[10:14] == 'd0nT' 11111111112222222222 012345678901234567890123456789 ISITDTU{1_d0nT_ 1 _ _ } 19 >> 277 LOAD_GLOBAL 4 (int) 280 LOAD_FAST 0 (flag) 283 LOAD_CONST 17 (18) 286 BINARY_SUBSCR 287 CALL_FUNCTION 1 290 LOAD_GLOBAL 4 (int) 293 LOAD_FAST 0 (flag) 296 LOAD_CONST 18 (23) 299 BINARY_SUBSCR 300 CALL_FUNCTION 1 303 BINARY_ADD 304 LOAD_GLOBAL 4 (int) 307 LOAD_FAST 0 (flag) 310 LOAD_CONST 19 (28) 313 BINARY_SUBSCR 314 CALL_FUNCTION 1 317 BINARY_ADD 318 LOAD_CONST 7 (9) 321 COMPARE_OP 3 (!=) 324 POP_JUMP_IF_TRUE 347 327 LOAD_FAST 0 (flag) 330 LOAD_CONST 17 (18) 333 BINARY_SUBSCR 334 LOAD_FAST 0 (flag) 337 LOAD_CONST 19 (28) 340 BINARY_SUBSCR 341 COMPARE_OP 3 (!=) 344 POP_JUMP_IF_FALSE 357 int(flag[18]) + int(flag[23]) + int(flag[28]) == 9 flag[18] == flag[28] ★まだ具体的な文字はわからないので保留(2) 11111111112222222222 012345678901234567890123456789 ISITDTU{1_d0nT_ 1 _ _ } 21 >> 357 LOAD_FAST 0 (flag) 360 LOAD_CONST 20 (15) 363 BINARY_SUBSCR 364 LOAD_CONST 21 ('L') 367 COMPARE_OP 3 (!=) 370 POP_JUMP_IF_FALSE 386 flag[15] == 'L' 11111111112222222222 012345678901234567890123456789 ISITDTU{1_d0nT_L1 _ _ } 23 >> 386 LOAD_GLOBAL 0 (ord) 389 LOAD_FAST 0 (flag) 392 LOAD_CONST 22 (17) 395 BINARY_SUBSCR 396 CALL_FUNCTION 1 399 LOAD_CONST 23 (-10) 402 BINARY_XOR 403 LOAD_CONST 24 (-99) 406 COMPARE_OP 3 (!=) 409 POP_JUMP_IF_FALSE 422 ord(flag[17]) == (-10) ^ (-99) →flag[17] == chr(107) == 'k' 11111111112222222222 012345678901234567890123456789 ISITDTU{1_d0nT_L1k _ _ } 25 >> 422 LOAD_GLOBAL 0 (ord) 425 LOAD_FAST 0 (flag) 428 LOAD_CONST 25 (20) 431 BINARY_SUBSCR 432 CALL_FUNCTION 1 435 LOAD_CONST 4 (2) 438 BINARY_ADD 439 LOAD_GLOBAL 0 (ord) 442 LOAD_FAST 0 (flag) 445 LOAD_CONST 26 (27) 448 BINARY_SUBSCR 449 CALL_FUNCTION 1 452 COMPARE_OP 3 (!=) 455 POP_JUMP_IF_TRUE 502 458 LOAD_GLOBAL 0 (ord) 461 LOAD_FAST 0 (flag) 464 LOAD_CONST 26 (27) 467 BINARY_SUBSCR 468 CALL_FUNCTION 1 471 LOAD_CONST 27 (123) 474 COMPARE_OP 4 (>) 477 POP_JUMP_IF_TRUE 502 480 LOAD_GLOBAL 0 (ord) 483 LOAD_FAST 0 (flag) 486 LOAD_CONST 25 (20) 489 BINARY_SUBSCR 490 CALL_FUNCTION 1 493 LOAD_CONST 28 (97) 496 COMPARE_OP 0 (<) 499 POP_JUMP_IF_FALSE 515 ord(flag[20]) + 2 == ord(flag[27]) ord(flag[27]) <= 123 ord(flag[20]) >= 97 ★まだ具体的な文字はわからないので保留(3) 11111111112222222222 012345678901234567890123456789 ISITDTU{1_d0nT_L1k _ _ } 27 >> 515 LOAD_GLOBAL 0 (ord) 518 LOAD_FAST 0 (flag) 521 LOAD_CONST 26 (27) 524 BINARY_SUBSCR 525 CALL_FUNCTION 1 528 LOAD_CONST 29 (100) 531 BINARY_MODULO 532 LOAD_CONST 1 (0) 535 COMPARE_OP 3 (!=) 538 POP_JUMP_IF_FALSE 551 ord(flag[27]) % 100 == 0 →ord(flag[27]) == 100 →flag[27] == 'd' ここで保留(3)を考える。 flag[20] == 'b' 11111111112222222222 012345678901234567890123456789 ISITDTU{1_d0nT_L1k _b _ d } 29 >> 551 LOAD_FAST 0 (flag) 554 LOAD_CONST 30 (25) 557 BINARY_SUBSCR 558 LOAD_CONST 31 ('C') 561 COMPARE_OP 3 (!=) 564 POP_JUMP_IF_FALSE 580 flag[25] = 'C' 11111111112222222222 012345678901234567890123456789 ISITDTU{1_d0nT_L1k _b _C d } 31 >> 580 LOAD_GLOBAL 0 (ord) 583 LOAD_FAST 0 (flag) 586 LOAD_CONST 32 (26) 589 BINARY_SUBSCR 590 CALL_FUNCTION 1 593 LOAD_CONST 4 (2) 596 BINARY_MODULO 597 LOAD_CONST 1 (0) 600 COMPARE_OP 3 (!=) 603 POP_JUMP_IF_TRUE 675 606 LOAD_GLOBAL 0 (ord) 609 LOAD_FAST 0 (flag) 612 LOAD_CONST 32 (26) 615 BINARY_SUBSCR 616 CALL_FUNCTION 1 619 LOAD_CONST 33 (3) 622 BINARY_MODULO 623 LOAD_CONST 1 (0) 626 COMPARE_OP 3 (!=) 629 POP_JUMP_IF_TRUE 675 632 LOAD_GLOBAL 0 (ord) 635 LOAD_FAST 0 (flag) 638 LOAD_CONST 32 (26) 641 BINARY_SUBSCR 642 CALL_FUNCTION 1 645 LOAD_CONST 34 (4) 648 BINARY_MODULO 649 LOAD_CONST 1 (0) 652 COMPARE_OP 3 (!=) 655 POP_JUMP_IF_TRUE 675 658 LOAD_FAST 0 (flag) 661 LOAD_CONST 32 (26) 664 BINARY_SUBSCR 665 LOAD_ATTR 5 (isdigit) 668 CALL_FUNCTION 0 671 UNARY_NOT 672 POP_JUMP_IF_FALSE 685 ord(flag[26]) % 2 == 0 ord(flag[26]) % 3 == 0 ord(flag[26]) % 4 == 0 flag[26]は数値 →flag[26]は'0' 11111111112222222222 012345678901234567890123456789 ISITDTU{1_d0nT_L1k _b _C0d } 33 >> 685 LOAD_GLOBAL 4 (int) 688 LOAD_FAST 0 (flag) 691 LOAD_CONST 18 (23) 694 BINARY_SUBSCR 695 CALL_FUNCTION 1 698 LOAD_CONST 33 (3) 701 COMPARE_OP 3 (!=) 704 POP_JUMP_IF_FALSE 720 int(flag[23]) == 3 ここで保留(2)を考える。 int(flag[18]) + int(flag[28]) == 9 - 3 flag[18] == flag[28] → flag[18] == flag[28] == '3' 11111111112222222222 012345678901234567890123456789 ISITDTU{1_d0nT_L1k3_b 3_C0d3} 35 >> 720 LOAD_FAST 0 (flag) 723 LOAD_CONST 35 (22) 726 BINARY_SUBSCR 727 LOAD_FAST 0 (flag) 730 LOAD_CONST 36 (13) 733 BINARY_SUBSCR 734 LOAD_ATTR 6 (lower) 737 CALL_FUNCTION 0 740 COMPARE_OP 3 (!=) 743 POP_JUMP_IF_FALSE 756 flag[22] == flag[13].lower() 11111111112222222222 012345678901234567890123456789 ISITDTU{1_d0nT_L1k3_b t3_C0d3} 42 791 LOAD_FAST 2 (tmp) 794 LOAD_GLOBAL 0 (ord) 797 LOAD_FAST 3 (i) 800 CALL_FUNCTION 1 803 INPLACE_ADD 804 STORE_FAST 2 (tmp) 807 JUMP_ABSOLUTE 785 >> 810 POP_BLOCK 43 >> 811 LOAD_FAST 2 (tmp) 814 LOAD_CONST 37 (2441) 817 COMPARE_OP 3 (!=) 820 POP_JUMP_IF_FALSE 833 フラグ全体のASCIIコードの合計は2441。 このことから残りの文字のASCIIコードを算出し、文字を割り出す。
tmp_flag = 'ISITDTU{1_d0nT_L1k3_b\x00t3_C0d3}' sum_code = 0 for c in tmp_flag: sum_code += ord(c) code = 2441 - sum_code flag = tmp_flag.replace('\x00', chr(code)) print flag
ISITDTU{1_d0nT_L1k3_b:t3_C0d3}
Survey (Thank you)
アンケートに答えたら、フラグが表示された。
ISITDTU{thank_you_for_your_feedback}