📂 动态页面加载

输入页面名称,从 pages 目录加载对应内容。合法页面:help、about、contact

快速测试: help about contact 🐛 攻击: /etc/passwd app.py 源码 主机名
📄 请求: /page?name=../app.py ✅ 加载成功
"""
VulnLab -- Web 安全漏洞实训平台
================================
模块化架构:每个实验模块独立一个文件,位于 modules/ 目录。

增删实验:
  1. 在 modules/ 中增删 .py 文件
  2. 在下方 import + register_blueprint
  3. 重建 Docker

模块编号:
  01 password_leak  -- 密码泄露 (vuln1-4)
  02 sql_injection  -- SQL 注入 (vuln5)
  03 file_upload    -- 文件上传 (vuln6)
  04 idor           -- IDOR 越权
  05 lfi            -- 文件包含 (vuln7)
  06 csrf           -- CSRF    (vuln8)
  07 ssrf           -- SSRF    (vuln9)
  08 cmdi           -- 命令注入 (vuln10)
  09 xxe            -- XXE     (vuln11)
"""
from flask import Flask
import database

# -- 导入实验模块 --
from modules.password_leak import bp as password_leak_bp
from modules.sql_injection import bp as sql_injection_bp
from modules.file_upload   import bp as file_upload_bp
from modules.idor          import bp as idor_bp
from modules.lfi           import bp as lfi_bp
from modules.csrf          import bp as csrf_bp
from modules.ssrf          import bp as ssrf_bp
from modules.cmdi          import bp as cmdi_bp
from modules.xxe           import bp as xxe_bp

# -- 创建 App --
app = Flask(__name__)
app.secret_key = 'dev-key-2025'
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024

# 注册数据库清理钩子
database.init_app(app)

# -- 注册实验模块 --
app.register_blueprint(password_leak_bp)
app.register_blueprint(sql_injection_bp)
app.register_blueprint(file_upload_bp)
app.register_blueprint(idor_bp)
app.register_blueprint(lfi_bp)
app.register_blueprint(csrf_bp)
app.register_blueprint(ssrf_bp)
app.register_blueprint(cmdi_bp)
app.register_blueprint(xxe_bp)

# -- 启动 --
if __name__ == '__main__':
    database.init_dirs()
    database.init_db()
    database.init_idor_db()
    app.run(host='0.0.0.0', port=5000, debug=True)

💡 实验提示

攻击思路:利用 ../ 跳出 pages 目录,访问系统任意文件

POC 01 · 读取系统敏感文件:输入 ../../../../../../etc/passwd 读取 Linux 用户信息
POC 02 · 窃取应用源码:输入 ../app.py 直接获取后端源代码
POC 03 · 探测系统环境:输入 ../../../../../../etc/hostname 获取主机名
⚠️ 漏洞根源:os.path.join("pages", name) 直接拼接用户输入,未过滤 ../ 路径穿越符
← 返回 LFI 菜单 | 进阶实验:Base64 编码绕过 LFI →