---
image: https://i.imgur.com/msUlGRr.jpg
---
QQ ㄋㄟㄋㄟ好打到咩噗CTF - 逢甲 write-up
===
* [逢甲 \- Web](#逢甲---Web)
* [CoolMD](#CoolMD)
* [Evil Robots](#Evil-Robots)
* [Google It Yourself](#Google-It-Yourself)
* [Notifications](#Notifications)
* [Stupid Session](#Stupid-Session)
* [Stupid Session Revenge](#Stupid-Session-Revenge)
* [逢甲 \- Misc](#逢甲---Misc)
* [GIForever](#GIForever)
* [Loseless Flowers](#Loseless-Flowers)
* [Real Google](#Real-Google)
* [Special RAR](#Special-RAR)
* [What Does the Wolf Say](#What-Does-the-Wolf-Say)
* [耗子尾汁](#耗子尾汁)
* [逢甲 \- Crypto](#逢甲---Crypto)
* [Base\-X](#Base-X)
* [Base\-XX](#Base-XX)
* [N=pq](#Npq)
* [左右分不清](#左右分不清)
* [逢甲 \- Reverse](#逢甲---Reverse)
* [babyCPP](#babyCPP)
* [C Minor](#C-Minor)
* [Popping Meow](#Popping-Meow)
* [Python2Exe](#Python2Exe)
----
# 逢甲 - Web
----
## CoolMD
### 解法
1. 打開頁面發現許多 CSS 效果 (彩色背景、旋轉圖片)
2. 題目提示查看 Source Code (原始碼)</br>

3. 於該頁面按下 Ctrl+U,即可於 <meta> 標籤中找到 flag
```htmlembedded
<meta name="robots" content="SWCTF{coOL_CSsY_Cha7_r0om}">
```
----
## Evil Robots
### 解法
1. 打開頁面發現顯示 404<br>

3. 根據題目名稱,猜測網站存在 robots.txt,可於 http://x.x.x.x/robots.txt 檢視
```
User-agent: *
Disallow: /nguinwiuniueniuw/hawuohudsoihfifiofs.php
```
2. 打開 http://x.x.x.x/nguinwiuniueniuw/hawuohudsoihfifiofs.php 即可拿到 flag
```
SWCTF{d0nt_iNDex_7HE_Fl46}
```
----
## Google It Yourself
### 解法
1. 打開頁面後,發現跳轉到 https://zh.lmgtfy.app/?q=pls+give+me+the+flag<br>

2. 開啟任意抓包工具,重新打開題目網址,即可於重導向回應 (302) 中找到 flag
```
HTTP/1.1 302 Found
Date: Wed, 30 Dec 2020 22:01:31 GMT
Server: Apache/2.4.38 (Debian)
X-Powered-By: PHP/7.4.13
Flag: SWCTF{G0ogle_It_YoUr53Lf}
Location: https://lmgtfy.app/?q=pls+give+me+the+flag
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
```
3. 或使用 `curl -v` 也可快速獲得相同結果
----
## Notifications
### 解法
1. 打開頁面後會跳出通知,不論點哪都會跳出謎因影片,重新整理就沒反應了 (從瀏覽器清理網站資料後才能再次出現)<br>

2. 從 F12 可找到 `register.js`,原始碼中即包含 `thirdparty/sw.js` 路徑 (連混淆都忘了 QQ)
3. 直接打開 http://x.x.x.x/thirdparty/sw.js 即可找到 flag
```javascript
/* SWCTF{SeRVICE_woRker_n3w_SubsCRiber} */
const showNotification = (title, body) => { ...
```
----
## Stupid Session
### 解法
1. 打開後發現登入頁面,登入錯誤會給出測試憑證 `test`/`test`<br>

2. 使用測試帳號登入後,觀察 cookie 可發現特殊資訊<br>

3. 將其 URL 解碼後,可得到看起來像 PHP 序列化的資訊
```r
解碼前: a%3A1%3A%7Bs%3A8%3A%22username%22%3Bs%3A4%3A%22test%22%3B%7D
解碼後: a:1:{s:8:"username";s:4:"test";}
```
4. 將 username 的值修改為,字串長度為 5 的 `admin`,並重新 URL 編碼
```r
編碼前: a:1:{s:8:"username";s:5:"admin";}
編碼後: a%3A1%3A%7Bs%3A8%3A%22username%22%3Bs%3A5%3A%22admin%22%3B%7D
```
5. 將 cookie 設定為修改後的內容並重新整理,即可獲得 flag<br>

----
## Stupid Session Revenge
### 解法
1. 同上可使用 `test`/`test` 登入
2. 檢查 cookie 同處,發現看起來像 JWT token 的資訊
```
eyJhbGciOiJub25lIn0.eyJ1c2VybmFtZSI6InRlc3QifQ.
```
3. 利用 JWT 官方線上工具 [JWT.IO](https://jwt.io/) 解碼,可得知該 token 不帶簽名校驗,且包含鍵名 username<br>

4. JWT token 的格式為 `(標頭).(資料).(校驗簽名)`,其中每個部分使用 [Base64URL](https://base64.guru/standards/base64url) 進行編碼,該編碼方式與 base64 的主要差別為:去掉後面 `=`,將 ==+== 換成 ==-==,==/== 換成 ==_==。故修改過程只使用 base64 操作也可。
5. 對資料部分使用 base64 解碼
```json
解碼前:eyJ1c2VybmFtZSI6InRlc3QifQ
解碼後:{"username":"test"}
```
6. 將 username 的值修改為 admin,並重新 base64 編碼 (若遇到特殊符號,依照規則修改即可),也可直接使用 base64URL 工具
```json
編碼前:{"username":"admin"}
編碼後:eyJ1c2VybmFtZSI6ImFkbWluIn0
完整拼起來的 token:eyJhbGciOiJub25lIn0.eyJ1c2VybmFtZSI6ImFkbWluIn0.
```
7. 將 cookie 設定為修改後的內容並重新整理,即可獲得 flag<br>

----
# 逢甲 - Misc
----
## GIForever
### 解法
1. 打開附件會發現 GIF 裡的 QRCode 變得越來越慢,掃描其中一幀後可拿到部分 flag 碎片<br>

2. Google 搜尋 "gif split online",使用任意服務拆解出 4 幀 QRCode
3. 手機掃描拼出完整 flag
```
SWCTF{UMarU_CRYin6_f0R3vEr_QAQAQ}
```
### 附註
- GIF 允許分別設定每幀的持續時間 (單位為 1/100 秒),最長可持續約 11 分鐘
----
## Loseless Flowers
### 解法
1. 使用 strings 查看圖片檔案
```bash
# strings ./Loseless_Flowers.png
JFIF
Exif
https://pastebin.com/AQ4WqdsQ
ICC_PROFILE
lcms
mntrRGB XYZ
9acspAPPL
-lcms
desc
^cprt
wtpt
bkpt
```
2. 從 JFIF 得知該圖片為 .jpg,一些 EXIF 資訊
3. 使用 exiftool,Windows Explorer (需重新命名副檔名為 .jpg) 或任意線上服務 (e.g. http://metapicz.com/#exif-box) 查看 EXIF
4. 獲得一個 pastebin 連結 (https://pastebin.com/AQ4WqdsQ
) 及解鎖密碼 (`x8U5@3HIZtMlmV@Upteu`)<br>

5. 打開連結輸入密碼即可獲得 flag<br>

----
## Real Google
### 解法
1. 題目給了一個瀏覽器連接不上的網址: https://thisisrealgoogle.tw
2. 使用 dig 命令查詢,該網域所有類型的 DNS 紀錄
```bash
# dig thisisrealgoogle.tw any
;; Got bad packet: FORMERR
311 bytes
7f 42 81 80 00 01 00 08 00 00 00 01 10 74 68 69 .B...........thi
73 69 73 72 65 61 6c 67 6f 6f 67 6c 65 02 74 77 sisrealgoogle.tw
00 00 ff 00 01 c0 0c 00 02 00 01 00 00 2a 2f 00 .............*/.
13 07 6e 73 2d 39 31 2d 61 05 67 61 6e 64 69 03 ..ns-91-a.gandi.
6e 65 74 00 c0 0c 00 02 00 01 00 00 2a 2f 00 0b net.........*/..
08 6e 73 2d 31 39 33 2d 62 c0 39 c0 0c 00 02 00 .ns-193-b.9.....
01 00 00 2a 2f 00 0b 08 6e 73 2d 32 33 35 2d 63 ...*/...ns-235-c
c0 39 c0 0c 00 06 00 01 00 00 54 5f 00 27 03 6e .9........T_.'.n
73 31 c0 39 0a 68 6f 73 74 6d 61 73 74 65 72 c0 s1.9.hostmaster.
39 5f ed 14 80 00 00 2a 30 00 00 0e 10 00 09 3a 9_.....*0......:
80 00 00 2a 30 c0 0c 00 0f 00 01 00 00 2a 2f 00 ...*0........*/.
0f 00 0a 05 73 70 6f 6f 6c 04 6d 61 69 6c c0 39 ....spool.mail.9
c0 0c 00 0f 00 01 00 00 2a 2f 00 07 00 32 02 66 ........*/...2.f
62 c0 b9 c0 0c 00 10 00 01 00 00 01 2b 00 28 27 b...........+.('
76 3d 73 70 66 31 20 69 6e 63 6c 75 64 65 3a 5f v=spf1.include:_
6d 61 69 6c 63 75 73 74 2e 67 61 6e 64 69 2e 6e mailcust.gandi.n
65 74 20 3f 61 6c 6c c0 0c 00 2c 00 01 00 00 01 et.?all...,.....
2b 00 19 01 01 53 57 43 54 46 7b 44 31 47 5f 69 +....SWCTF{D1G_i
4e 54 30 5f 54 48 45 5f 64 4e 53 7d 00 00 29 02 NT0_THE_dNS}..).
00 00 00 00 00 00 00 .......
```
3. 或使用線上工具 (e.g. [Google Admin Toolbox](https://toolbox.googleapps.com/apps/dig/#ANY/)),可於 SSHFP 紀錄找到十六進位編碼的 flag<br>

----
## Special RAR
### 解法
1. 題目附件提供一個 .rar 壓縮包,可用多個解壓縮軟體分析
2. Windows/Wine - WinRAR:只能看到加密後的 flag.txt 及提示檔案 password.txt
3. Windows/Wine - 7-Zip:除了上述檔案以外還能看到 password.txt:key1.txt 及 password.txt:key2.txt 兩個 NTFS stream<br>

4. Linux - unrar/strings:能觀察到 NTFS stream 名稱但無法解壓縮其內容
```
# unrar vta Special_RAR.rar
Name: STM
Type: NTFS alternate data stream
Target: :key1.txt
Size: 67
Packed size: 78
Ratio: 116%
Attributes: .B
CRC32: AD7573EE
Host OS: Windows
Compression: RAR 5.0(v50) -m3 -md=128K
Name: STM
Type: NTFS alternate data stream
Target: :key2.txt
Size: 66
Packed size: 76
Ratio: 115%
Attributes: .B
CRC32: 8C43157E
Host OS: Windows
Compression: RAR 5.0(v50) -m3 -md=128K
```
5. 透過 7-Zip (GUI) 解壓縮 key1.txt 及 key2.txt 後可獲得 flag.txt 的解壓縮密碼:`zE9cqSU^oyEGuA@6Ji1c`
```
SWCTF{bRuHHh_deSi6n_From_N7FS}
```
### 附註
- ~~偷來的 (x~~
----
## What Does the Wolf Say
### 解法
1. 題目附帶 Minecraft 截圖及其對應的存檔壓縮包,截圖中的 flag 變成亂碼了<br>

2. 通過在 NBTExplorer 中搜尋 `"SWCTF"`,可於玩家工具欄 (inventory) 的命名牌上 & 狼的名字上找到相同的 flag<br>

3. 也可以將存檔資料夾下的 level.dat 以 gzip/7-Zip 解壓縮,並用 strings+grep 拿到工具欄上的 flag
```bash
gzip -S .dat -dk level.dat
strings level | grep SWCTF
# i{"text":"\u00A7eSWCTF\u00A76{\u00A7a\u00A7kWhat_kinD\u00A76\u00A7k_oF_d0g_\u00A7c\u00A7kis_This\u00A76}"}
```
4. 由於 flag 有 Unicode 逃逸過的字元,可通過 [CyberChef](https://gchq.github.io/CyberChef/) 的 `Unescape string` 及 `Find/Replace (§\w)` 去除<br>

### 附註
- `§k` 為顯示亂碼的原因
----
## 耗子尾汁
### 解法
1. 題目附件是個 .gif
2. 通過 binwalk 分析,得知檔案內包含 GIF, 7-zip, bzip2 等 (檔案)特徵
3. 通過 `binwalk -e` 自動將各部分存成檔案
4. 利用 strings+grep 得到 flag<br>

----
# 逢甲 - Crypto
----
## Base-X
### 解法
1. 題目: `wpZTV0NURntCYXNlNjRfdEhlX0xhTkdVNDZlX09mX2g0Q2szcnN9Cg==`
2. Base64 解碼
```
SWCTF{Base64_tHe_LaNGU46e_Of_h4Ck3rs}
```
### 附註
- ~~抱歉 Crypto 硬塞 base64 :(~~
----
## Base-XX
### 解法
1. 題目: `ZIpR1J2NvPqtgSJxbO4xnJ1JTGotDRpxoO4ZnLoJiMqxYAIt5TE++`
2. 使用線上 [XXDecode](http://www.webutils.pl/index.php?idx=xx) 還原明文
```
SWCTF{only_ghosT5_KNOw_this_Encod1NG}
```
### 附註
- ~~偷來的 (x~~
----
## N=pq
### 解法
1. 題目給的 RSA 參數:
```json
N = 16857159784242147958930006036274524315067659003347665436247836447121615960042560515473548747696129683
e = 65537
encrypted_flag = 4133875657690452080396474983972067706781976275589651694439550567678165824984290994659861724649235686
```
2. 將 N 扔去 [factordb](http://factordb.com/index.php?query=16857159784242147958930006036274524315067659003347665436247836447121615960042560515473548747696129683) 可得到 p, q
```json
p = 23
q = 732919990619223824301304610272805405002941695797724584184688541179200693914893935455371684682440421
```
3. 用 Python 3.x 計算私鑰 d、解密並轉回明文字串
```python=
from Crypto.Util.number import long_to_bytes
p = 23
q = 732919990619223824301304610272805405002941695797724584184688541179200693914893935455371684682440421
e = 65537
phiN = (p-1)*(q-1)
N = p*q
encrypted_flag = 4133875657690452080396474983972067706781976275589651694439550567678165824984290994659861724649235686
def decrypt():
d = pow(e, -1, phiN) # Python 3.8+ ONLY
flag = pow(encrypted_flag, d, N)
return long_to_bytes(flag).decode()
print(decrypt())
```
4. 或使用 [RsaCtfTool](https://github.com/Ganapati/RsaCtfTool) 自動處理
```bash
python3 RsaCtfTool.py \
-n 16857159784242147958930006036274524315067659003347665436247836447121615960042560515473548747696129683 \
-p 23 \
-q 732919990619223824301304610272805405002941695797724584184688541179200693914893935455371684682440421 \
-e 65537 \
--uncipher 4133875657690452080396474983972067706781976275589651694439550567678165824984290994659861724649235686
```

----
## 左右分不清
### 解法
1. 題目: `RVBSE{QNS_5TooNQsr_tOO3q_KNvdQbzRd}`
2. 自動解密:https://www.dcode.fr/caesar-cipher
3. 手動1:用 [CyberChef](https://gchq.github.io/CyberChef/) 的 ROT13 試到對為止
4. 手動2:flag 字元經過位移 (rotation),通過把 `[S, W, C, T, F]` 對應的 ASCII 碼分別減去 `[R, V, B, S, E]` 可得到 `key = 1`,再用腳本還原明文
```python=
import string
def rot(char, key):
if char in string.ascii_lowercase:
return chr(((ord(char) + key - ord('a')) % 26) + ord('a'))
elif char in string.ascii_uppercase:
return chr(((ord(char) + key - ord('A')) % 26) + ord('A'))
else:
return char
cipher = 'RVBSE{QNS_5TooNQsr_tOO3q_KNvdQbzRd}'
key = 1
flag = ''.join(rot(char, key) for char in cipher)
print(flag)
```
----
# 逢甲 - Reverse
----
## babyCPP
### 解法
1. 題目提供一個要眼速夠快才能看出 flag 的小遊戲</br>

2. 解法1:將畫面錄起來一幀一幀看就行了 (e.g. 上面的 GIF)
3. 解法2:使用 `babyCPP.exe > a.txt` 把 stdout 導到檔案中即可
----
## C Minor
### 解法
1. 題目要求輸入正確 flag<br>

2. 通過靜態分析可猜測執行檔為 .NET 程式<br>

3. 於 dnSpy 中隨便瀏覽即可發現處理 flag 的主邏輯,推測把內嵌資源 cipher 逆轉後的每位元組加上 75 即可還原成明文</br>

4. 利用 dnSpy 功能 (右鍵 -> Save cipher) 將資源 cipher 儲存成檔案方便處理</br>

5. 將檔案拉去 [CyberChef](https://gchq.github.io/CyberChef/) 的 input 區,套上 `ADD(75)` (解密)、`Reverse` (逆轉) 即可獲得 flag</br>

----
## Popping Meow
### 解法
1. 透過 adb 或其他方式安裝完 .apk 後,打開 app 後發現影片擋住了 flag 字串</br>
<img src="https://i.imgur.com/gwjFwHC.gif" width="45%"></img>
2. 從 jadx-gui 的 `Resources -> resources.arsc -> res -> values -> strings.xml` 中可找到 flag 字串</br>

3. 或將 apk unzip 後使用 strings+grep 解出 flag</br>

----
## Python2Exe
### 解法
1. 題目給了一個用 PyInstaller 打包的執行檔<br>

2. 利用 [pyinstxtractor](https://github.com/extremecoders-re/pyinstxtractor) 靜態解出 pyc
3. 對 flag.pyc 使用 strings+grep 即可解出 flag
4. 或使用 [線上反編譯工具](https://www.decompiler.com/) 獲得 [原始碼](https://www.decompiler.com/jar/4cd07393b37a490f818223ff31b367a9/flag.py) (並可透過 CyberChef 的 Unescape Unicode Characters 將 \u 解碼成中文),並從原始碼中獲得 flag
```python=
import os
def login():
print('::: packed by PyInstaller :::\n')
pwd = input(u'曹操:欲得吾旗,必交密令: ')
if pwd == u'水之呼吸 貳之型':
print('SWCTF{PyThon_Scr1PT_kiddiES}\n')
else:
print(u'因為密碼錯誤,你被曹操流放了...\n')
if __name__ == '__main__':
try:
login()
os.system('pause')
except KeyboardInterrupt:
pass
```
----