THJCC 我出的題目官方解
Super baby reverse
先 file 看看檔案類型
1 | alvin@suiseiiscute ~/Downloads> file THJCC_Super_Baby_Reverse |
ELF 檔案 接著丟 ida

Flag: THJCC{BaBY_r3v3rs3_f0r_beggin3r}
Fllllllag_ch3cker_again?
老樣子 先file 看看檔案類型
1 | alvin@suiseiiscute ~/Downloads> file chal |
一樣是 ELF 接著丟 ida
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
看 code 發現他就是個簡單 XOR
1 | from struct import pack |
Flag: THJCC{A_Simpl3_R3v3r3_using_CPP_d0ing_X0R}
THJCC-anti-virus
一樣先 file 看 檔案類型
1 | alvin@suiseiiscute ~/Downloads> file anti-virus |
好 ELF 看到 no section header 覺得怪怪的
binwalk 看看
1 | alvin@suiseiiscute ~/Downloads> binwalk anti-virus |
看到
1 | Copyright text: "Copyright (C) 1996-2025 the UPX Team. All Rights Reserved. $ " |
這段,發現被 upx 加殼過了
解殼就好
1 | alvin@suiseiiscute ~/Downloads> upx -d anti-virus -o anti-virus-unpacked |
接著丟 IDA 逆向
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
在 main function 我們會看到他去 call start_challenge 這個 function
那 分析一下 start_challenge 在幹嘛吧
1 | unsigned __int64 start_challenge() |
簡單來講 他就是一個 function 去判斷你輸入的東西 然後呢,你輸入的東西要 XOR 過 並且同時還需要一個 magic header 才能驗証通過,驗証通過後 = RCE
那 magic header 呢? 看到有 call 一個 check_command function 追下去
1 | _BOOL8 __fastcall check_command(__int64 a1) |
發現 magic header 要放 THJCCAV
並且要繞過
1 | if ( !strstr(haystack, "system") |
這串 才能打 RCE
接著 條件都有了 來搓 exploit 吧
1 |
|
這題是透過 Reverse shell 去打,但不是每個人都有 Reverse shell
所以有第二個 exploit (感謝 Grissia)
1 | from pwn import * |
Flag: THJCC{An_3a3y_Ant1_Viru5_H0p3_y0u_enj0y_it}
幽々子の食べ物
這題我只出第一關的 VMP 所以我只會講解第一 part
decompile 後我們可以注意到幾個重點
1 | v3 = getenv("VMP_SKIP_AD"); |
這邊是個 anti-debug 除非 VMP_SKIP_AD = 1
接著
1 | v6 = (unsigned __int8 *)malloc(0x40FB0u); |
- 分配一塊大 buffer buf = malloc(0x40FB0)
- 用 unk_402160 初始化(payload 初始 blob)
並且 看到
1 | v9 = (char *)memcpy(v8, &unk_443114, n); |
會得知 他是 XOR / LCG stream cipher 去解密 120 bytes 的 VM bytecode
所以就生了個 hook 去把東西 unpack
1 |
|
至於一開始 anti-debugger 怎麽繞
1 | export VMP_SKIP_AD=1 |
這樣就好
編譯
1 | gcc -shared -fPIC -O2 -Wall -Wextra -ldl unpacked.c -o unpacked.so |
接著
1 | export VMP_SKIP_AD=1 |
然後就
1 | file unpacked.bin |

boom 解完了
THJCC-anti-virus-revange
這題看題目名稱就可以知道是 THJCC-anti-virus 的 revenge 題目 恩對 題目英文拼錯(不是故意的)
好那這題本質上跟上一題差不多,都是要 RCE .w.
1 | if ( read(0, s, 7u) == 7 && read(0, &v3, 1u) == 1 && (v1 = read(0, v4, v3), v1 == v3) ) |
那這個 function 是判斷能否 executing command
一樣發現
1 | if ( strncmp((const char *)a1, "THJCCAV", 7u) ) |
一樣發現 magic header 需要 THJCC AV
並且 sub_2223
1 | unsigned __int64 __fastcall sub_2223(__int64 a1, __int64 a2, int a3) |
定義:
C[i] = in[i]:ciphertext byte
prev = C[i-1],且 prev=0 當 i=0
K(i, prev) = sub_21C9(i, prev)
T[i] = v8[i]:中間值
則:
並且
*(_BYTE *)(j + a2) = (v8[j] >> 5) | (8 * v8[j]);
這段是在做位元旋轉
1 | char __fastcall sub_21C9(int a1, char a2) |
這個 function
是在
byte_3010
1 | .rodata:0000000000003010 byte_3010 db 3Fh, 7Ah, 1Dh, 0E2h, 55h, 0B8h, 0Ch, 91h, 4Eh, 0D3h |
然後
在 .data 裡有被 blacklist 的 字元
1 | data:0000000000005080 off_5080 dq offset aSystem_0 ; DATA XREF: sub_2376+D4↑o |
那 有解密規則跟被 ban 的字元了
我們來看環境吧
1 | RUN mv /flag.txt /flag-$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1).txt |
這段讓 flag 有接上隨機字元 並且有擋 flag 所以我們可以使用 fl* 來解覺問題
並且有 ban cat 我們可以用 tac 來解覺這個問題,
此外 我還有把 / 跟 ban 掉,這時候可以用 ${IFS} 代替空格 ${HOME:0:1} 代替 /
來搓 exploit 吧
1 | from pwn import * |
Flag: THJCC{t4c_t4c_d1d_y0u_r3v3rs3_c4t???}
