TSCCTF write up (賽後解)
REV
目錄
- Reverse
- What_Happened
- Chill Checker
- Gateway to the Reverse
- Meoware
What_Happened
雖然題目說不用用靜態分析直接用動態,但我還是稍微用了ida一下,以下是靜態完的結果


這裡是我覺得的重點,所以我接下來就直接去看了enc跟dec兩個函式
Chill_Checker
先打開ida 做逆向分析,可知他會先輸入長度為8的Input ,再經過7次complex_function 加密,要等於”SGZIYIHW”(要顛倒,原因是此執行檔是little-endian 所以儲存順序會顛倒

以下可以有兩種方式逆向
靜態逆向

透過觀察main 可知輸入的Input 每個字元都會逐一經過complex_function加密,所以可以得到以下示意圖:
1 | Input -> complex_function -> ”SGZIYIHW” |
再觀察complex_function 可得到以下重點

綠色:Input 要在’A’(65) ~ ’Z’(89)之間
藍色:為加密演算法,所以可得以下公式
((a1 - 65 + 31 * a2) % 26 + 65) = [SGZIYIHW]
做逆向求 a1:
(a1 - 65 + 31 * a2) % 26 = [SGZIYIHW] - 65
a1 - 65 + 31 * a2 = [SGZIYIHW] - 65 + 26k
a1 = [SGZIYIHW] - 65 + 26k + 65 - 31 * a2
a1 = [SGZIYIHW] + 26*k - 31 * a2
以他做一個exploit.py
1 | Output = "SGZIYIHW" |
即可得到真正要輸入的字串:
1 | TSCCTF\REV> python exploit.py" |
再重新啟動elf檔並輸入”ENBFQVPZ”即可得到flag
1 | ┌──(kali㉿kali)-[~/Downloads] |
動態逆向
用ida 觀察main可知他會將原始字串加密後由strcmp去進行比較,所以只要隨便輸入東西在比較時把暫存器內的值進行更動即可
1 | gef➤ disas main |

紅色範圍:complex_function 加密,結束後到藍色strcmp做比較
藍色範圍:比較函式。對他做斷點,以便後續竄改加密結果
1 | gef➤ b *0x000055555555544f |
並開始程式,輸入範圍在A~Z之間且為長度為8個字元即可
1 | gef➤ r |
此時會看到strcmp@plt的參數會傳入的值,並對其進行修改

我們要改的值是$rdi的值 ( by calling convention, 呼叫慣例,修改完後繼續執行程式即可通過檢查並成功取得flag
1 | gef➤ set {char[9]} 0x00007fffffffdc90 = "SGZIYIHW" |
Gateway_to_the_Reverse
方法一 ( gdb-gef
先用ida打開並觀察發現(看不懂,s2 是單獨計算的,與輸入是多少無關,所以只要在strcmp 時,設個斷點,觀察s2即可看到輸入要等於什麼
1 | gef➤ b strcmp@plt |

即可得知flag了
方法二 ( ltrace

因為它會把函式之間的關係都顯示得很清楚,自然也能看到傳入的參數為何
Meoware
經過觀察後重點在於它會有一段,所以只要rand() == 0 即可結束迴圈


1 | v3 = time(0LL); |
再來結束迴圈後出現了std::operator<<<std::char_traits<char>>(&_bss_start, "flag is:"); ,所以很明顯我們要先結束迴圈並繼續執行到最後
所以到gef裡面進行動態分析:
1 | gef➤ starti |


由此可知他迴圈是先跳到<main+593> 接著進行比較,test eax,eax ,如果不為 0,則回到迴圈裡,所以在此設斷點,再把eax設為0即可跳出迴圈並執行程式。
1 | gef➤ b *main+598 |
- Title: TSCCTF write up (賽後解)
- Author: Mike
- Created at : 2025-01-22 17:40:45
- Updated at : 2025-04-30 12:18:13
- Link: https://happymike0103.github.io/2025/01/22/2025-1-22-TSCCTF/
- License: This work is licensed under CC BY-NC-SA 4.0.