この大会は2020/2/15 23:00(JST)~2020/2/16 23:00(JST)に開催されました。
今回もチームで参戦。結果は 7279点で418チーム中84位でした。
自分で解けた問題をWriteupとして書いておきます。
Deep dive (Misc)
$ file flag.txt flag.txt: POSIX tar archive (GNU) $ tar xvf flag.txt ./ ./flag.txt $ file flag.txt flag.txt: Zip archive data, at least v2.0 to extract $ file flag.txt flag.txt: bzip2 compressed data, block size = 900k
何重にも圧縮されている。スクリプトで解凍する。xzを解凍する際には、「ファイルのパーミッションを設定できません: 定義されたデータ型に対して値が大きすぎます」と警告が表示され、すぐに次の処理に入ると、エラーになるので、sleep処理を入れた。
import subprocess import os import time cmd_file = 'file %s' cmd_tar = 'tar xvf %s' cmd_zip = 'unzip %s' cmd_bz2 = 'bzip2 -d %s' cmd_gz = 'gzip -d %s' cmd_xz = 'xz -d %s' filename_base = 'flag' filename_txt = 'flag.txt' filename_tar = 'flag.tar' filename_zip = 'flag.zip' filename_bz2 = 'flag.bz2' filename_gz = 'flag.gz' filename_xz = 'flag.xz' i = 1 while True: print '%d times' % i cmd = cmd_file % filename_txt ret = subprocess.check_output( cmd.split(" ") ) print ret if 'tar archive' in ret: os.rename(filename_txt, filename_tar) os.system(cmd_tar % filename_tar) os.remove(filename_tar) elif 'Zip archive' in ret: os.rename(filename_txt, filename_zip) os.system(cmd_zip % filename_zip) os.remove(filename_zip) elif 'bzip2 compressed' in ret: os.rename(filename_txt, filename_bz2) os.system(cmd_bz2 % filename_bz2) os.rename(filename_base, filename_txt) elif 'gzip compressed' in ret: os.rename(filename_txt, filename_gz) os.system(cmd_gz % filename_gz) os.rename(filename_base, filename_txt) elif 'XZ compressed' in ret: os.rename(filename_txt, filename_xz) os.system(cmd_xz % filename_xz) time.sleep(2) os.rename(filename_base, filename_txt) else: break i += 1
実行結果は以下の通り。
: 722 times flag.txt: POSIX tar archive (GNU) ./ ./flag.txt 723 times flag.txt: ASCII text, with no line terminators $ cat flag.txt FLAG{matri0sha256}
FLAG{matri0sha256}
Blogger (Forensics)
pcapngからUSBのキー入力を読み取る。
#!/usr/bin/env python # -*- coding: utf-8 -*- from scapy.all import * keymap = { 0x04: ('a', 'A'), 0x05: ('b', 'B'), 0x06: ('c', 'C'), 0x07: ('d', 'D'), 0x08: ('e', 'E'), 0x09: ('f', 'F'), 0x0a: ('g', 'G'), 0x0b: ('h', 'H'), 0x0c: ('i', 'I'), 0x0d: ('j', 'J'), 0x0e: ('k', 'K'), 0x0f: ('l', 'L'), 0x10: ('m', 'M'), 0x11: ('n', 'N'), 0x12: ('o', 'O'), 0x13: ('p', 'P'), 0x14: ('q', 'Q'), 0x15: ('r', 'R'), 0x16: ('s', 'S'), 0x17: ('t', 'T'), 0x18: ('u', 'U'), 0x19: ('v', 'V'), 0x1a: ('w', 'W'), 0x1b: ('x', 'X'), 0x1c: ('y', 'Y'), 0x1d: ('z', 'Z'), 0x1e: ('1', '!'), 0x1f: ('2', '@'), 0x20: ('3', '#'), 0x21: ('4', '$'), 0x22: ('5', '%'), 0x23: ('6', '^'), 0x24: ('7', '&'), 0x25: ('8', '*'), 0x26: ('9', '('), 0x27: ('0', ')'), 0x28: ('\x0a', '\x0a'), 0x29: ('\x1b', '\x1b'), 0x2a: ('\x08', '\x08'), 0x2b: ('\x09', '\x09'), 0x2c: ('\x20', '\x20'), 0x2d: ('-', '_'), 0x2e: ('=', '+'), 0x2f: ('[', '{'), 0x30: (']', '}'), 0x31: ('\\', '|'), 0x33: (';', ':'), 0x34: ('\'', '\"'), 0x35: ('`', '~'), 0x36: (',', '<'), 0x37: ('.', '>'), 0x38: ('/', '?')} packets = rdpcap('usb_here.pcapng') usb_data = [] for p in packets: buf = p['Raw'].load if buf[22] == '\x01' and len(buf[27:]) > 0: usb_data.append(buf[27:]) msg = '' for d in usb_data: if d[2] == '\x00' or not('\x00' in d[3:8]): continue elif ord(d[2]) not in keymap: continue if d[0] == '\x02' or d[0] == '\x20': c = keymap[ord(d[2])][1] msg += c else: c = keymap[ord(d[2])][0] msg += c print msg
実行結果は以下の通り。
Sherlock, John, and Henry then visit the hollow in the hope of finding the hound. On the way, John notices what seems to be FLAG{like_a_b100dh0und} e
FLAG{like_a_b100dh0und}
Magic of numbers (PPC)
$ nc 212.47.229.1 33004 ====================================================================================================== Hey, hello! Just send me an answer to 9 simple examples, so I can check if my machine knows math well. ====================================================================================================== [>] 0 + 1 [>] Result: 1 [>] 1 + 3 [>] Result: 4 [>] 2 + 5 [>] Result: 7 [>] 3 + 7 [>] Result: 10 [>] 4 + 9 [>] Result: 13 [>] 5 + 11 [>] Result: 16 [>] 6 + 13 [>] Result: 19 [>] 7 + 15 [>] Result: 22 [>] 8 + 17 [>] Result: 25 [>] 0.1 + 0.2 [>] Result: 0.3 You made a mistake somewhere! Bay, bay!
小数の計算については、コンピュータの場合の結果を答える必要がありそう。
$ nc 212.47.229.1 33004 ====================================================================================================== Hey, hello! Just send me an answer to 9 simple examples, so I can check if my machine knows math well. ====================================================================================================== [>] 0 + 1 [>] Result: 1 [>] 1 + 3 [>] Result: 4 [>] 2 + 5 [>] Result: 7 [>] 3 + 7 [>] Result: 10 [>] 4 + 9 [>] Result: 13 [>] 5 + 11 [>] Result: 16 [>] 6 + 13 [>] Result: 19 [>] 7 + 15 [>] Result: 22 [>] 8 + 17 [>] Result: 25 [>] 0.1 + 0.2 [>] Result: 0.30000000000000004 FLAG{MaGiC_0f_NuMbErS}
FLAG{MaGiC_0f_NuMbErS}
Crossw0rd (Reverse)
$ ./crossw0rd Welcome. You're in function check. Please Enter a password to continue. 1 attempt remaining: aaa Wrong password! Your attempt is over.
正しいパスワードを入れる必要があるようだ。Ghidraでデコンパイルしてみる。
void check(void) { char cVar1; long in_FS_OFFSET; char local_28 [24]; long local_10; local_10 = *(long *)(in_FS_OFFSET + 0x28); puts( "Welcome. You\'re in function check. Please Enter a password to continue. 1 attemptremaining:" ); scanf("%s",local_28); cVar1 = e(local_28); if (cVar1 == 0) { puts("Wrong password! Your attempt is over."); } else { puts("You cracked the system!"); } if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) { /* WARNING: Subroutine does not return */ __stack_chk_fail(); } return; }
ulong e(char *param_1) { byte bVar1; char cVar2; if ((((param_1[7] == '5') && (param_1[0x11] == 'g')) && (param_1[2] == 'A')) && (cVar2 = b(param_1), cVar2 != 0)) { bVar1 = 1; } else { bVar1 = 0; } return (ulong)bVar1; }
ここから読み取れる条件は以下の通り。
・param_1[7] == '5' ・param_1[17] == 'g' ・param_1[2] == 'A' ・b(param_1) == 1
ulong b(char *param_1) { byte bVar1; char cVar2; if ((((param_1[0xf] == 'i') && (param_1[9] == 'r')) && (param_1[1] == 'L')) && (cVar2 = d(param_1), cVar2 != 0)) { bVar1 = 1; } else { bVar1 = 0; } return (ulong)bVar1; }
ここから読み取れる条件は以下の通り。
・param_1[15] == 'i' ・param_1[9] == 'r' ・param_1[1] == 'L' ・d(param_1) == 1
ulong d(char *param_1) { byte bVar1; char cVar2; if ((((param_1[10] == '3') && (param_1[0x12] == '}')) && (param_1[6] == 'a')) && (cVar2 = f(param_1), cVar2 != 0)) { bVar1 = 1; } else { bVar1 = 0; } return (ulong)bVar1; }
ここから読み取れる条件は以下の通り。
・param_1[10] == '3' ・param_1[18] == '}' ・param_1[6] == 'a' ・f(param_1) == 1
ulong f(char *param_1) { byte bVar1; char cVar2; if ((((*param_1 == 'F') && (param_1[0xe] == '5')) && (param_1[0x10] == 'n')) && (cVar2 = c(param_1), cVar2 != 0)) { bVar1 = 1; } else { bVar1 = 0; } return (ulong)bVar1; }
ここから読み取れる条件は以下の通り。
・param_1[0] == 'F' ・param_1[14] == '5' ・param_1[16] == 'n' ・c(param_1) == 1
ulong c(char *param_1) { byte bVar1; char cVar2; if ((((param_1[3] == 'G') && (param_1[0xb] == 'v')) && (param_1[5] == '3')) && (cVar2 = a(param_1), cVar2 != 0)) { bVar1 = 1; } else { bVar1 = 0; } return (ulong)bVar1; }
ここから読み取れる条件は以下の通り。
・param_1[3] == 'G' ・param_1[11] == 'v' ・param_1[5] == '3' ・a(param_1) == 1
undefined8 a(char *param_1) { undefined8 uVar1; if ((((param_1[4] == '{') && (param_1[0xc] == '3')) && (param_1[8] == 'y')) && (param_1[0xd] == 'r')) { uVar1 = 1; } else { uVar1 = 0; } return uVar1; }
ここから読み取れる条件は以下の通り。
・param_1[4] == '{' ・param_1[12] == '3' ・param_1[8] == 'y' ・param_1[13] == 'r'
条件を順に並べる。
・param_1[0] == 'F' ・param_1[1] == 'L' ・param_1[2] == 'A' ・param_1[3] == 'G' ・param_1[4] == '{' ・param_1[5] == '3' ・param_1[6] == 'a' ・param_1[7] == '5' ・param_1[8] == 'y' ・param_1[9] == 'r' ・param_1[10] == '3' ・param_1[11] == 'v' ・param_1[12] == '3' ・param_1[13] == 'r' ・param_1[14] == '5' ・param_1[15] == 'i' ・param_1[16] == 'n' ・param_1[17] == 'g' ・param_1[18] == '}'
これでフラグはわかった。
FLAG{3a5yr3v3r5ing}
Find Moriarty (Stego)
3つのPNGファイルと1つのJPGファイルが添付されている。JPGファイルには"PASS: IATA"の文字がある。3つのPNGファイルは空港の画像のようだ。画像検索でどこの空港かを調べ、その情報をまとめてみる。
35d6d33467aae9a2e3dccb4b6b027878.png ロンドン・ガトウィック空港 IATA空港コード: LGW ファイル名逆md5: three b8a9f715dbb64fd5c56e7783c6820a61.png ロンドン・ヒースロー空港 IATA空港コード: LHR ファイル名逆md5: two f97c5d29941bfb1b2fdab0874906ab82.png ロンドン・スタンステッド空港 IATA空港コード: STN ファイル名逆md5: one
ファイル名をmd5クラックした結果のone, two, threeの順にIATA空港コードを並べたものがパスになる。steghideでこのパス"STNLHRLGW"を指定し、隠されたファイルを抽出する。
$ steghide extract -sf fly.jpg Enter passphrase: wrote extracted data to "key.txt". $ cat key.txt FLAG{l375_fly_w17h_bu65}
FLAG{l375_fly_w17h_bu65}