この大会は2022/4/30 7:00(JST)~2022/5/2 7:00(JST)に開催されました。
今回もチームで参戦。結果は900点で242チーム中52位でした。
自分で解けた問題をWriteupとして書いておきます。
Shhhhhh it’s a Sekret (Stu's Investigation Extravaganza! 50)
公開鍵をインポートしてみる。
$ gpg --import key.asc gpg: 鍵2A6264BD39D4EC07: 公開鍵"cybersecstu <ctfsaresometimefun@mail.com>"をインポートしました gpg: 処理数の合計: 1 gpg: インポート: 1
署名に使ったメールアドレスはctfsaresometimefun@mail.com。
DOCTF{ctfsaresometimefun@mail.com}
Part 1 - Ingress (Misc 50)
$ cat brut.log | grep DOCTF{ | head -1 2021-04-20 08:28:00 NGINX POST wp-login.php - 443 - 13.105.95.112 Mozilla/5.0+(Windows+NT+10.0;+Win64;+x64)+AppleWebKit/537.36+(DOCTF{w34k_p455w0rd5_637_pwnd})+Chrome/84.0.4147.105+Safari/537.36 - 401 0 0 28
DOCTF{w34k_p455w0rd5_637_pwnd}
Get down with the Gitness (Misc 100)
$ git clone https://github.com/punk-security/DOCON22_CTF1 Cloning into 'DOCON22_CTF1'... remote: Enumerating objects: 682, done. remote: Counting objects: 100% (682/682), done. remote: Compressing objects: 100% (243/243), done. remote: Total 682 (delta 392), reused 682 (delta 392), pack-reused 0 Receiving objects: 100% (682/682), 74.68 KiB | 483.00 KiB/s, done. Resolving deltas: 100% (392/392), done. $ cd DOCON22_CTF1/ $ git log -p | grep DOCTF | grep -v REDACTED -the fl4g is: DOCTF{REDACTING_IN_GIT_IS_HARDZ} +the fl4g is: DOCTF{REDACTING_IN_GIT_IS_HARDZ}
DOCTF{REDACTING_IN_GIT_IS_HARDZ}
1 - Ready ? (OSINT 10)
問題にフラグが書いてある。
DOCTF{R34DY}
vault (Reverse 100)
$ gdb -q ./vault Reading symbols from ./vault...(no debugging symbols found)...done. gdb-peda$ start [----------------------------------registers-----------------------------------] RAX: 0x5555555551e9 (<main>: endbr64) RBX: 0x0 RCX: 0x555555555370 (<__libc_csu_init>: endbr64) RDX: 0x7fffffffdee8 --> 0x7fffffffe244 ("CLUTTER_IM_MODULE=xim") RSI: 0x7fffffffded8 --> 0x7fffffffe22d ("/mnt/hgfs/Shared/vault") RDI: 0x1 RBP: 0x555555555370 (<__libc_csu_init>: endbr64) RSP: 0x7fffffffddf8 --> 0x7ffff7a03c87 (<__libc_start_main+231>: mov edi,eax) RIP: 0x5555555551e9 (<main>: endbr64) R8 : 0x7ffff7dced80 --> 0x0 R9 : 0x7ffff7dced80 --> 0x0 R10: 0x0 R11: 0x0 R12: 0x555555555100 (<_start>: endbr64) R13: 0x7fffffffded0 --> 0x1 R14: 0x0 R15: 0x0 EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x5555555551d9 <__do_global_dtors_aux+57>: nop DWORD PTR [rax+0x0] 0x5555555551e0 <frame_dummy>: endbr64 0x5555555551e4 <frame_dummy+4>: jmp 0x555555555160 <register_tm_clones> => 0x5555555551e9 <main>: endbr64 0x5555555551ed <main+4>: push rbp 0x5555555551ee <main+5>: mov rbp,rsp 0x5555555551f1 <main+8>: sub rsp,0x40 0x5555555551f5 <main+12>: mov rax,QWORD PTR fs:0x28 [------------------------------------stack-------------------------------------] 0000| 0x7fffffffddf8 --> 0x7ffff7a03c87 (<__libc_start_main+231>: mov edi,eax) 0008| 0x7fffffffde00 --> 0x1 0016| 0x7fffffffde08 --> 0x7fffffffded8 --> 0x7fffffffe22d ("/mnt/hgfs/Shared/vault") 0024| 0x7fffffffde10 --> 0x100008000 0032| 0x7fffffffde18 --> 0x5555555551e9 (<main>: endbr64) 0040| 0x7fffffffde20 --> 0x0 0048| 0x7fffffffde28 --> 0x52ff018447034528 0056| 0x7fffffffde30 --> 0x555555555100 (<_start>: endbr64) [------------------------------------------------------------------------------] Legend: code, data, rodata, value Temporary breakpoint 1, 0x00005555555551e9 in main () gdb-peda$ disas main Dump of assembler code for function main: => 0x00005555555551e9 <+0>: endbr64 0x00005555555551ed <+4>: push rbp 0x00005555555551ee <+5>: mov rbp,rsp 0x00005555555551f1 <+8>: sub rsp,0x40 0x00005555555551f5 <+12>: mov rax,QWORD PTR fs:0x28 0x00005555555551fe <+21>: mov QWORD PTR [rbp-0x8],rax 0x0000555555555202 <+25>: xor eax,eax 0x0000555555555204 <+27>: mov BYTE PTR [rbp-0x3a],0x7d 0x0000555555555208 <+31>: mov BYTE PTR [rbp-0x39],0x30 0x000055555555520c <+35>: mov BYTE PTR [rbp-0x38],0x7b 0x0000555555555210 <+39>: mov BYTE PTR [rbp-0x37],0x43 0x0000555555555214 <+43>: mov BYTE PTR [rbp-0x36],0x46 0x0000555555555218 <+47>: mov BYTE PTR [rbp-0x35],0x43 0x000055555555521c <+51>: mov BYTE PTR [rbp-0x34],0x52 0x0000555555555220 <+55>: mov BYTE PTR [rbp-0x33],0x30 0x0000555555555224 <+59>: mov BYTE PTR [rbp-0x32],0x50 0x0000555555555228 <+63>: mov BYTE PTR [rbp-0x31],0x52 0x000055555555522c <+67>: mov BYTE PTR [rbp-0x30],0x34 0x0000555555555230 <+71>: mov BYTE PTR [rbp-0x2f],0x46 0x0000555555555234 <+75>: mov BYTE PTR [rbp-0x2e],0x4f 0x0000555555555238 <+79>: mov BYTE PTR [rbp-0x2d],0x54 0x000055555555523c <+83>: mov BYTE PTR [rbp-0x2c],0x33 0x0000555555555240 <+87>: mov BYTE PTR [rbp-0x2b],0x44 0x0000555555555244 <+91>: mov BYTE PTR [rbp-0x2a],0x48 0x0000555555555248 <+95>: mov BYTE PTR [rbp-0x29],0x4b 0x000055555555524c <+99>: mov edi,0x12 0x0000555555555251 <+104>: call 0x5555555550e0 <malloc@plt> 0x0000555555555256 <+109>: mov QWORD PTR [rbp-0x28],rax 0x000055555555525a <+113>: lea rdi,[rip+0xda7] # 0x555555556008 0x0000555555555261 <+120>: mov eax,0x0 0x0000555555555266 <+125>: call 0x5555555550d0 <printf@plt> 0x000055555555526b <+130>: mov rax,QWORD PTR [rbp-0x28] 0x000055555555526f <+134>: mov rsi,rax 0x0000555555555272 <+137>: lea rdi,[rip+0xda4] # 0x55555555601d 0x0000555555555279 <+144>: mov eax,0x0 0x000055555555527e <+149>: call 0x5555555550f0 <__isoc99_scanf@plt> 0x0000555555555283 <+154>: movzx eax,BYTE PTR [rbp-0x2b] 0x0000555555555287 <+158>: mov BYTE PTR [rbp-0x20],al 0x000055555555528a <+161>: movzx eax,BYTE PTR [rbp-0x2e] 0x000055555555528e <+165>: mov BYTE PTR [rbp-0x1f],al 0x0000555555555291 <+168>: movzx eax,BYTE PTR [rbp-0x37] 0x0000555555555295 <+172>: mov BYTE PTR [rbp-0x1e],al 0x0000555555555298 <+175>: movzx eax,BYTE PTR [rbp-0x2d] 0x000055555555529c <+179>: mov BYTE PTR [rbp-0x1d],al 0x000055555555529f <+182>: movzx eax,BYTE PTR [rbp-0x36] 0x00005555555552a3 <+186>: mov BYTE PTR [rbp-0x1c],al 0x00005555555552a6 <+189>: movzx eax,BYTE PTR [rbp-0x38] 0x00005555555552aa <+193>: mov BYTE PTR [rbp-0x1b],al 0x00005555555552ad <+196>: movzx eax,BYTE PTR [rbp-0x2a] 0x00005555555552b1 <+200>: mov BYTE PTR [rbp-0x1a],al 0x00005555555552b4 <+203>: movzx eax,BYTE PTR [rbp-0x30] 0x00005555555552b8 <+207>: mov BYTE PTR [rbp-0x19],al 0x00005555555552bb <+210>: movzx eax,BYTE PTR [rbp-0x35] 0x00005555555552bf <+214>: mov BYTE PTR [rbp-0x18],al 0x00005555555552c2 <+217>: movzx eax,BYTE PTR [rbp-0x29] 0x00005555555552c6 <+221>: mov BYTE PTR [rbp-0x17],al 0x00005555555552c9 <+224>: movzx eax,BYTE PTR [rbp-0x2c] 0x00005555555552cd <+228>: mov BYTE PTR [rbp-0x16],al 0x00005555555552d0 <+231>: movzx eax,BYTE PTR [rbp-0x34] 0x00005555555552d4 <+235>: mov BYTE PTR [rbp-0x15],al 0x00005555555552d7 <+238>: movzx eax,BYTE PTR [rbp-0x32] 0x00005555555552db <+242>: mov BYTE PTR [rbp-0x14],al 0x00005555555552de <+245>: movzx eax,BYTE PTR [rbp-0x31] 0x00005555555552e2 <+249>: mov BYTE PTR [rbp-0x13],al 0x00005555555552e5 <+252>: movzx eax,BYTE PTR [rbp-0x33] 0x00005555555552e9 <+256>: mov BYTE PTR [rbp-0x12],al 0x00005555555552ec <+259>: movzx eax,BYTE PTR [rbp-0x39] 0x00005555555552f0 <+263>: mov BYTE PTR [rbp-0x11],al 0x00005555555552f3 <+266>: movzx eax,BYTE PTR [rbp-0x2f] 0x00005555555552f7 <+270>: mov BYTE PTR [rbp-0x10],al 0x00005555555552fa <+273>: movzx eax,BYTE PTR [rbp-0x3a] 0x00005555555552fe <+277>: mov BYTE PTR [rbp-0xf],al 0x0000555555555301 <+280>: mov BYTE PTR [rbp-0xe],0x0 0x0000555555555305 <+284>: mov rcx,QWORD PTR [rbp-0x28] 0x0000555555555309 <+288>: lea rax,[rbp-0x20] 0x000055555555530d <+292>: mov edx,0x12 0x0000555555555312 <+297>: mov rsi,rcx 0x0000555555555315 <+300>: mov rdi,rax 0x0000555555555318 <+303>: call 0x5555555550a0 <strncmp@plt> 0x000055555555531d <+308>: test eax,eax 0x000055555555531f <+310>: jne 0x55555555533b <main+338> 0x0000555555555321 <+312>: lea rax,[rbp-0x20] 0x0000555555555325 <+316>: mov rsi,rax 0x0000555555555328 <+319>: lea rdi,[rip+0xcf1] # 0x555555556020 0x000055555555532f <+326>: mov eax,0x0 0x0000555555555334 <+331>: call 0x5555555550d0 <printf@plt> 0x0000555555555339 <+336>: jmp 0x555555555347 <main+350> 0x000055555555533b <+338>: lea rdi,[rip+0xd02] # 0x555555556044 0x0000555555555342 <+345>: call 0x5555555550b0 <puts@plt> 0x0000555555555347 <+350>: mov eax,0x0 0x000055555555534c <+355>: mov rdx,QWORD PTR [rbp-0x8] 0x0000555555555350 <+359>: xor rdx,QWORD PTR fs:0x28 0x0000555555555359 <+368>: je 0x555555555360 <main+375> 0x000055555555535b <+370>: call 0x5555555550c0 <__stack_chk_fail@plt> 0x0000555555555360 <+375>: leave 0x0000555555555361 <+376>: ret End of assembler dump.
strncmpの比較をしているところにブレークポイントを置き、実行する。
gdb-peda$ b *0x0000555555555318 Breakpoint 2 at 0x555555555318 gdb-peda$ r Starting program: /mnt/hgfs/Shared/vault Enter the Password: hoge [----------------------------------registers-----------------------------------] RAX: 0x7fffffffddd0 ("DOCTF{H4CK3RPR00F}") RBX: 0x0 RCX: 0x555555559260 --> 0x65676f68 ('hoge') RDX: 0x12 RSI: 0x555555559260 --> 0x65676f68 ('hoge') RDI: 0x7fffffffddd0 ("DOCTF{H4CK3RPR00F}") RBP: 0x7fffffffddf0 --> 0x555555555370 (<__libc_csu_init>: endbr64) RSP: 0x7fffffffddb0 --> 0x307d0000000000c2 RIP: 0x555555555318 (<main+303>: call 0x5555555550a0 <strncmp@plt>) R8 : 0x0 R9 : 0x0 R10: 0x0 R11: 0x55555555601f --> 0x7373656363755300 ('') R12: 0x555555555100 (<_start>: endbr64) R13: 0x7fffffffded0 --> 0x1 R14: 0x0 R15: 0x0 EFLAGS: 0x206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x55555555530d <main+292>: mov edx,0x12 0x555555555312 <main+297>: mov rsi,rcx 0x555555555315 <main+300>: mov rdi,rax => 0x555555555318 <main+303>: call 0x5555555550a0 <strncmp@plt> 0x55555555531d <main+308>: test eax,eax 0x55555555531f <main+310>: jne 0x55555555533b <main+338> 0x555555555321 <main+312>: lea rax,[rbp-0x20] 0x555555555325 <main+316>: mov rsi,rax Guessed arguments: arg[0]: 0x7fffffffddd0 ("DOCTF{H4CK3RPR00F}") arg[1]: 0x555555559260 --> 0x65676f68 ('hoge') arg[2]: 0x12 arg[3]: 0x555555559260 --> 0x65676f68 ('hoge') [------------------------------------stack-------------------------------------] 0000| 0x7fffffffddb0 --> 0x307d0000000000c2 0008| 0x7fffffffddb8 ("{CFCR0PR4FOT3DHK`\222UUUU") 0016| 0x7fffffffddc0 ("4FOT3DHK`\222UUUU") 0024| 0x7fffffffddc8 --> 0x555555559260 --> 0x65676f68 ('hoge') 0032| 0x7fffffffddd0 ("DOCTF{H4CK3RPR00F}") 0040| 0x7fffffffddd8 ("CK3RPR00F}") 0048| 0x7fffffffdde0 --> 0x7fffff007d46 0056| 0x7fffffffdde8 --> 0x2b6b04de17511900 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Breakpoint 2, 0x0000555555555318 in main ()
strncmpの第一引数にフラグが入っている。
DOCTF{H4CK3RPR00F}
Area 51 (Steganography 50)
Audacityで開き、スペクトログラムを見ると、フラグが現れた。
DOCTF{SP3CTR0GR4M5_4R3_C00L_1F_0NLY_1_KN3W_H0W_T0_CR34T3_1T_MY53LF}
Matryoshka (Steganography 50)
何重にもzip圧縮されているので、スクリプトで解凍していく。
#!/usr/bin/env python3 import zipfile import os fname = '8fb0444894b78f857dd600b7f35c0af4.zip' while True: with zipfile.ZipFile(fname) as zf: next_fname = zf.namelist()[0] zf.extractall('.') os.remove(fname) fname = next_fname if not fname.endswith('.zip'): break
最後にBOMB_FLAGファイルが展開され、中にはこう書いてあった。
Welcome to the bottom! Here's your flag: DOCTF{G00D_3FF0RT_BUT_1$_1T_0V3R?} Nicos
DOCTF{G00D_3FF0RT_BUT_1$_1T_0V3R?}
Honey Maker (Cryptography 50)
HTMLソースを見ると、コメントにこう書いてある。
<!-- honey maker ctf--> <!--looks like you've found me! \ / \ o ^ o / \ ( ) / ____________(%%%%%%%)____________ ( / / )%%%%%%%( \ \ ) (___/___/__/ \__\___\___) ( / /(%%%%%%%)\ \ ) (__/___/ (%%%%%%%) \___\__) /( )\ / (%%%%%) \ (%%%) ! wWWWw wWWWw vVVVv (___) wWWWw (___) vVVVv (___) ~Y~ (___) vVVVv ~Y~ (___) ~Y~ \| ~Y~ (___) |/ ~Y~ \| \ |/ \| / \~Y~/ \| \ |/ \\|// \\|// \\|/// \\|// \\|// \\\|/// jgs^^^^^^https://youtu.be/ptBkmMk5YCc^^^^^^--> <!--honey maker ctf ends here-->
https://youtu.be/ptBkmMk5YCcの動画を眺めてみる。6:12くらいのところでフラグが表示された。
DOCTF{STINGER}
Mendel(la) effect (Cryptography 50)
https://www.nacalai.co.jp/information/trivia2/09.htmlのDNAの遺伝暗号表を元に復号する。
ATGGCAGGAATCTGCTGA M A G I C (STOP)
DOCTF{MAGIC}
Frog festivities (Cryptography 50)
image.pngにはjumpyと書かれており、2段で横26マスの表になっている。Keyed Caesar Cipherと推測し、https://www.boxentriq.com/code-breaking/keyed-caesar-cipherで復号する。
ribbit
DOCTF{ribbit}
Based (Cryptography 100)
base64文字列のようなので、デコードする。
$ cat based.txt | base64 -d Grandpa sent me on a treasure hunt to get a lost flag but the map wasnt completed. All I saw was the city of ROT and a coded message: Jung lbh jvfu sbe vf ng ...- .. --. . -. . .-. . ... -.-. .- ... - .-.. . hfr gur xrl QBgjb naq cebivqr gur cuenfr TPICG{MpcHpkskKbifj}
"cuenfr"までモールス信号を除き、シーザー暗号と推測し、https://www.geocachingtoolbox.com/index.php?lang=en&page=caesarCipherで復号してみる。
Jung lbh jvfu sbe vf ng [モールスコード] hfr gur xrl QBgjb naq cebivqr gur cuenfr ↓ROT13 What you wish for is at [モールスコード] use the key DOtwo and provide the phrase
モールスコード部分をhttps://morsecode.world/international/translator.htmlでデコードしてみる。
VIGENERESCASTLE
フラグ部分をVigenere暗号と推測し、復号してみる。鍵はQBGJB。
DOCTF{WowYoureBased}
Fight the corruption (Cryptography 100)
1箇所ASCII文字になっていない箇所があり、さらにDER形式に変換すると、先頭にゴミが入っている。ゴミを削除後、不明な1バイトをブルートフォースで、PEM形式にして例外が発生しないものを探す。探し当てることができたら、そのパラメータを使って、復号する。
#!/usr/bin/env python3 from Crypto.PublicKey import RSA from Crypto.Util.number import * from base64 import * from string import * import re def der_to_pem(der): pem = b'-----BEGIN PRIVATE KEY-----\r\n' b64 = b64encode(der) for i in range(0, len(b64), 64): pem += b64[i:i+64] + b'\r\n' pem += b'-----END PRIVATE KEY-----\r\n' return pem.decode() with open('challenge.pem', 'rb') as f: data = f.read() index = data.index(b'fhWn') b64str = ascii_letters + digits + '+/' for c in b64str: tmp_data = data[:index-4] + c.encode() + data[index:] tmp_data = tmp_data.replace(b'\r\n', b'') tmp_data = tmp_data.replace(b'-----BEGIN PRIVATE KEY-----', b'') tmp_data = tmp_data.replace(b'-----END PRIVATE KEY-----', b'') der_data = b64decode(tmp_data)[26:] pem_data = der_to_pem(der_data) try: privkey = RSA.importKey(pem_data) print('[+] unknown char:', c) break except: continue n = privkey.n d = privkey.d with open('SECRET.enc', 'rb') as f: c = bytes_to_long(f.read()) m = pow(c, d, n) msg = long_to_bytes(m) index_begin = msg.index(b'DOCTF') index_end = msg.index(b'}', index_begin) flag = msg[index_begin:index_end + 1].decode() print('[*] flag:', flag)
実行結果は以下の通り。
[+] unknown char: Y [*] flag: DOCTF{1M4G1N3_TH1S_W0ULD_H4PP3N_1N_PR0DUCTI0N}
DOCTF{1M4G1N3_TH1S_W0ULD_H4PP3N_1N_PR0DUCTI0N}