この大会は2019/8/24 23:30(JST)~2019/8/25 15:30(JST)に開催されました。
今回は個人で参戦。結果は1000点で319チーム中38位でした。
解けた問題をWriteupとして書いておきます。
Image Corruption (Max Score: 100)
開けないbmpが添付されている。バイナリエディタで見てみる。
matrixという文字がたくさん入っているので、matrixとXORしてみる。
with open('image.bmp', 'rb') as f: enc = f.read() key = 'matrix' flag = '' for i in range(len(enc)): code = ord(enc[i]) ^ ord(key[i%len(key)]) flag += chr(code) with open('flag.bmp', 'wb') as f: f.write(flag)
フラグが書かれたbmpファイルになった。
CodefestCTF{f1l35_h4v3_m461c_by735}
Mail capture (Max Score: 100)
添付ファイルにはこう書いてある。
begin 664 flag_encoded E0V]D969E<W1#5$9[-V@Q-5\Q-5\T7V,P,#%?,VYC,&0Q;CE]"@`` ` end
uuencodeとすぐにわかったので、uudecodeする。
with open('encoded_file', 'r') as f: enc = f.read() flag = enc.decode('uu') print flag
CodefestCTF{7h15_15_4_c001_3nc0d1n9}
Weird encoding (Max Score: 200)
添付ファイルにはこう書いてある。
0x85+1x1+0x14 0x7+1x1+0x7+1x1+0x9+1x2+0x3+1x4+0x3+1x1+0x6+1x5+0x1+1x1+0x2+1x1+0x1+1x2+0x13+1x2+0x3+1x1+0x8+1x1+0x5+1x2+0x8 0x1+1x5+0x18+1x3+0x3+1x1+0x16+1x2+0x1+1x1+0x5+1x2+0x2+1x1+0x3+1x1+0x4+1x2+0x3+1x3+0x3+1x1+0x2+1x2+0x4+1x3+0x8 0x3+1x1+0x7+1x1+0x11+1x2+0x1+1x1+0x3+1x5+0x12+1x1+0x2+1x1+0x7+1x1+0x10+1x1+0x3+1x2+0x1+1x1+0x5+1x3+0x4+1x1+0x1+1x2+0x2+1x1+0x4 0x3+1x1+0x3+1x1+0x7+1x2+0x3+1x1+0x2+1x1+0x2+1x1+0x7+1x1+0x11+1x2+0x2+1x2+0x5+1x2+0x10+1x1+0x3+1x1+0x2+1x1+0x3+1x2+0x2+1x1+0x4+1x4+0x7 0x3+1x1+0x3+1x1+0x3+1x1+0x1+1x3+0x10+1x1+0x7+1x1+0x7+1x1+0x3+1x1+0x3+1x1+0x1+1x2+0x2+1x3+0x8+1x5+0x4+1x1+0x3+1x9+0x1+1x3+0x7 0x3+1x1+0x3+1x3+0x1+1x1+0x1+1x4+0x9+1x1+0x6+1x2+0x2+1x1+0x7+1x2+0x3+1x1+0x2+1x1+0x4+1x1+0x10+1x1+0x6+1x1+0x7+1x1+0x7+1x4+0x4 0x5+1x1+0x1+1x1+0x1+1x1+0x1+1x1+0x4+1x2+0x7+1x2+0x3+1x4+0x11+1x1+0x4+1x1+0x2+1x1+0x3+1x2+0x6+1x1+0x3+1x1+0x6+1x1+0x7+1x1+0x1+1x1+0x1+1x5+0x7 0x7+1x1+0x1+1x1+0x1+1x1+0x2+1x3+0x7+1x5+0x16+1x1+0x4+1x1+0x2+1x1+0x1+1x3+0x3+1x6+0x2+1x1+0x2+1x1+0x1+1x5+0x5+1x1+0x2+1x1+0x4+1x1+0x7 0x18+1x5+0x13+1x6+0x27+1x1+0x14+1x1+0x2+1x2+0x2+1x1+0x5+1x1+0x2 0x1+1x1+0x5+1x1+0x4+1x1+0x3+1x1+0x8+1x1+0x8+1x1+0x9+1x1+0x8+1x1+0x5+1x1+0x17+1x1+0x10+1x3+0x9 0x68+1x1+0x11+1x1+0x19
0, 1で何か表示していると推測する。各行0が何個、1が何個ということを示していると、つじつまが合いそう。各行0, 1の合計は100になる。絵に起こしてみる。
def parse(s): ret = '' elms = s.split('+') for e in elms: c = e.split('x')[0] num = int(e.split('x')[1]) ret += c * num return ret with open('encoded_img', 'r') as f: lines = f.readlines() for line in lines: s = line.rstrip() zo = parse(s) print zo
実行結果は以下の通り。
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000 0000000100000001000000000110001111000100000011111010010110000000000000110001000000001000001100000000 0111110000000000000000001110001000000000000000011010000011001000100001100011100010011000011100000000 0001000000010000000000011010001111100000000000010010000000100000000001000110100000111000010110010000 0001000100000001100010010010000000100000000000110011000001100000000001000100100011001000011110000000 0001000100010111000000000010000000100000001000100010110011100000000111110000100011111111101110000000 0001000111010111100000000010000001100100000001100010010000100000000001000000100000001000000011110000 0000010101010000110000000110001111000000000001000010010001100000010001000000100000001010111110000000 0000000101010011100000001111100000000000000001000010010111000111111001001011111000001001000010000000 0000000000000000001111100000000000001111110000000000000000000000000001000000000000001001100100000100 0100000100001000100000000100000000100000000010000000010000010000000000000000010000000000111000000000 0000000000000000000000000000000000000000000000000000000000000000000010000000000010000000000000000000
わかりづらいので、文字を置換してみる。
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□■□□□□□□□□□□□□□□ □□□□□□□■□□□□□□□■□□□□□□□□□■■□□□■■■■□□□■□□□□□□■■■■■□■□□■□■■□□□□□□□□□□□□□■■□□□■□□□□□□□□■□□□□□■■□□□□□□□□ □■■■■■□□□□□□□□□□□□□□□□□□■■■□□□■□□□□□□□□□□□□□□□□■■□■□□□□□■■□□■□□□■□□□□■■□□□■■■□□□■□□■■□□□□■■■□□□□□□□□ □□□■□□□□□□□■□□□□□□□□□□□■■□■□□□■■■■■□□□□□□□□□□□□■□□■□□□□□□□■□□□□□□□□□□■□□□■■□■□□□□□■■■□□□□■□■■□□■□□□□ □□□■□□□■□□□□□□□■■□□□■□□■□□■□□□□□□□■□□□□□□□□□□□■■□□■■□□□□□■■□□□□□□□□□□■□□□■□□■□□□■■□□■□□□□■■■■□□□□□□□ □□□■□□□■□□□■□■■■□□□□□□□□□□■□□□□□□□■□□□□□□□■□□□■□□□■□■■□□■■■□□□□□□□□■■■■■□□□□■□□□■■■■■■■■■□■■■□□□□□□□ □□□■□□□■■■□■□■■■■□□□□□□□□□■□□□□□□■■□□■□□□□□□□■■□□□■□□■□□□□■□□□□□□□□□□■□□□□□□■□□□□□□□■□□□□□□□■■■■□□□□ □□□□□■□■□■□■□□□□■■□□□□□□□■■□□□■■■■□□□□□□□□□□□■□□□□■□□■□□□■■□□□□□□■□□□■□□□□□□■□□□□□□□■□■□■■■■■□□□□□□□ □□□□□□□■□■□■□□■■■□□□□□□□■■■■■□□□□□□□□□□□□□□□□■□□□□■□□■□■■■□□□■■■■■■□□■□□■□■■■■■□□□□□■□□■□□□□■□□□□□□□ □□□□□□□□□□□□□□□□□□■■■■■□□□□□□□□□□□□□■■■■■■□□□□□□□□□□□□□□□□□□□□□□□□□□□■□□□□□□□□□□□□□□■□□■■□□■□□□□□■□□ □■□□□□□■□□□□■□□□■□□□□□□□□■□□□□□□□□■□□□□□□□□□■□□□□□□□□■□□□□□■□□□□□□□□□□□□□□□□□■□□□□□□□□□□■■■□□□□□□□□□ □□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□■□□□□□□□□□□□■□□□□□□□□□□□□□□□□□□□
フラグのASCIIアートのような感じになった。
CodefestCTF{This_15_7h3_f14g}
Linux RE 2 (Max Score: 500)
Ghidraでデコンパイルする。
undefined8 main(void) { size_t sVar1; long in_FS_OFFSET; char local_78; char local_77; char local_76; char local_75; char local_74; char local_73; char local_72; char local_71; char local_70; char local_6f; byte local_6e; char local_6d; byte local_6c; char local_6b; byte local_6a; char local_69; char local_68; byte local_67; char local_66; byte local_65; char local_64; byte local_63; char local_62; long local_10; local_10 = *(long *)(in_FS_OFFSET + 0x28); __isoc99_scanf(&DAT_00400a88,&local_78); sVar1 = strlen(&local_78); if (sVar1 == 0x17) { if (local_74 == 'l') { if ((int)local_75 + 1 == (int)local_72) { if ((int)local_73 + 1 == (int)local_71) { if (local_71 == 'e') { if (local_75 == 'u') { if (local_76 == 'o') { if (local_78 == 's') { if (local_77 == 'h') { if (local_70 == '_') { if ((int)(char)local_6c + 1 == (int)local_6d) { if ((int)(char)local_6e + 2 == (int)local_6f) { if ((local_6c ^ local_6e) == 0x17) { if (local_6c == 100) { if (local_6b == '_') { if ((int)(char)local_67 + 8 == (int)local_68) { if ((int)local_69 + -2 == (int)local_68) { if ((local_67 ^ local_6a) == 0x16) { if (local_68 == 'm') { if (local_66 == '_') { if ((int)local_62 + 3 == (int)local_64) { if ((int)local_64 + 0x10 == (int)(char)local_63 + 0x10) { if ((local_65 ^ local_63) == 0x1b) { if (local_62 == 'l') { puts("Congratulations! Correct password!"); } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } } else { puts("Sorry! Wrong password!"); } if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) { /* WARNING: Subroutine does not return */ __stack_chk_fail(); } return 0;
ここから整理しながら条件を見ていく。
長さ0x17 = 23 local_75 + 1 == (int)local_72 (int)local_73 + 1 == (int)local_71 (int)(char)local_6c + 1 == (int)local_6d (int)(char)local_6e + 2 == (int)local_6f (local_6c ^ local_6e) == 0x17 (int)(char)local_67 + 8 == (int)local_68 (int)local_69 + -2 == (int)local_68 (local_67 ^ local_6a) == 0x16 (int)local_62 + 3 == (int)local_64 int)local_64 + 0x10 == (int)(char)local_63 + 0x10 (local_65 ^ local_63) == 0x1b local_62 = 'l' local_63 = 'o' local_64 = 'o' local_65 = 't' local_66 = '_' local_67 = 'e' local_68 = 'm' local_69 = 'o' local_6a = 's' local_6b = '_' local_6c = 'd' local_6d = 'e' local_6e = 's' local_6f = 'u' local_70 = '_' local_71 = 'e' local_72 = 'v' local_73 = 'd' local_74 = 'l' local_75 = 'u' local_76 = 'o' local_77 = 'h' local_78 = 's'
あとは下から並べると、フラグになる。
CodefestCTF{shouldve_used_some_tool}
Feedback - Codefest'19 (Max Score: 100)
アンケートに答えたら、フラグが表示された。
CodefestCTF{Th4nk3_f0r_pl4ying}