この大会は2023/8/5 17:07(JST)~2023/8/7 5:07(JST)に開催されました。
今回もチームで参戦。結果は325点で712チーム中263位でした。
ただこの大会、問題盗用等で問題になった模様。
途中からやる気もなくなりましたが、
自分で解けた問題をWriteupとして書いておきます。
Avail Your Good Boy Points (Misc, Easy)
ルールにフラグが書いてあった。
dsc{y0u_4re_4_g00D_80Y}
where-are-the-cookies (Web, Easy)
$ curl https://ch291050125115.ch.eng.run/robots.txt User-agent: * Disallow: /cookiesaretotallynothere $ curl https://ch291050125115.ch.eng.run/cookiesaretotallynothere -v * Trying 15.207.137.16:443... * Connected to ch291050125115.ch.eng.run (15.207.137.16) port 443 (#0) * ALPN: offers h2,http/1.1 * TLSv1.3 (OUT), TLS handshake, Client hello (1): * CAfile: /etc/ssl/certs/ca-certificates.crt * CApath: /etc/ssl/certs * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 * ALPN: server accepted h2 * Server certificate: * subject: CN=*.shell.eng.run * start date: May 3 00:00:00 2023 GMT * expire date: Jun 1 23:59:59 2024 GMT * subjectAltName: host "ch291050125115.ch.eng.run" matched cert's "*.ch.eng.run" * issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M01 * SSL certificate verify ok. * using HTTP/2 * h2h3 [:method: GET] * h2h3 [:path: /cookiesaretotallynothere] * h2h3 [:scheme: https] * h2h3 [:authority: ch291050125115.ch.eng.run] * h2h3 [user-agent: curl/7.88.1] * h2h3 [accept: */*] * Using Stream ID: 1 (easy handle 0x5648edebd9e0) > GET /cookiesaretotallynothere HTTP/2 > Host: ch291050125115.ch.eng.run > user-agent: curl/7.88.1 > accept: */* > < HTTP/2 200 < date: Sat, 05 Aug 2023 08:31:19 GMT < content-type: text/html; charset=utf-8 < content-length: 25 < server: nginx/1.25.1 < x-powered-by: Express < set-cookie: caniseethecookie=bm8==; Path=/; HttpOnly; Secure; SameSite=Strict < etag: W/"19-1g63qbCXThU+tYI+45oRq6XoS80" < * Connection #0 to host ch291050125115.ch.eng.run left intact No cookies for you today! $ echo bm8= | base64 -d no
yesをセットする。
$ echo -n yes | base64 eWVz $ curl https://ch291050125115.ch.eng.run/cookiesaretotallynothere -b 'caniseethecookie=eWVz' You found the cookie! 🍪 Oh, I also found this unrelated string, might be useful to you: dsc{1_f0unD_Th3_c0oK135}
dsc{1_f0unD_Th3_c0oK135}
Gibberish (Forensics, Easy)
flag.txtの内容をbase64デコードして保存する。
#!/usr/bin/env python3 from base64 import * with open('flag.txt', 'r') as f: enc = f.read() with open('flag.bin', 'wb') as f: f.write(b64decode(enc))
ELFバイナリになっているので、実行してみる。
$ ./flag.bin Password:
パスワードを聞かれる。
$ strings flag.bin : Password: goodbye mlh{nc_c4n_4ls0_trnsmit_f1les} Wrong password. :
dsc{nc_c4n_4ls0_trnsmit_f1les}
Hash Roll (Forensics, Easy)
zipにパスワードがかかっているので、クラックする。
$ zip2john encrypted1.zip > zip.hash $ john --wordlist=dict/rockyou.txt zip.hash Using default input encoding: UTF-8 Loaded 1 password hash (ZIP, WinZip [PBKDF2-SHA1 256/256 AVX2 8x]) Cost 1 (HMAC size) is 143716 for all loaded hashes Will run 2 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status diosesamor (encrypted1.zip/flag.jpg) 1g 0:00:00:00 DONE (2023-08-05 18:10) 11.11g/s 45511p/s 45511c/s 45511C/s 123456..oooooo Use the "--show" option to display all of the cracked passwords reliably Session completed. $ 7z x encrypted1.zip 7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 p7zip Version 16.02 (locale=ja_JP.UTF-8,Utf16=on,HugeFiles=on,64 bits,2 CPUs Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz (A0655),ASM,AES-NI) Scanning the drive for archives: 1 file, 143908 bytes (141 KiB) Extracting archive: encrypted1.zip -- Path = encrypted1.zip Type = zip Physical Size = 143908 Enter password (will not be echoed): Everything is Ok Size: 146035 Compressed: 143908
展開されたflag.jpgの画像にフラグが書かれていた。
dsc{N3v3r_9OnNA_gIv3_y0u_up}
Magicplay (Forensics, Medium)
PNGの先頭4バイト、IHDRチャンク名、sRGBチャンク名、gAMAチャンク名、pHYsチャンクが壊れているので、修正する。
修正した画像にフラグが書いてあった。
dsc{COrrupt3d_M4g1C_f1Ag}
BLURY (Cryptography, HARD)
※この問題は取り下げになった模様。
AES CBC暗号だが、最後の暗号ブロックと一部の暗号、平文の全体しかわからない。フラグはIV。
最後のブロックの暗号化の復号と、最後のブロックの平文のXORが最後から2番目のブロックになることから、ブルートフォースでkeyを求める。それから最後のブロックから順に暗号を求め、最初のブロックの暗号の復号と最初のブロックの平文のXORがフラグになる。
#!/usr/bin/env python3 from Crypto.Cipher import AES from Crypto.Util.strxor import strxor from base64 import * import binascii key_head = b'3N7g309d6Y7enT' message = b'Security is not a joke, mind it. But complete security is a myth' with open('ciphertext.txt', 'r') as f: ct = b64decode(b64decode(f.read())) pt_blocks = [message[i:i+16] for i in range(0, len(message), 16)] ct_blocks = [ct[i:i+32].decode() for i in range(0, len(ct), 32)] print('[+] ct_blocks:', ct_blocks) ct = binascii.unhexlify(ct_blocks[-1]) pt_tail = strxor(binascii.unhexlify(ct_blocks[-2][-4:]), pt_blocks[-1][-2:]) found = False for c1 in range(32, 127): for c2 in range(32, 127): key = key_head + bytes([c1 ,c2]) aes = AES.new(key, AES.MODE_ECB) pt = aes.decrypt(ct) if pt[-2:] == pt_tail: found = True print('[+] key:', key.decode()) break if found: break pt_blocks = pt_blocks[::-1] ct_blocks = [binascii.hexlify(ct).decode()] for i in range(len(pt_blocks)): aes = AES.new(key, AES.MODE_ECB) pt = aes.decrypt(binascii.unhexlify(ct_blocks[i])) ct_blocks.append(binascii.hexlify(strxor(pt, pt_blocks[i])).decode()) flag = binascii.unhexlify(ct_blocks[-1]) ct_blocks = ct_blocks[:-1][::-1] print('[+] ct_blocks:', ct_blocks) flag = flag.decode() print('[*] flag:', flag)
実行結果は以下の通り。
[+] ct_blocks: ['54**************************36d4', '3a**************************1658', 'e7**************************bb2c', 'dabc02a058f8c3936a5fd6ddd3c50491'] [+] key: 3N7g309d6Y7enT1p [+] ct_blocks: ['54453ced1207bb9f67894d2c8ae336d4', '3a4911ae86c1f5138c2d8e17e7721658', 'e764f66e54397534f7d049506acabb2c', 'dabc02a058f8c3936a5fd6ddd3c50491'] [*] flag: {W3ak_IV_5uckS5}
DSC{W3ak_IV_5uckS5}