Dangerous Flask 题解
0x01 题目信息
这是一个 Flask 投票站,题目提示后端开启了 debug=True。本题的考点是 Flask 调试器开启后导致的源码泄露。
0x02 信息收集
打开首页后可以看到一个党争投票页面。站点只有 / 一个路由,使用 POST 参数 data,参数值是 JSON 字符串:
data={"choice": "kazusa"}
data={"choice": "setsuna"}
除此之外没有发现其他交互点。服务器会对 data 参数调用 json.loads 进行解析,因此可以提交非法 JSON 主动触发异常。
0x03 触发调试器
直接提交一段非法的 data:

json.loads 抛出 JSONDecodeError 后,响应变成 500,页面变成 Werkzeug 的报错调试页:

0x04 获取 flag
调试页面中直接显示了源代码,可以看到 flag 就写在注释里:

因此不需要进一步利用,直接查看源码即可得到 flag。
0x05 踩坑记录:console RCE 失败
通常 debug=True 的经典利用方式是使用调试器自带的 console 进行 RCE,但这道题无法直接使用这一思路:
EVALEX = false。新版 Werkzeug 为调试器增加了 Host 白名单,默认只允许127.0.0.1和.localhost,从题目域名访问时 console 会被关闭。- 尝试伪造
Host: 127.0.0.1时,前端网关会根据域名进行路由,Host 被修改后直接返回 404。 - 即使 console 能够打开,执行命令还需要通过 PIN 校验,而 PIN 的生成依赖机器上的 MAC 地址、machine-id 等信息。
所以这题中 debug=True 的真正利用点,就是调试页面直接泄露源代码。