TSCCTF write up (賽後解)

NPCMike Lv.99

這篇整理 TSCCTF REV 題目的賽後補解,紀錄我如何使用 IDA、GDB/GEF 與 ltrace 觀察程式邏輯,並透過靜態與動態分析逐步取得 flag。

REV

本篇紀錄 TSCCTF 賽後補解的 REV 題目。

題目包含:

  • What_Happened
  • Chill Checker
  • Gateway to the Reverse
  • Meoware

What_Happened

雖然題目說不用靜態分析、直接用動態分析即可,但我還是稍微用 IDA 看了一下。以下是靜態分析後的結果。

我覺得重點在 encdec 兩個函式,所以接下來就直接去看這兩個函式。

Chill Checker

先打開 IDA 做逆向分析,可以知道程式會先輸入長度為 8 的 input,再經過 7 次 complex_function 加密,最後要等於 SGZIYIHW

這裡要注意順序要顛倒,原因是執行檔是 little-endian,所以儲存順序會顛倒。

靜態逆向

觀察 main 可以知道輸入的每個字元都會逐一經過 complex_function 加密:

1
Input -> complex_function -> SGZIYIHW

再觀察 complex_function 可得到以下重點:

  • Input 必須在 AZ 之間。
  • 加密公式如下:
1
((a1 - 65 + 31 * a2) % 26 + 65) = SGZIYIHW

反推 a1

1
2
3
(a1 - 65 + 31 * a2) % 26 = SGZIYIHW - 65
a1 - 65 + 31 * a2 = SGZIYIHW - 65 + 26k
a1 = SGZIYIHW + 26k - 31 * a2

寫成 exploit:

1
2
3
4
5
6
7
8
9
10
Output = "SGZIYIHW"
Input = ""

def dec_func(a1, a2):
return chr((ord(a1) - 65 - a2 * 31) % 26 + 65)

for i in range(8):
Input += dec_func(Output[i], (i + 8))

print(Input)

執行後得到真正要輸入的字串:

1
ENBFQVPZ

重新啟動 ELF 檔並輸入:

1
./chill
1
2
3
Whisper your code: ENBFQVPZ
Man, you're really on fire!
Your flag is: TSC{t4k3_1t_3a$y}

動態逆向

用 IDA 觀察 main 可知,程式會將原始字串加密後由 strcmp 比較,所以只要隨便輸入東西,並在比較時修改暫存器內的值即可。

strcmp@plt 前下斷點:

1
b *0x000055555555544f

開始執行程式,輸入範圍在 AZ 之間且長度為 8 的字串:

1
r
1
Whisper your code: ABCDABCD

此時可以看到 strcmp@plt 傳入的參數。我們要改的是 $rdi 指向的值:

1
2
set {char[9]} 0x00007fffffffdc90 = "SGZIYIHW"
c

即可通過檢查並取得 flag:

1
Your flag is: TSC{t4k3_1t_3a$y}

Gateway to the Reverse

方法一:GDB + GEF

先用 IDA 打開並觀察,發現 s2 是單獨計算的,與輸入是多少無關。因此只要在 strcmp 時設斷點,觀察 s2 就可以知道輸入要等於什麼。

1
2
b strcmp@plt
r
1
Enter the access key: ABCDABCD

接著觀察傳入 strcmp 的參數,即可得知 flag。

方法二:ltrace

因為 ltrace 會把函式之間的關係顯示得很清楚,自然也能看到傳入的參數。

Meoware

經過觀察後,重點在於程式會有一段 rand() 迴圈:

1
2
3
4
5
6
v3 = time(0LL);
srand(v3);

while (rand()) {
show_pic();
}

只要讓 rand() == 0,即可結束迴圈。

結束迴圈後,會出現:

1
std::operator<<<std::char_traits<char>>(&_bss_start, "flag is:");

所以很明顯要先結束迴圈,並繼續執行到最後。

進入 GEF 做動態分析:

1
2
3
4
5
starti
i func
b main
c
disas main

可以知道程式會先跳到 <main+593>,接著進行比較:

1
test eax, eax

如果 eax 不為 0,則回到迴圈裡。因此在這裡設斷點,再把 eax 設成 0 即可跳出迴圈。

1
2
3
4
b *main+598
c
set $eax = 0
c

最後得到 flag:

1
flag is:TSC{Bobo_milk-tea_black-carbon}
  • Title: TSCCTF write up (賽後解)
  • Author: NPCMike
  • Created at : 2025-01-22 00:00:00
  • Updated at : 2026-05-13 16:49:36
  • Link: https://npcmike.github.io/2025/01/22/2025-1-22-TSCCTF/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments