2025 AIS3 考試前準備 / MyFirstCTF 寫作

Hi 大家好,我是梅森,今年五月底我參加了對於學生來說頗為重要的 CTF 競賽 — 由 AIS3 舉辦的 Pre-Exam 和 MyFirstCTF。這次競賽除了是進入 AIS3 暑期課程的重要門票之外,也是對於去年暑假有參加過 AIS3 Junior 2024(沒看過可以去看一下)的我來說,算是一個很好的機會可以測試一下自己這段時間的進步幅度。說實話這次比賽難度對我而言有點難度,雖然有些題目卡了很久,但最後還是順利解出來了,特別是 Rev 和 Crypto 的部分讓我學到不少新東西,所以這次想透過 writeup 的方式記錄一下解題過程,順便分享給同樣在學習資安的朋友們參考~
比賽過程中我發現自己在 Web 跟 OSINT 類型的題目比較快就能解出來,但在逆向和 PWN 的部分還是需要花比較多時間去理解和分析,特別是 WebAssembly 逆向工程對我來說算是比較新的領域。整體來說這次比賽讓我對自己的能力有更清楚的認知,也知道接下來要加強的方向。
雜項
歡迎
- 題目上就寫出 FLAG 但不能直接複製
直接手打出來- 獲取 FLAG
AIS3{Welcome_And_Enjoy_The_CTF_!}
Windows CTF
- 題目 FLAG 格式為 AIS3{Google Maps上的店名:拉麵名稱}
- 題目給了一張圖片,看來是
隱寫術呢

- 將圖片用 exiftool 或 Aperi’Solve 分析,你會發現什麼都拿不到
- 發現唯一的線索是右上角的發票,根本是明明的暗示
- 分析發票資訊,拉麵店店名有”平和”,賣方為 3478592?,有一個完整的 QRCode

- 如果上網 Google “平和 拉麵” 只會出現香港麵店
- 眾所皆知,賣方編號為八碼,且與統一編號相同,因此可以在 財政部 稅籍登記資料公示查詢網 從 34785920 往 34785929 開始查詢猜測店名
- 查詢到 34785923 會發現是一家叫做”平和溫泉拉麵店”的店家,地址在”宜蘭縣礁溪鄉德陽村5鄰礁溪路5段108巷1號”

- 在 Google Maps 貼上地址後會發現,這家店的正確店名是 “樂山溫泉拉麵”

- 掃描左邊的 QRCode,會發現是以下內容:MF1687991111404137095000001f4000001f40000000034785923VG9sG89nFznfPnKYFRlsoA==:**********:2:2:1:蝦拉
- 搭配菜單猜測為蝦拉麵
- 獲取 FLAG
AIS3{樂山溫泉拉麵:蝦拉麵}
AIS3 微型伺服器 — Web / 雜項
- 根據題目引用 GitHub 敘述會發現這是一個安全防護低、以 c 語言編寫的網頁伺服器
- 題目原始檔為可在 window kali linux 系統上執行之包裝好的伺服器檔案,在本地架設執行後發現會顯示同一資料夾下之檔案
- 根據題目敘述要求尋找名稱為
/readable_flag_隨機字串之 FLAG 檔案 - 輸入 ctfd token 開啟 Instance
- 進入 Instance 發現進入
[http://chals1.ais3.org:20127/index.html](http://chals1.ais3.org:20127/index.html)

- 按照本地端測試結果,回到上一層
http://chals1.ais3.org:20127/,可以發現此目錄下只有 index.html

- 嘗試發現
http://chals1.ais3.org:20127/index.html/../一樣會跳到上一層,推斷可以進行 目錄遍歷(Directory traversal)攻擊

- 按照系統架構,通常為了看見系統架構、使用者資訊或密碼等,測試透過路徑遍歷進入 /etc 資料夾http://chals1.ais3.org:20902/..%2F..%2F..%2F..%2F..%2F/etc

- 我在這邊卡了很久,想說到底是哪個底下的資料夾可能存在 flag

- 後來在某次偶然打錯成
http://chals1.ais3.org:20902/..%2F..%2F..%2F..%2F..%2F,發現原來只要執行路徑遍歷就能看到flag檔案

- 接著進入
http://chals1.ais3.org:20902/..%2F..%2F..%2F..%2F..%2F/readable_flag_BjSvx3Dj72Xd2GlSNQueTNxhE7PTUgSS就能得到flag

- 獲取 FLAG
AIS3{tInY_We8_53RvER_w1tH_fILe_Br0Ws1nG_as_@_Fe4Tur3}
網路
托莫林
- 分析題目,伺服器開放在 http://chals1.ais3.org:30000,並提供了一段 Go 程式碼:
http .Handle ( "/" , http.FileServer ( http.Dir ( "/app/Tomorin" ))) http .HandleFunc ( "/flag" , func (w http.ResponseWriter, r *http.Request) { http .Redirect (w http.ResponseWriter, r *http.Request) { http .Redirect ( w, r, "httpshttps://lobe/ http.StatusFound) }) |
初步觀察:
/被設為靜態檔案伺服器,對應的是 /app/Tomorin/flag被設定為 redirect,到一個 YouTube 連結,顯然是誘餌- 推測 flag 被藏在非公開目錄中
- 嘗試直接訪問
/flag,結果為一段 youtube 影片,確認是 redirect,不是 flag 本體 - 嘗試對
/進行靜態檔案掃描爆破,使用字典搭配 ffuf 掃描常見檔名,沒有特別發現
ffuf -w common.txt -u http://chals1.ais3.org:30000/FUZZ -mc all |
- 後來我請 AI 生了一份常見的 flag 檔案名稱來用 ffuf 爆破
cat > strong-list.txt <<EOF |
- 再一次進行 ffuf 爆破
ffuf -w strong-list.txt -u http://chals1.ais3.org:30000/FUZZ -mc all |
- 從 ffuf 的輸出來看,有三個 payload 成功回傳了 200 OK,且大小一致(Size: 95),成功發現三個 flag 位置:
..%2fflag [Status: 200, Size: 95] |
透過 curl 得到三個頁面皆為正確flag

- Get FLAG
AIS3{G01ang_H2v3_a_c0O1_way!!!_Us3ing_C0NN3ct_M3Th07_L0l@T0m0r1n_1s_cute_D0_yo7_L0ve_t0MoRIN?}
Login Screen 1
- 從題目原始碼發現會需要在 index.php 登入得到 user SESSION,接著進入 2fa.php 拿到 code SESSION 才能進入 dashboard.php 拿到 flag
- 根據頁面提示,透過 guest/guest 進入到 2fa 並輸入 000000,發現只能在 dashboard 讀到
Only admin and view the flag.,所以要設法拿到admin權限 - 原本在 index.php 時想說要如何才能取得 admin,用 sqlmap 爆後發現不可行,無意間嘗試輸入 admin/admin 結果就取得 admin 權限,成功進入 2fa
- 但目前困境在於不知道要如何獲得到正確 2fa code,想說嘗試爆破看看有沒有辦法爆出來,我試了不同速度的腳本,要不就太快被擋,要不就太慢
- 觀察原始程式會發現,如果沒有成功拿到 code SESSION 雖然在 2fa 想直接跳到 dashboard 一定會被重導向回 2fa,但是可以用 burp suite 的 repeater 來測試看看會回傳什麼
- 於是乎開啟 burp suite 登入 admin/admin

- 接著進入 2fa

- 把網址修改成
/dashboard.php - 將封包點右鍵送到 repeater 中

- 成功獲得 flag

- Get FLAG
AIS3{1.Es55y_SQL_1nJ3ct10n_w1th_2fa_IuABDADGeP0}
Rev
web flag checker
- 此題是一個使用 WebAssembly 製作的的 flag 檢查器,需要輸入正確的 flag 才會顯示 “Success”
- 初步檢視 HTML 檔案,發現這是一個簡單的輸入介面:
- 有一個輸入框用於輸入 flag
- 有一個 “check” 按鈕用於驗證
- 結果會顯示在頁面上
- 從 index.js 可以看出這是用 Emscripten 編譯的 WebAssembly 程式
接著分析 WebAssembly:
查看 WASM 程式碼,找到關鍵函數 主要驗證函數 (func 9)
wasm(func (;9;) (type 3) (param i32) (result i32) |
這個函數執行以下步驟:
- 檢查輸入長度是否為 40 字元 (i32.const 40)
- 初始化魔術常數 -39934163 (0xFD9EA72D)
- 設置 5 個 64 位元的預期值
- 將輸入分成 5 組,每組 8 字元
- 對每組進行位元左旋轉操作
- 將結果與預期值比較
從 WASM 程式碼中提取的期望值:
wasmi64.const 7577352992956835434 ; 0x692E506F4734536A |
旋轉函數 (func 8) 實作 64 位元左旋轉操作:
wasm(func (;8;) (type 7) (param i64 i32) (result i64) |
分析加密演算法:
- 發現程式使用魔術常數 -39934163 (0xFD9EA72D)
- 旋轉量計算公式:旋轉量 = (ROTATION_KEY >> (i * 6)) & 63
- 對每組 8 字元進行左旋轉後與預期值比較
撰寫 Python 解密腳本:
#!/usr/bin/env python3 |
def decode_flag(): |
def reverse_rotation_64(value, shift): |
def bigint_to_ascii(value): |
def analyze_rotation_key(rotation_key): |
if __name__ == "__main__": |
- 輸出結果

- Get FLAG
AIS3{W4SM_R3v3rsing_w17h_g0_4pp_39229dd}
Crypto
Stream
- 題目原始程式碼中提供了一段以 sha512(os.urandom(True)) 製造隨機噪音的迴圈,最後一行則使用如下方式將 flag 做加密處理並輸出:
def hexor(a: bytes, b: int): |
print(hexor(flag, getrandbits(256))) |
- 發現程式中前 80 行的輸出皆為雜湊後亂數與隨機 key² 進行 XOR,意圖混淆視聽
- 最後一行才是重點,真正的 flag 被轉為 bytes 後與一個 256-bit 隨機整數的平方做 XOR,然後輸出為十六進位字串
- 加密公式還原
encrypted = int.from_bytes(flag, "big") ^ key**2 - 只要知道 encrypted 和猜中 flag 開頭,即可推得 key**2,進而爆破還原出完整 flag
- 利用 flag 格式 AIS3{…},我們假設開頭為 AIS3{,將其轉為 int 後與 encrypted XOR,得到 key 的平方附近值
- 開始嘗試爆破 key,取開平方後 ±10000 範圍暴力嘗試,解回來的結果若符合 AIS3{ 開頭與 } 結尾,即為正解
- 解出結果,成功還原出 flag
Payload:
import math |
enc_hex = "0x1a95888d32cd61925d40815f139aeb35d39d8e33f7e477bd020b88d3ca4adee68de5a0dee2922628da3f834c9ada0fa283e693f1deb61e888423fd64d5c3694" |
known_prefix = b“AIS3{” |
對於範圍內的增量(-10000,10000): |
- 獲取 FLAG
AIS3{no_more_junks...plz}
心得
這次的 AIS3 Pre-Exam / MyFirstCTF 對我來說算是一個很好的練習機會,整體難度雖然對我來說仍然有挑戰,但能夠讓我可以測試自己這段時間學習資安的成果。比較有趣的是題目類型很多元,從基礎的 MISC 到需要深入分析的 Rev 和 Crypto 都有涵蓋到,而且可以看出 author 很絞盡腦汁且用心的出題。
其中讓我比較有信心的是 Ramen CTF 這題,雖然是 OSINT 類型,但我很快就從發票資訊推敲出店名,透過財政部稅籍查詢系統和 Google Maps 找到正確答案,感覺平常練習 Google 搜尋技巧還是有用的。
Web 類的題目也很實用,像是 Tomorin db 這題讓我學到了更多關於 Go 語言 HTTP 服務的漏洞利用技巧,用 ffuf 進行目錄爆破也是很經典的手法。Login Screen 1 能夠考驗對於 Burp Suite 是否足夠熟悉,利用 repeater 功能繞過 2FA,這種解法還蠻巧妙的。
Rev 的部分是我覺得最有挑戰性的,WebAssembly 逆向工程對我來說算是比較新的領域,需要分析 WASM 程式碼找出加密演算法,然後寫 Python 腳本進行反向解密。這題讓我對位元運算和旋轉加密更加了解,也學到了如何處理大整數和 ASCII 轉換。不過說實話我在這部分花了很多時間,發現自己在逆向工程這塊還需要多加練習。
Crypto 的 Stream 題目設計得很聰明,前面 80 行都是用來混淆視聽的雜訊,真正的 flag 藏在最後一行。利用已知的 flag 格式 AIS3{ 來推算 key 的平方值,然後進行暴力破解,這種攻擊手法在現實中也很常見。
整體來說,這次比賽讓我對自己的能力有了更清楚的認知,也發現了一些需要加強的地方,特別是 Pwn 和 Rev 的部分。雖然這次比賽沒有解出 Pwn 題目,但我知道這是我接下來必須要重點加強的領域,畢竟類似得題目在 CTF 中佔了很重要的份量。Rev 的部分雖然有解出來,但過程中還是有些吃力,需要多練習不同類型的逆向工程題目。這次的名次雖然處於一個比上不足,比下有餘的位置,但幸好最後有成功進入 AIS3 暑期課程,讓我更加期待。
希望我的文章能給各位讀者們幫助,歡迎幫我按個拍手跟追蹤,您就能收到新文章的通知,也歡迎把本文分享給您的親朋好友,讓更多人知道喔!
若如有任何疑問及合作歡迎來信:ohmygodmason@gmail.com
By 那個成天泡在電腦裡的梅森 on August 22, 2025.