opencode-api-security-testing 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +1797 -0
- package/core/advanced_recon.py +788 -0
- package/core/agentic_analyzer.py +445 -0
- package/core/analyzers/api_parser.py +210 -0
- package/core/analyzers/response_analyzer.py +212 -0
- package/core/analyzers/sensitive_finder.py +184 -0
- package/core/api_fuzzer.py +422 -0
- package/core/api_interceptor.py +525 -0
- package/core/api_parser.py +955 -0
- package/core/browser_tester.py +479 -0
- package/core/cloud_storage_tester.py +1330 -0
- package/core/collectors/__init__.py +23 -0
- package/core/collectors/api_path_finder.py +300 -0
- package/core/collectors/browser_collect.py +645 -0
- package/core/collectors/browser_collector.py +411 -0
- package/core/collectors/http_client.py +111 -0
- package/core/collectors/js_collector.py +490 -0
- package/core/collectors/js_parser.py +780 -0
- package/core/collectors/url_collector.py +319 -0
- package/core/context_manager.py +682 -0
- package/core/deep_api_tester_v35.py +844 -0
- package/core/deep_api_tester_v55.py +366 -0
- package/core/dynamic_api_analyzer.py +532 -0
- package/core/http_client.py +179 -0
- package/core/models.py +296 -0
- package/core/orchestrator.py +890 -0
- package/core/prerequisite.py +227 -0
- package/core/reasoning_engine.py +1042 -0
- package/core/response_classifier.py +606 -0
- package/core/runner.py +938 -0
- package/core/scan_engine.py +599 -0
- package/core/skill_executor.py +435 -0
- package/core/skill_executor_v2.py +670 -0
- package/core/skill_executor_v3.py +704 -0
- package/core/smart_analyzer.py +687 -0
- package/core/strategy_pool.py +707 -0
- package/core/testers/auth_tester.py +264 -0
- package/core/testers/idor_tester.py +200 -0
- package/core/testers/sqli_tester.py +211 -0
- package/core/testing_loop.py +655 -0
- package/core/utils/base_path_dict.py +255 -0
- package/core/utils/payload_lib.py +167 -0
- package/core/utils/ssrf_detector.py +220 -0
- package/core/verifiers/vuln_verifier.py +536 -0
- package/package.json +17 -13
- package/references/asset-discovery.md +119 -612
- package/references/graphql-guidance.md +65 -641
- package/references/intake.md +84 -0
- package/references/report-template.md +131 -38
- package/references/rest-guidance.md +55 -526
- package/references/severity-model.md +52 -264
- package/references/test-matrix.md +65 -263
- package/references/validation.md +53 -400
- package/scripts/postinstall.js +46 -0
- package/agents/cyber-supervisor.md +0 -55
- package/agents/probing-miner.md +0 -42
- package/agents/resource-specialist.md +0 -31
- package/commands/api-security-testing-scan.md +0 -59
- package/commands/api-security-testing-test.md +0 -49
- package/commands/api-security-testing.md +0 -72
- package/tsconfig.json +0 -17
package/SKILL.md
ADDED
|
@@ -0,0 +1,1797 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: api-security-testing
|
|
3
|
+
description: 针对授权目标进行结构化的 REST/GraphQL API 安全评估。当用户提到安全测试、漏洞检测、渗透测试或需要生成安全报告时自动触发。
|
|
4
|
+
trigger:
|
|
5
|
+
phrases:
|
|
6
|
+
- "安全测试"
|
|
7
|
+
- "安全审计"
|
|
8
|
+
- "渗透测试"
|
|
9
|
+
- "漏洞检测"
|
|
10
|
+
- "安全评估"
|
|
11
|
+
- "api 安全"
|
|
12
|
+
- "接口安全"
|
|
13
|
+
- "帮我检测漏洞"
|
|
14
|
+
- "检查安全问题"
|
|
15
|
+
- "安全报告"
|
|
16
|
+
- "全流程测试"
|
|
17
|
+
- "完整测试"
|
|
18
|
+
- "云存储安全"
|
|
19
|
+
patterns:
|
|
20
|
+
- "(?:帮我)?(?:进行?|做)(?:api|接口|安全|云存储|oss)?(?:测试|检测|扫描)"
|
|
21
|
+
- "(?:帮我)?(?:检查?|发现?)(?:api|安全|oss|云存储|bucket)?(?:漏洞|问题)"
|
|
22
|
+
auto_trigger: true
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 前置检查与依赖处理
|
|
28
|
+
|
|
29
|
+
### 当依赖不可用时
|
|
30
|
+
|
|
31
|
+
当你需要进行安全测试,但发现某些工具不可用时:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
遇到Playwright不可用:
|
|
35
|
+
1. 尝试 pip install playwright && playwright install chromium
|
|
36
|
+
2. 尝试 playwright install-deps chromium # 安装系统依赖(容易被忽略)
|
|
37
|
+
3. 【增强】自动检测系统依赖缺失:
|
|
38
|
+
```python
|
|
39
|
+
# 检查 Playwright 系统依赖
|
|
40
|
+
try:
|
|
41
|
+
from playwright.sync_api import sync_playwright
|
|
42
|
+
with sync_playwright() as p:
|
|
43
|
+
browser = p.chromium.launch(headless=True)
|
|
44
|
+
browser.close()
|
|
45
|
+
except Exception as e:
|
|
46
|
+
if "libglib" in str(e) or "Shared object" in str(e):
|
|
47
|
+
print("检测到系统依赖缺失,自动安装...")
|
|
48
|
+
subprocess.run(["playwright", "install-deps", "chromium"], check=True)
|
|
49
|
+
```
|
|
50
|
+
4. 尝试使用MCP工具: headless_browser
|
|
51
|
+
5. 尝试其他方案: selenium, pyppeteer
|
|
52
|
+
6. 最后才使用 requests 静态解析
|
|
53
|
+
|
|
54
|
+
常见依赖缺失及解决:
|
|
55
|
+
| 缺失库 | 解决方案 |
|
|
56
|
+
|--------|----------|
|
|
57
|
+
| libglib-2.0.so | playwright install-deps chromium |
|
|
58
|
+
| libnss3 | 同上 |
|
|
59
|
+
| libatk | 同上 |
|
|
60
|
+
| libpango | 同上 |
|
|
61
|
+
|
|
62
|
+
遇到requests不可用:
|
|
63
|
+
1. 尝试 pip install requests
|
|
64
|
+
2. 尝试curl
|
|
65
|
+
3. 报告环境问题
|
|
66
|
+
|
|
67
|
+
注意:不要轻易回退!优先解决依赖问题。
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 发现即测原则
|
|
71
|
+
|
|
72
|
+
**不要等全部扫描完再测试,发现接口立即测试。**
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
错误做法:
|
|
76
|
+
1. 先扫描所有端点
|
|
77
|
+
2. 再逐一测试漏洞
|
|
78
|
+
|
|
79
|
+
正确做法:
|
|
80
|
+
1. 发现一个接口 → 立即测试相关漏洞
|
|
81
|
+
2. 发现敏感接口 → 立即深入测试
|
|
82
|
+
3. 发现认证接口 → 立即测试绕过
|
|
83
|
+
|
|
84
|
+
发现Swagger → 立即访问获取更多API
|
|
85
|
+
发现Actuator → 立即测试敏感端点
|
|
86
|
+
发现登录接口 → 立即测试注入/爆破
|
|
87
|
+
发现查询接口 → 立即测试IDOR
|
|
88
|
+
发现文件上传接口 → 立即测试上传绕过
|
|
89
|
+
|
|
90
|
+
【新增】API 类型对应的测试重点:
|
|
91
|
+
|
|
92
|
+
| API 类型 | 发现后立即测试 |
|
|
93
|
+
|----------|---------------|
|
|
94
|
+
| 认证类 (login, auth) | SQL注入、暴力破解、用户枚举 |
|
|
95
|
+
| 查询类 (list, get, search) | IDOR,信息泄露、注入 |
|
|
96
|
+
| 操作类 (add, modify, delete) | 越权、批量操作、业务逻辑 |
|
|
97
|
+
| 文件类 (upload, download) | 上传绕过、恶意文件、路径遍历 |
|
|
98
|
+
| 支付类 (pay, refund, order) | 金额篡改、支付绕过、退款欺诈 |
|
|
99
|
+
|
|
100
|
+
### 发现即测的例外
|
|
101
|
+
|
|
102
|
+
**以下情况需要先验证,再深入:**
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
1. 发现返回200但内容异常
|
|
106
|
+
→ 不要直接报告漏洞
|
|
107
|
+
→ 先验证:是真实数据还是WAF拦截页?
|
|
108
|
+
|
|
109
|
+
2. 发现可疑的响应差异
|
|
110
|
+
→ 不要直接报告漏洞
|
|
111
|
+
→ 先多次请求确认差异是否稳定
|
|
112
|
+
|
|
113
|
+
3. 发现疑似敏感信息
|
|
114
|
+
→ 不要直接报告漏洞
|
|
115
|
+
→ 先确认:这是业务数据还是测试数据?
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 测试优先级
|
|
119
|
+
|
|
120
|
+
当你发现多个问题时,按这个顺序:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
1. 立即可利用的漏洞(如SQL注入、认证绕过)
|
|
124
|
+
2. 信息泄露(如Swagger、Actuator暴露)
|
|
125
|
+
3. 业务逻辑漏洞(如越权、支付篡改)
|
|
126
|
+
4. 枚举类漏洞(如用户枚举)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## 核心检测思维
|
|
132
|
+
|
|
133
|
+
### 1. 遇到"查询类"接口时这么想
|
|
134
|
+
|
|
135
|
+
当你发现一个接口用于查询数据时:
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
思考:这个接口查的是什么数据?需要认证吗?能查到别人的数据吗?
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**推理步骤:**
|
|
142
|
+
1. 这个接口查询需要什么参数?(userId、phone、orderNo...)
|
|
143
|
+
2. 不带参数能查到数据吗?
|
|
144
|
+
3. 带别人的ID能查到数据吗?(IDOR)
|
|
145
|
+
4. 响应中有没有敏感字段?(password、token、余额...)
|
|
146
|
+
|
|
147
|
+
**示例:**
|
|
148
|
+
```
|
|
149
|
+
你发现:GET /api/user/info?userId=123
|
|
150
|
+
思考:
|
|
151
|
+
- 需要认证吗?→ 测试不带token
|
|
152
|
+
- 能查其他用户吗?→ 测试userId=124
|
|
153
|
+
- 响应有敏感字段吗?→ 检查password、token等
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### 2. 遇到"认证类"接口时这么想
|
|
157
|
+
|
|
158
|
+
当你发现登录、注册接口时:
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
思考:认证机制安全吗?能绕过吗?能枚举用户吗?
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**推理步骤:**
|
|
165
|
+
1. 不带认证信息能访问吗?
|
|
166
|
+
2. 伪造token能通过吗?(JWTalg:none)
|
|
167
|
+
3. 用户不存在时的响应有区别吗?(用户枚举)
|
|
168
|
+
4. 有短信验证码吗?能轰炸吗?
|
|
169
|
+
|
|
170
|
+
**示例:**
|
|
171
|
+
```
|
|
172
|
+
你发现:POST /api/login
|
|
173
|
+
思考:
|
|
174
|
+
- SQL注入?→ 测试 username=' OR '1'='1
|
|
175
|
+
- 暴力破解?→ 多次尝试错误密码
|
|
176
|
+
- 用户枚举?→ 测试不存在的用户
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### 3. 遇到"资金/订单类"接口时这么想
|
|
180
|
+
|
|
181
|
+
当你发现支付、退款、订单接口时:
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
思考:钱能转走吗?订单能篡改吗?能刷单吗?
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**推理步骤:**
|
|
188
|
+
1. 订单归属校验了吗?(用A的token能操作B的订单吗?)
|
|
189
|
+
2. 金额能篡改吗?(改成0.01)
|
|
190
|
+
3. 退款接口需要什么权限?能绕过吗?
|
|
191
|
+
|
|
192
|
+
**示例:**
|
|
193
|
+
```
|
|
194
|
+
你发现:POST /api/pay/refund
|
|
195
|
+
思考:
|
|
196
|
+
- 需要认证吗?→ 不带token测试
|
|
197
|
+
- 需要自己的订单吗?→ 尝试他人的orderNo
|
|
198
|
+
- 金额能改成0吗?→ amount=0测试
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### 4. 遇到"用户信息"接口时这么想
|
|
202
|
+
|
|
203
|
+
当你发现返回用户资料的接口时:
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
思考:别人的资料能拿到吗?密码暴露了吗?能修改吗?
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**推理步骤:**
|
|
210
|
+
1. 不带token能拿到吗?
|
|
211
|
+
2. 响应里有password吗?
|
|
212
|
+
3. 能通过phone/email找到userId吗?
|
|
213
|
+
4. 修改接口有校验吗?能改别人的吗?
|
|
214
|
+
|
|
215
|
+
**示例:**
|
|
216
|
+
```
|
|
217
|
+
你发现:GET /api/user/info?phone=138xxx
|
|
218
|
+
思考:
|
|
219
|
+
- 返回userId了吗?→ 记录
|
|
220
|
+
- 返回password了吗?→ 漏洞
|
|
221
|
+
- userId=124能查到吗?→ IDOR测试
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## 敏感信息识别
|
|
227
|
+
|
|
228
|
+
### 必须识别这些敏感字段
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
password → 不应返回前端
|
|
232
|
+
token → 可能存在泄露
|
|
233
|
+
secretKey → 不应暴露
|
|
234
|
+
apiKey → 不应暴露
|
|
235
|
+
balance → 可能存在越权
|
|
236
|
+
orderNo → 可能被篡改
|
|
237
|
+
userId → 可用于越权测试
|
|
238
|
+
phone → 可用于用户枚举
|
|
239
|
+
email → 可用于钓鱼
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### 响应类型分类(重要)
|
|
243
|
+
|
|
244
|
+
**不同响应类型代表不同含义:**
|
|
245
|
+
|
|
246
|
+
| 响应类型 | 特征 | 含义 |
|
|
247
|
+
|----------|------|------|
|
|
248
|
+
| JSON对象 | `{"code":200,"data":{...}}` | 真实API响应 |
|
|
249
|
+
| JSON数组 | `[{"id":1,...},...]` | 真实数据列表 |
|
|
250
|
+
| HTML页面 | `<!DOCTYPE html>...` | SPA路由/WAF/错误页 |
|
|
251
|
+
| 空响应 | 长度<50字节 | 可能是错误/空数据 |
|
|
252
|
+
| 重定向 | HTTP 301/302 | 需要认证/跳转 |
|
|
253
|
+
|
|
254
|
+
**判断逻辑:**
|
|
255
|
+
```
|
|
256
|
+
1. 检查Content-Type: 是application/json还是text/html?
|
|
257
|
+
2. 检查响应长度: <100字节通常是错误响应
|
|
258
|
+
3. 检查响应内容: 是否包含< DOCTYPE html?
|
|
259
|
+
4. 对比正常请求: 相同接口的响应应该相似
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### 响应分析思维
|
|
263
|
+
|
|
264
|
+
当你看到响应时:
|
|
265
|
+
```
|
|
266
|
+
1. 这个响应正常吗? → 检查状态码
|
|
267
|
+
2. 有敏感字段吗? → 搜索password/token/secret
|
|
268
|
+
3. 有ID类字段吗? → 尝试遍历
|
|
269
|
+
4. 有手机号吗? → 尝试用户枚举
|
|
270
|
+
5. 有订单号吗? → 尝试越权操作
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## 漏洞验证闭环
|
|
276
|
+
|
|
277
|
+
### 三步验证流程
|
|
278
|
+
|
|
279
|
+
```
|
|
280
|
+
第一步:发现 (Discover)
|
|
281
|
+
- 发现可疑的响应差异
|
|
282
|
+
- 发现异常的状态码
|
|
283
|
+
- 发现敏感信息暴露
|
|
284
|
+
|
|
285
|
+
第二步:分析 (Analyze)
|
|
286
|
+
- 多次请求确认差异稳定
|
|
287
|
+
- 对比正常请求和异常请求
|
|
288
|
+
- 检查是否是WAF/路由/认证导致
|
|
289
|
+
|
|
290
|
+
第三步:验证 (Verify)
|
|
291
|
+
- 确认为漏洞 → 收集证据 → 报告
|
|
292
|
+
- 排除为误报 → 记录原因 → 继续扫描
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### 验证检查清单(10个维度)
|
|
296
|
+
|
|
297
|
+
```
|
|
298
|
+
□ 维度1: 响应类型 - 是JSON还是HTML?(HTML可能是WAF)
|
|
299
|
+
□ 维度2: 状态码 - 是否合理?
|
|
300
|
+
□ 维度3: 响应长度 - 是否过短?(可能是拦截)
|
|
301
|
+
□ 维度4: WAF拦截 - 是否为WAF/安全设备?
|
|
302
|
+
□ 维度5: 敏感信息 - 是否包含password/token/secret?
|
|
303
|
+
□ 维度6: 一致性 - 多次请求响应是否一致?
|
|
304
|
+
□ 维度7: SQL注入 - 是否包含SQL错误特征?
|
|
305
|
+
□ 维度8: IDOR - 是否返回用户/业务数据?
|
|
306
|
+
□ 维度9: 认证绕过 - 是否返回token/session?
|
|
307
|
+
□ 维度10: 信息泄露 - 是否泄露非公开信息?
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### 常见误报识别
|
|
311
|
+
|
|
312
|
+
```
|
|
313
|
+
这些不是漏洞(识别为误报):
|
|
314
|
+
1. HTTP 200 返回 HTML 页面
|
|
315
|
+
→ 可能是WAF拦截页/SPA路由/默认错误页
|
|
316
|
+
→ 验证:是否是JSON格式的业务数据?
|
|
317
|
+
|
|
318
|
+
2. 响应长度完全相同但返回"登录失效"
|
|
319
|
+
→ 说明后端有正确的认证检查
|
|
320
|
+
→ 不是漏洞,是安全防护有效
|
|
321
|
+
|
|
322
|
+
3. 所有ID查询返回相同响应
|
|
323
|
+
→ 可能是统一错误处理
|
|
324
|
+
→ 验证:是否真的返回了不同的业务数据?
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## 漏洞链构造思维
|
|
330
|
+
|
|
331
|
+
### 发现用户枚举后的推理
|
|
332
|
+
|
|
333
|
+
当你发现可以枚举用户时:
|
|
334
|
+
|
|
335
|
+
```
|
|
336
|
+
你发现的:GET /api/user/check?phone=138xxx 返回 userId
|
|
337
|
+
|
|
338
|
+
思考能做什么:
|
|
339
|
+
1. 收集更多userId → 批量探测手机号
|
|
340
|
+
2. 用userId查更多信息 → GET /api/user/info?userId=xxx
|
|
341
|
+
3. 尝试修改他人资料 → POST /api/user/update
|
|
342
|
+
4. 查看他人订单 → GET /api/order/list?userId=xxx
|
|
343
|
+
5. 尝试退款 → POST /api/refund (用他人的orderNo)
|
|
344
|
+
|
|
345
|
+
利用链:
|
|
346
|
+
用户枚举 → 获取userId → 查订单 → 退款
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### 发现token泄露后的推理
|
|
350
|
+
|
|
351
|
+
当你发现响应中包含token时:
|
|
352
|
+
|
|
353
|
+
```
|
|
354
|
+
你发现的:{"token": "xxx", "userId": 123}
|
|
355
|
+
|
|
356
|
+
思考能做什么:
|
|
357
|
+
1. 这个token有效吗? → 用这个token访问其他接口
|
|
358
|
+
2. 能用这个token访问admin接口吗? → GET /api/admin/xxx
|
|
359
|
+
3. token能用于其他用户吗? → 改userId重放
|
|
360
|
+
|
|
361
|
+
利用链:
|
|
362
|
+
token泄露 → 用token访问敏感接口 → 越权操作
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### 发现订单接口后的推理
|
|
366
|
+
|
|
367
|
+
当你发现订单相关接口时:
|
|
368
|
+
|
|
369
|
+
```
|
|
370
|
+
你发现的:GET /api/order/list
|
|
371
|
+
|
|
372
|
+
思考能做什么:
|
|
373
|
+
1. 不带认证能访问吗? → 测试
|
|
374
|
+
2. 能带userId参数吗? → 查他人订单
|
|
375
|
+
3. 能找到orderNo吗? → 尝试 /api/order/detail?orderNo=xxx
|
|
376
|
+
4. 有退款接口吗? → 尝试 /api/refund?orderNo=xxx
|
|
377
|
+
|
|
378
|
+
利用链:
|
|
379
|
+
用户枚举 → 获取userId → 查订单 → 获取orderNo → 退款
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### 【新增】利用链推理提示词参考
|
|
383
|
+
|
|
384
|
+
当发现多个独立漏洞时,可以使用以下提示词进行利用链推理:
|
|
385
|
+
|
|
386
|
+
```
|
|
387
|
+
## 利用链推理提示词
|
|
388
|
+
|
|
389
|
+
当发现多个漏洞时,按以下模板进行利用链分析:
|
|
390
|
+
|
|
391
|
+
### 模板1:认证类漏洞利用链
|
|
392
|
+
```
|
|
393
|
+
发现的漏洞:
|
|
394
|
+
- 登录接口无验证码
|
|
395
|
+
- 暴力破解可获取有效账号
|
|
396
|
+
|
|
397
|
+
利用链推理:
|
|
398
|
+
1. 使用暴力破解获取有效账号 → 记录账号密码
|
|
399
|
+
2. 使用有效账号登录 → 获取 JWT Token
|
|
400
|
+
3. 使用 Token 访问敏感接口 → 测试越权操作
|
|
401
|
+
4. 越权访问获取更多数据 → 扩大攻击面
|
|
402
|
+
|
|
403
|
+
验证步骤:
|
|
404
|
+
- 使用获取的 Token 请求 /api/admin/user/list
|
|
405
|
+
- 如果返回用户数据,说明 Token 有效且可利用
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### 模板2:用户枚举 + IDOR 利用链
|
|
409
|
+
```
|
|
410
|
+
发现的漏洞:
|
|
411
|
+
- 用户存在/不存在响应不同(用户枚举)
|
|
412
|
+
- 查询接口存在 IDOR
|
|
413
|
+
|
|
414
|
+
利用链推理:
|
|
415
|
+
1. 用户枚举获取 userId 列表
|
|
416
|
+
2. 使用 userId 遍历查询接口
|
|
417
|
+
3. 如果能查到他人数据,说明存在 IDOR
|
|
418
|
+
|
|
419
|
+
验证步骤:
|
|
420
|
+
- 使用不同 userId 请求 /api/user/profile?userId=X
|
|
421
|
+
- 对比返回数据是否属于不同用户
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### 模板3:敏感信息泄露 + 认证绕过
|
|
425
|
+
```
|
|
426
|
+
发现的漏洞:
|
|
427
|
+
- 某接口返回敏感信息(如 password)
|
|
428
|
+
- 另一接口存在认证绕过
|
|
429
|
+
|
|
430
|
+
利用链推理:
|
|
431
|
+
1. 认证绕过获取初始访问
|
|
432
|
+
2. 利用敏感信息泄露获取更多凭证
|
|
433
|
+
3. 组合利用扩大攻击面
|
|
434
|
+
|
|
435
|
+
验证步骤:
|
|
436
|
+
- 绕过认证访问 /api/info 获取数据
|
|
437
|
+
- 检查响应中是否包含可利用的凭证
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### 通用利用链验证格式
|
|
441
|
+
```
|
|
442
|
+
漏洞利用链:
|
|
443
|
+
1. [漏洞A] → [漏洞B] → [漏洞C]
|
|
444
|
+
- 漏洞A: 具体描述
|
|
445
|
+
- 漏洞B: 基于A的结果能做什么
|
|
446
|
+
- 漏洞C: 最终能获取什么
|
|
447
|
+
|
|
448
|
+
2. 验证记录:
|
|
449
|
+
- Step 1: 执行的操作
|
|
450
|
+
- Step 2: 返回的结果
|
|
451
|
+
- Step 3: 是否成功利用
|
|
452
|
+
```
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
## HTTP方法与测试策略
|
|
458
|
+
|
|
459
|
+
### 不同方法的测试重点
|
|
460
|
+
|
|
461
|
+
| 方法 | 测试重点 |
|
|
462
|
+
|------|----------|
|
|
463
|
+
| GET | 参数遍历、IDOR,信息泄露 |
|
|
464
|
+
| POST | 认证绕过、业务逻辑、注入 |
|
|
465
|
+
| PUT | 资源篡改、越权修改 |
|
|
466
|
+
| DELETE | 资源删除、越权删除 |
|
|
467
|
+
| PATCH | 部分更新、字段覆盖 |
|
|
468
|
+
|
|
469
|
+
### 参数测试思维
|
|
470
|
+
|
|
471
|
+
当你发现一个接口有参数时:
|
|
472
|
+
|
|
473
|
+
```
|
|
474
|
+
接口:GET /api/xxx?param=value
|
|
475
|
+
|
|
476
|
+
测试顺序:
|
|
477
|
+
1. param=空值
|
|
478
|
+
2. param=正常值
|
|
479
|
+
3. param=特殊字符 (' " < >)
|
|
480
|
+
4. param=SQL注入 (1' OR '1'='1)
|
|
481
|
+
5. param=XSS (<script>alert(1)</script>)
|
|
482
|
+
6. param=路径遍历 (../../../etc/passwd)
|
|
483
|
+
7. param=其他用户的值 (IDOR)
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
---
|
|
487
|
+
|
|
488
|
+
## 认证上下文理解
|
|
489
|
+
|
|
490
|
+
### 发现登录接口后
|
|
491
|
+
|
|
492
|
+
```
|
|
493
|
+
你发现的:POST /api/login {"username":"xxx","password":"xxx"}
|
|
494
|
+
|
|
495
|
+
思考:
|
|
496
|
+
1. 返回token吗? → 记录token
|
|
497
|
+
2. 返回userId吗? → 记录userId
|
|
498
|
+
3. 响应有什么区别? → 用户枚举
|
|
499
|
+
4. 有验证码吗? → 暴力破解难度
|
|
500
|
+
|
|
501
|
+
接下来用这个token:
|
|
502
|
+
- 访问 GET /api/user/info
|
|
503
|
+
- 访问 GET /api/order/list
|
|
504
|
+
- 尝试 GET /api/admin/xxx (测试权限)
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### 发现token但不知道用法时
|
|
508
|
+
|
|
509
|
+
```
|
|
510
|
+
你发现的:token=eyJhbGciOiJIUzI1NiJ9...
|
|
511
|
+
|
|
512
|
+
思考:
|
|
513
|
+
1. JWT吗? → 解码看payload
|
|
514
|
+
2. 放在哪? → Authorization: Bearer token
|
|
515
|
+
3. 哪个接口用? → 尝试访问需要认证的接口
|
|
516
|
+
4. userId是什么? → 从token解码获取
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
---
|
|
520
|
+
|
|
521
|
+
## 常见漏洞模式识别
|
|
522
|
+
|
|
523
|
+
### 用户相关漏洞模式
|
|
524
|
+
|
|
525
|
+
```
|
|
526
|
+
1. 用户信息泄露
|
|
527
|
+
特征:响应包含password、token
|
|
528
|
+
测试:不带认证访问
|
|
529
|
+
|
|
530
|
+
2. 用户枚举
|
|
531
|
+
特征:用户存在/不存在响应不同
|
|
532
|
+
测试:探测不存在的手机号/邮箱
|
|
533
|
+
|
|
534
|
+
3. 密码重置漏洞
|
|
535
|
+
特征:可通过phone/email重置
|
|
536
|
+
测试:尝试修改他人密码
|
|
537
|
+
|
|
538
|
+
4. 越权访问
|
|
539
|
+
特征:通过参数切换用户
|
|
540
|
+
测试:修改userId/phone等参数
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
### 订单相关漏洞模式
|
|
544
|
+
|
|
545
|
+
```
|
|
546
|
+
1. 订单遍历
|
|
547
|
+
特征:参数化查询订单
|
|
548
|
+
测试:修改userId查他人订单
|
|
549
|
+
|
|
550
|
+
2. 订单篡改
|
|
551
|
+
特征:订单金额可修改
|
|
552
|
+
测试:尝试amount=0.01
|
|
553
|
+
|
|
554
|
+
3. 虚假订单
|
|
555
|
+
特征:可创建任意订单
|
|
556
|
+
测试:构造恶意订单数据
|
|
557
|
+
|
|
558
|
+
4. 退款绕过
|
|
559
|
+
特征:退款接口无校验
|
|
560
|
+
测试:使用他人orderNo退款
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### 认证相关漏洞模式
|
|
564
|
+
|
|
565
|
+
```
|
|
566
|
+
1. JWT伪造
|
|
567
|
+
特征:alg:None 或不验签
|
|
568
|
+
测试:修改payload重放
|
|
569
|
+
|
|
570
|
+
2. 暴力破解
|
|
571
|
+
特征:无验证码、无限流
|
|
572
|
+
测试:多次尝试密码
|
|
573
|
+
|
|
574
|
+
3. 会话固定
|
|
575
|
+
特征:登录后session不变
|
|
576
|
+
测试:登录前后cookie对比
|
|
577
|
+
|
|
578
|
+
4. 登出后令牌仍有效
|
|
579
|
+
特征:token注销机制缺失
|
|
580
|
+
测试:登出后重放token
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
---
|
|
584
|
+
|
|
585
|
+
## 特殊情况处理
|
|
586
|
+
|
|
587
|
+
### 遇到WAF/安全设备时
|
|
588
|
+
|
|
589
|
+
```
|
|
590
|
+
识别特征:
|
|
591
|
+
- 所有请求返回相似的HTML页面
|
|
592
|
+
- 响应包含"拦截"、"安全"、"访问受限"等关键词
|
|
593
|
+
- 响应内容与实际API无关
|
|
594
|
+
|
|
595
|
+
处理方法:
|
|
596
|
+
1. 识别为WAF拦截,不是漏洞
|
|
597
|
+
2. 记录"存在WAF防护"作为安全能力
|
|
598
|
+
3. 可以尝试降低请求频率绕过
|
|
599
|
+
|
|
600
|
+
判断逻辑:
|
|
601
|
+
- 请求1: 返回业务JSON = 正常
|
|
602
|
+
- 请求2: 返回HTML拦截页 = WAF
|
|
603
|
+
- 请求3: 返回业务JSON = 恢复
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
### 遇到SPA应用时
|
|
607
|
+
|
|
608
|
+
```
|
|
609
|
+
识别特征:
|
|
610
|
+
- /api/* 路径返回HTML页面
|
|
611
|
+
- 响应内容是前端框架代码
|
|
612
|
+
- 不是真实的API端点
|
|
613
|
+
|
|
614
|
+
处理方法:
|
|
615
|
+
1. 通过JS源码分析获取真实API配置
|
|
616
|
+
2. 使用无头浏览器触发动态API请求
|
|
617
|
+
3. 不要对SPA路由的/api/*路径直接测试
|
|
618
|
+
|
|
619
|
+
判断逻辑:
|
|
620
|
+
- GET /api/user/info 返回HTML = SPA前端路由
|
|
621
|
+
- GET /api/user/info 返回JSON = 真实API
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
### SPA应用完整采集流程(必须按顺序执行)
|
|
625
|
+
|
|
626
|
+
**阶段1:基础探测**
|
|
627
|
+
```
|
|
628
|
+
1. HTTP探测目标可访问性
|
|
629
|
+
curl -I http://target.com
|
|
630
|
+
|
|
631
|
+
2. 技术栈识别
|
|
632
|
+
- 检查响应头Server字段
|
|
633
|
+
- 检查HTML中是否包含Vue/React/Angular关键词
|
|
634
|
+
- 检查是否包含webpack chunk引用
|
|
635
|
+
|
|
636
|
+
3. 判断是否是SPA应用
|
|
637
|
+
- /api/* 返回HTML → SPA
|
|
638
|
+
- HTML包含JS chunk路径 → Vue/React应用
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
**阶段2:JS采集(必须使用无头浏览器)**
|
|
642
|
+
```
|
|
643
|
+
1. 使用Playwright访问目标
|
|
644
|
+
from playwright.sync_api import sync_playwright
|
|
645
|
+
|
|
646
|
+
with sync_playwright() as p:
|
|
647
|
+
browser = p.chromium.launch(headless=True)
|
|
648
|
+
page = browser.new_page()
|
|
649
|
+
page.goto(url, wait_until="networkidle")
|
|
650
|
+
page.wait_for_timeout(5000) # 等待JS完全执行
|
|
651
|
+
|
|
652
|
+
2. 从DOM提取所有JS文件
|
|
653
|
+
js_files = re.findall(r'<script[^>]+src=["\']([^"\']+)["\']', page.content())
|
|
654
|
+
|
|
655
|
+
3. 【新增】拦截所有请求和响应
|
|
656
|
+
- page.on('request') → 捕获所有API请求
|
|
657
|
+
- page.on('response') → 捕获所有响应(提取IP、域名)
|
|
658
|
+
|
|
659
|
+
4. 【新增】采集敏感信息
|
|
660
|
+
- localStorage: 检查token、key等敏感数据
|
|
661
|
+
- 响应头: 提取server版本、IP、域名信息
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
**阶段3:JS深度分析(AST+正则双模式提取)**
|
|
665
|
+
```
|
|
666
|
+
【关键】必须使用AST+正则双模式进行深度分析
|
|
667
|
+
|
|
668
|
+
**【增强】递归分析所有 chunk 文件**
|
|
669
|
+
|
|
670
|
+
之前只分析了主 JS 文件,实际上 webpack 打包的应用会将代码分散到多个 chunk 文件中。
|
|
671
|
+
|
|
672
|
+
实现步骤:
|
|
673
|
+
|
|
674
|
+
```python
|
|
675
|
+
# 1. 从 HTML 中提取所有 JS 引用
|
|
676
|
+
js_files = re.findall(r'<script[^>]+src=["'"]?([^"'">]+)["'"]?', html)
|
|
677
|
+
|
|
678
|
+
# 2. 递归下载并分析 JS
|
|
679
|
+
visited_js = set()
|
|
680
|
+
to_visit = list(js_files)
|
|
681
|
+
|
|
682
|
+
while to_visit:
|
|
683
|
+
js_url = to_visit.pop(0)
|
|
684
|
+
if js_url in visited_js:
|
|
685
|
+
continue
|
|
686
|
+
visited_js.add(js_url)
|
|
687
|
+
|
|
688
|
+
content = download_js(js_url)
|
|
689
|
+
|
|
690
|
+
# 查找动态导入的 JS (import())
|
|
691
|
+
dynamic_imports = re.findall(r'import\(["']([^"'"]+\.js)["']\)', content)
|
|
692
|
+
for di in dynamic_imports:
|
|
693
|
+
if di not in visited_js:
|
|
694
|
+
to_visit.append(di)
|
|
695
|
+
|
|
696
|
+
# 查找 webpack chunk 引用
|
|
697
|
+
chunk_refs = re.findall(r'"chunk-([a-z0-9]+)"', content)
|
|
698
|
+
for chunk_id in chunk_refs:
|
|
699
|
+
# 尝试构造 chunk URL
|
|
700
|
+
chunk_url = f"/static/js/chunk-{chunk_id}.js"
|
|
701
|
+
if chunk_url not in visited_js:
|
|
702
|
+
to_visit.append(chunk_url)
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
**【增强】按大小优先级分析**
|
|
706
|
+
|
|
707
|
+
重要发现:大 chunk 文件通常包含更多业务逻辑
|
|
708
|
+
|
|
709
|
+
```python
|
|
710
|
+
# 分析策略
|
|
711
|
+
js_files_with_size = []
|
|
712
|
+
for js_url in all_js_files:
|
|
713
|
+
content = download_js(js_url)
|
|
714
|
+
size = len(content)
|
|
715
|
+
js_files_with_size.append((size, js_url))
|
|
716
|
+
|
|
717
|
+
# 按大小排序,优先分析大文件
|
|
718
|
+
js_files_with_size.sort(reverse=True)
|
|
719
|
+
|
|
720
|
+
# 优先分析 >50KB 的 chunk
|
|
721
|
+
for size, js_url in js_files_with_size:
|
|
722
|
+
if size > 50000:
|
|
723
|
+
analyze_js(js_url, content)
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
测试结果对比:
|
|
727
|
+
| 之前(仅app.js) | 之后(所有chunk) |
|
|
728
|
+
|------------------|-------------------|
|
|
729
|
+
| 发现 5 个 API | 发现 65+ 个 API |
|
|
730
|
+
| 缺失大量业务接口 | 覆盖完整业务模块 |
|
|
731
|
+
|
|
732
|
+
1. 提取baseURL配置(最优先!)
|
|
733
|
+
patterns:
|
|
734
|
+
- r'baseURL\s*[:=]\s*["\']([^"\']+)["\']'
|
|
735
|
+
- r'axios\.create\s*\(\s*\{([^}]+)\}'
|
|
736
|
+
|
|
737
|
+
重要发现:
|
|
738
|
+
- baseURL:"" 为空 → 使用相对路径 + nginx代理
|
|
739
|
+
- baseURL:"https://api.xxx.com" → 使用配置的域名前缀
|
|
740
|
+
- baseURL不存在 → 使用同源请求
|
|
741
|
+
|
|
742
|
+
2. AST+正则双模式提取API端点
|
|
743
|
+
|
|
744
|
+
【正则模式】(快速提取):
|
|
745
|
+
patterns:
|
|
746
|
+
- r'["\'](/(?:user|auth|admin|login|logout|api|v\d|frame)[^"\']*)["\']'
|
|
747
|
+
- r'axios\.[a-z]+\(["\']([^"\']+)["\']'
|
|
748
|
+
- r'fetch\(["\']([^"\']+)["\']'
|
|
749
|
+
- r'\.get\(["\']([^"\']+)["\']'
|
|
750
|
+
- r'\.post\(["\']([^"\']+)["\']'
|
|
751
|
+
|
|
752
|
+
【AST模式】(深度提取):
|
|
753
|
+
- 使用esprima.parse()解析JS AST
|
|
754
|
+
- 提取所有字符串字面量
|
|
755
|
+
- 从字符串字面量中筛选API路径
|
|
756
|
+
|
|
757
|
+
【重要】发现API后深入分析来源JS:
|
|
758
|
+
→ 记录API所在的JS文件名
|
|
759
|
+
→ 深度分析该JS文件(用curl下载):
|
|
760
|
+
- 获取完整JS内容(可能有混淆,需多次提取)
|
|
761
|
+
- 使用AST+正则双模式提取所有API路径
|
|
762
|
+
- 提取敏感信息(API密钥、硬编码凭证等)
|
|
763
|
+
- 提取URL模板(如 /user/${userId}/info)
|
|
764
|
+
|
|
765
|
+
3. 【新增】敏感信息提取
|
|
766
|
+
从JS/响应中提取:
|
|
767
|
+
- IP地址: r'\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b'
|
|
768
|
+
- 外部域名: 从URL中提取netloc
|
|
769
|
+
- 凭证信息:
|
|
770
|
+
* api_key, secret_key: r'(?:api[_-]?key|secret[_-]?key)\s*[:=]\s*["\']([^"\']+)["\']'
|
|
771
|
+
* token: r'(?:access[_-]?token|Bearer)\s+([a-zA-Z0-9\-_\.]+)'
|
|
772
|
+
* password: r'password\s*[:=]\s*["\']([^"\']+)["\']'
|
|
773
|
+
|
|
774
|
+
4. 提取环境变量配置
|
|
775
|
+
patterns:
|
|
776
|
+
- r'VUE_APP_\w+'
|
|
777
|
+
- r'process\.env\.(\w+)'
|
|
778
|
+
|
|
779
|
+
5. 提取URL模板字符串
|
|
780
|
+
patterns:
|
|
781
|
+
- r'`[^`]*(?:api|user|auth|admin)[^`]*`'
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
**阶段3:JS深度分析(AST+正则双模式提取)**
|
|
785
|
+
```
|
|
786
|
+
【关键】必须使用AST+正则双模式进行深度分析
|
|
787
|
+
|
|
788
|
+
1. 提取baseURL配置(最优先!)
|
|
789
|
+
patterns:
|
|
790
|
+
- r'baseURL\s*[:=]\s*["\']([^"\']+)["\']'
|
|
791
|
+
- r'axios\.create\s*\(\s*\{([^}]+)\}'
|
|
792
|
+
|
|
793
|
+
重要发现:
|
|
794
|
+
- baseURL:"" 为空 → 使用相对路径 + nginx代理
|
|
795
|
+
- baseURL:"https://api.xxx.com" → 使用配置的域名前缀
|
|
796
|
+
- baseURL不存在 → 使用同源请求
|
|
797
|
+
|
|
798
|
+
2. AST+正则双模式提取API端点
|
|
799
|
+
|
|
800
|
+
正则模式(快速提取):
|
|
801
|
+
patterns:
|
|
802
|
+
- r'["\'](/(?:user|auth|admin|login|logout|api|v\d|frame)[^"\']*)["\']'
|
|
803
|
+
- r'axios\.[a-z]+\(["\']([^"\']+)["\']'
|
|
804
|
+
- r'fetch\(["\']([^"\']+)["\']'
|
|
805
|
+
- r'\.get\(["\']([^"\']+)["\']'
|
|
806
|
+
- r'\.post\(["\']([^"\']+)["\']'
|
|
807
|
+
|
|
808
|
+
【重要】发现API后深入分析来源JS:
|
|
809
|
+
→ 记录API所在的JS文件名
|
|
810
|
+
→ 深度分析该JS文件(用curl下载):
|
|
811
|
+
- 获取完整JS内容(可能有混淆,需多次提取)
|
|
812
|
+
- 提取所有API路径(不仅限正则匹配到的)
|
|
813
|
+
- 提取敏感信息(API密钥、硬编码凭证等)
|
|
814
|
+
- 提取URL模板(如 /user/${userId}/info)
|
|
815
|
+
|
|
816
|
+
3. 提取环境变量配置
|
|
817
|
+
patterns:
|
|
818
|
+
- r'VUE_APP_\w+'
|
|
819
|
+
- r'process\.env\.(\w+)'
|
|
820
|
+
|
|
821
|
+
4. 提取URL模板字符串
|
|
822
|
+
patterns:
|
|
823
|
+
- r'`[^`]*(?:api|user|auth|admin)[^`]*`'
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
**阶段4:API测试**
|
|
827
|
+
```
|
|
828
|
+
1. 确定base_path(关键!找不到时使用字典)
|
|
829
|
+
|
|
830
|
+
base_path获取优先级:
|
|
831
|
+
1. baseURL配置 → 直接使用
|
|
832
|
+
2. nginx反向代理推测 → 从响应头Server字段分析
|
|
833
|
+
3. 使用字典 fallback:
|
|
834
|
+
|
|
835
|
+
# 常见API前缀/父路径字典
|
|
836
|
+
common_api_prefixes = [
|
|
837
|
+
"/api", "/api/v1", "/api/v2", "/api/v3",
|
|
838
|
+
"/webapi", "/openapi", "/rest", "/rest/api",
|
|
839
|
+
"/admin", "/manager", "/backend", "/server",
|
|
840
|
+
"/user", "/auth", "/oauth", "/public",
|
|
841
|
+
]
|
|
842
|
+
|
|
843
|
+
2. 逐个测试发现的API端点
|
|
844
|
+
- GET请求:检查Content-Type和响应内容
|
|
845
|
+
- POST请求:测试登录接口(SQL注入/XSS)
|
|
846
|
+
|
|
847
|
+
3. 判断响应类型
|
|
848
|
+
- application/json → 真实API
|
|
849
|
+
- text/html → SPA路由或WAF拦截
|
|
850
|
+
|
|
851
|
+
4. 记录认证要求
|
|
852
|
+
- 401/403 → 需要认证(正常)
|
|
853
|
+
- 200 + JSON → 检查是否未授权
|
|
854
|
+
|
|
855
|
+
【重要】发现Swagger/接口文档时:
|
|
856
|
+
→ 立即访问获取更多API
|
|
857
|
+
→ 解析Swagger JSON获取完整API列表
|
|
858
|
+
→ 对获取的API立即进行漏洞测试
|
|
859
|
+
```
|
|
860
|
+
|
|
861
|
+
**阶段4.5:【新增】Fuzzing 组合测试**
|
|
862
|
+
|
|
863
|
+
重要发现:很多 API 网关只拦截 `/api/*` 路径,根路径(如 `/`, `/health`, `/metrics`)可能直接暴露后端服务。
|
|
864
|
+
|
|
865
|
+
测试策略:
|
|
866
|
+
|
|
867
|
+
```python
|
|
868
|
+
# 1. API 前缀字典
|
|
869
|
+
api_prefixes = [
|
|
870
|
+
# 已发现
|
|
871
|
+
"/api/admin", "/api/authority", "/api/system",
|
|
872
|
+
# 通用
|
|
873
|
+
"/api", "/api/v1", "/api/v2", "/api/v3", "/api/v4",
|
|
874
|
+
"/rest", "/rest/api", "/webapi",
|
|
875
|
+
# 认证
|
|
876
|
+
"/auth", "/oauth", "/oauth2", "/cas", "/sso",
|
|
877
|
+
# 管理
|
|
878
|
+
"/admin", "/admin/api", "/manager", "/backend",
|
|
879
|
+
# 协议
|
|
880
|
+
"/openapi", "/open/api", "/gateway", "/proxy",
|
|
881
|
+
]
|
|
882
|
+
|
|
883
|
+
# 2. API 端点字典(根据业务场景扩展)
|
|
884
|
+
api_endpoints = [
|
|
885
|
+
# 通用 CRUD
|
|
886
|
+
"login", "logout", "register", "list", "add", "delete", "modify",
|
|
887
|
+
"getList", "getListOfPage", "detail", "getInfo", "profile",
|
|
888
|
+
# 用户相关
|
|
889
|
+
"user", "user/list", "user/add", "user/delete", "user/modify",
|
|
890
|
+
"user/profile", "user/restPassword", "user/enable", "user/disable",
|
|
891
|
+
# 角色权限
|
|
892
|
+
"role", "role/list", "role/add", "role/delete", "role/modify",
|
|
893
|
+
"menu", "menu/list", "menu/add", "menu/delete", "menu/modify",
|
|
894
|
+
# 文件操作
|
|
895
|
+
"file", "upload", "download", "import", "export",
|
|
896
|
+
"imgUpload", "avatar", "attachment",
|
|
897
|
+
]
|
|
898
|
+
|
|
899
|
+
# 3. Fuzzing 测试
|
|
900
|
+
for prefix in api_prefixes:
|
|
901
|
+
for endpoint in api_endpoints:
|
|
902
|
+
url = target + prefix + "/" + endpoint
|
|
903
|
+
response = requests.get(url)
|
|
904
|
+
# 记录返回 200 的接口
|
|
905
|
+
```
|
|
906
|
+
|
|
907
|
+
**阶段4.6:【新增】API 根路径探测**
|
|
908
|
+
|
|
909
|
+
重要发现:`http://api.target.com/`、`/health`、`/metrics` 等路径返回 JSON,表明网关只拦截 `/api/*`。
|
|
910
|
+
|
|
911
|
+
```python
|
|
912
|
+
# 测试非 /api 路径
|
|
913
|
+
root_paths = [
|
|
914
|
+
"/", "/login", "/auth", "/oauth", "/sso", "/cas",
|
|
915
|
+
"/health", "/healthz", "/ready", "/status", "/info",
|
|
916
|
+
"/metrics", "/ping", "/actuator",
|
|
917
|
+
]
|
|
918
|
+
|
|
919
|
+
for path in root_paths:
|
|
920
|
+
url = api_base + path
|
|
921
|
+
response = requests.get(url)
|
|
922
|
+
if "json" in response.headers.get("Content-Type", ""):
|
|
923
|
+
# 发现可访问的接口
|
|
924
|
+
```
|
|
925
|
+
|
|
926
|
+
**阶段4.7:【新增】业务端点模板提示词参考
|
|
927
|
+
|
|
928
|
+
根据发现的 API 路径模式,使用以下提示词模板扩展测试:
|
|
929
|
+
|
|
930
|
+
```
|
|
931
|
+
## 业务端点扩展提示词
|
|
932
|
+
|
|
933
|
+
当发现类似 {resource}/list、{resource}/add 这类 API 模式时,可按以下模板扩展测试:
|
|
934
|
+
|
|
935
|
+
### 通用 CRUD 端点模式
|
|
936
|
+
```
|
|
937
|
+
发现的模式: /{module}/{operation}
|
|
938
|
+
可能存在的端点:
|
|
939
|
+
- /{module}/list → 列表查询
|
|
940
|
+
- /{module}/add → 新增创建
|
|
941
|
+
- /{module}/modify → 修改更新
|
|
942
|
+
- /{module}/delete → 删除操作
|
|
943
|
+
- /{module}/detail → 详情查看
|
|
944
|
+
- /{module}/getInfo → 信息获取
|
|
945
|
+
- /{module}/export → 导出数据
|
|
946
|
+
- /{module}/import → 导入数据
|
|
947
|
+
```
|
|
948
|
+
|
|
949
|
+
### RESTful 风格端点模式
|
|
950
|
+
```
|
|
951
|
+
发现的模式: /{resource}/{id}
|
|
952
|
+
可能存在的端点:
|
|
953
|
+
- GET /{resource}/{id} → 获取详情
|
|
954
|
+
- PUT /{resource}/{id} → 完整更新
|
|
955
|
+
- DELETE /{resource}/{id} → 删除资源
|
|
956
|
+
- PATCH /{resource}/{id} → 部分更新
|
|
957
|
+
```
|
|
958
|
+
|
|
959
|
+
### 管理后台常见端点模式
|
|
960
|
+
```
|
|
961
|
+
用户管理: user, users, member, members
|
|
962
|
+
- /admin/user/list, /admin/user/add, /admin/user/delete
|
|
963
|
+
- /system/user/export, /system/user/import
|
|
964
|
+
|
|
965
|
+
角色权限: role, roles, permission, menu
|
|
966
|
+
- /admin/role/list, /admin/role/add, /admin/role/delete
|
|
967
|
+
- /admin/menu/list, /admin/menu/tree
|
|
968
|
+
|
|
969
|
+
业务模块: 根据系统功能模块名扩展
|
|
970
|
+
- 物业管理: property, estate, building
|
|
971
|
+
- 订单管理: order, orders, transaction
|
|
972
|
+
- 内容管理: content, article, news
|
|
973
|
+
- 设备管理: device, equipment, sensor
|
|
974
|
+
```
|
|
975
|
+
|
|
976
|
+
### 端点扩展测试示例
|
|
977
|
+
```
|
|
978
|
+
发现的端点: /api/building/list
|
|
979
|
+
扩展测试:
|
|
980
|
+
1. GET /api/building/list → 列表
|
|
981
|
+
2. POST /api/building/add → 新增
|
|
982
|
+
3. POST /api/building/modify → 修改
|
|
983
|
+
4. POST /api/building/delete → 删除
|
|
984
|
+
5. GET /api/building/detail?id=1 → 详情
|
|
985
|
+
6. GET /api/building/export → 导出
|
|
986
|
+
7. POST /api/building/import → 导入
|
|
987
|
+
```
|
|
988
|
+
|
|
989
|
+
### API 前缀扩展提示词
|
|
990
|
+
```
|
|
991
|
+
当发现 /api/admin/xxx 时,可尝试:
|
|
992
|
+
- /api/authority/xxx
|
|
993
|
+
- /api/system/xxx
|
|
994
|
+
- /api/common/xxx
|
|
995
|
+
- /api/v1/xxx, /api/v2/xxx, /api/v3/xxx
|
|
996
|
+
|
|
997
|
+
当发现 /api/xxx 时,可尝试:
|
|
998
|
+
- /rest/api/xxx
|
|
999
|
+
- /webapi/xxx
|
|
1000
|
+
- /auth/xxx
|
|
1001
|
+
- /oauth/xxx
|
|
1002
|
+
```
|
|
1003
|
+
```
|
|
1004
|
+
|
|
1005
|
+
**阶段5:漏洞验证(10维度)**
|
|
1006
|
+
```
|
|
1007
|
+
□ 维度1: 响应类型 - 是JSON还是HTML?
|
|
1008
|
+
□ 维度2: 状态码 - 是否合理?
|
|
1009
|
+
□ 维度3: 响应长度 - 是否过短?
|
|
1010
|
+
□ 维度4: WAF拦截 - 是否为WAF?
|
|
1011
|
+
□ 维度5: 敏感信息 - 是否包含password/token?
|
|
1012
|
+
□ 维度6: 一致性 - 多次请求是否一致?
|
|
1013
|
+
□ 维度7: SQL注入 - 是否包含SQL错误?
|
|
1014
|
+
□ 维度8: IDOR - 是否返回用户数据?
|
|
1015
|
+
□ 维度9: 认证绕过 - 是否返回token?
|
|
1016
|
+
□ 维度10: 信息泄露 - 是否泄露非公开信息?
|
|
1017
|
+
```
|
|
1018
|
+
|
|
1019
|
+
### SPA采集流程检查清单
|
|
1020
|
+
|
|
1021
|
+
```
|
|
1022
|
+
□ 阶段1: 基础探测
|
|
1023
|
+
□ 目标可访问
|
|
1024
|
+
□ 技术栈识别完成
|
|
1025
|
+
□ 判断为SPA应用
|
|
1026
|
+
□ 检查Swagger/接口文档
|
|
1027
|
+
|
|
1028
|
+
□ 阶段2: JS采集
|
|
1029
|
+
□ Playwright无头浏览器启动
|
|
1030
|
+
□ wait_until="networkidle"
|
|
1031
|
+
□ 额外等待3-5秒
|
|
1032
|
+
□ 获取所有JS文件列表
|
|
1033
|
+
□ 拦截API请求(XHR/Fetch)
|
|
1034
|
+
□ 采集响应头(Server、IP、域名)
|
|
1035
|
+
□ 采集localStorage敏感信息
|
|
1036
|
+
|
|
1037
|
+
□ 阶段3: JS分析(AST+正则双模式)
|
|
1038
|
+
□ 提取baseURL配置
|
|
1039
|
+
□ AST模式解析JS字符串字面量
|
|
1040
|
+
□ 正则模式提取API路径
|
|
1041
|
+
□ 提取环境变量
|
|
1042
|
+
□ 提取URL模板
|
|
1043
|
+
□ 【新增】提取IP地址
|
|
1044
|
+
□ 【新增】提取外部域名
|
|
1045
|
+
□ 【新增】提取敏感凭证
|
|
1046
|
+
□ 【新增】深度分析来源JS文件
|
|
1047
|
+
|
|
1048
|
+
□ 阶段4: API测试
|
|
1049
|
+
□ 确定base_path(配置→反推→字典)
|
|
1050
|
+
□ 逐个测试API端点
|
|
1051
|
+
□ 区分JSON/HTML响应
|
|
1052
|
+
□ 测试POST登录接口
|
|
1053
|
+
□ 发现Swagger立即解析
|
|
1054
|
+
|
|
1055
|
+
□ 阶段5: 漏洞验证
|
|
1056
|
+
□ 10维度验证
|
|
1057
|
+
□ 排除SPA路由误报
|
|
1058
|
+
□ 确认或排除漏洞
|
|
1059
|
+
```
|
|
1060
|
+
|
|
1061
|
+
### 遇到加密/混淆的数据时
|
|
1062
|
+
|
|
1063
|
+
```
|
|
1064
|
+
思考:
|
|
1065
|
+
- 能解密吗? → 查看前端JS代码
|
|
1066
|
+
- 有密钥泄露吗? → 检查响应、注释
|
|
1067
|
+
- 能绕过吗? → 不带加密参数试试
|
|
1068
|
+
```
|
|
1069
|
+
|
|
1070
|
+
### 遇到验证码/限流时
|
|
1071
|
+
|
|
1072
|
+
```
|
|
1073
|
+
思考:
|
|
1074
|
+
- 验证码能绕过吗? → 改参数、删cookie
|
|
1075
|
+
- 限流能绕过吗? → 改IP、延时
|
|
1076
|
+
- 有风控吗? → 行为异常检测
|
|
1077
|
+
```
|
|
1078
|
+
|
|
1079
|
+
### 遇到WAP环境时
|
|
1080
|
+
|
|
1081
|
+
```
|
|
1082
|
+
思考:
|
|
1083
|
+
- 需要Cookie吗? → 保持session
|
|
1084
|
+
- 需要Referer吗? → 添加来源
|
|
1085
|
+
- 需要特定Header吗? → 复制正常请求头
|
|
1086
|
+
```
|
|
1087
|
+
|
|
1088
|
+
---
|
|
1089
|
+
|
|
1090
|
+
## 核心模块能力池 (core/)
|
|
1091
|
+
|
|
1092
|
+
> **重要:能力池只作为参考,不是固定流程**
|
|
1093
|
+
> - 根据目标站点特点选择合适的模块
|
|
1094
|
+
> - 根据测试阶段动态调整
|
|
1095
|
+
> - 可以只用部分模块,也可以组合使用
|
|
1096
|
+
|
|
1097
|
+
### 目录结构
|
|
1098
|
+
|
|
1099
|
+
```
|
|
1100
|
+
core/ # 核心能力池(原子化)
|
|
1101
|
+
├── collectors/ # 信息采集能力
|
|
1102
|
+
│ ├── http_client.py # HTTP请求能力
|
|
1103
|
+
│ ├── js_parser.py # JS源码解析(AST+正则)
|
|
1104
|
+
│ ├── browser_collect.py # 无头浏览器采集
|
|
1105
|
+
│ ├── js_collector.py # JS采集(基础版)
|
|
1106
|
+
│ ├── browser_collector.py # 浏览器采集(基础版)
|
|
1107
|
+
│ ├── url_collector.py # URL采集
|
|
1108
|
+
│ └── api_path_finder.py # API路径发现
|
|
1109
|
+
├── analyzers/ # 分析能力
|
|
1110
|
+
│ ├── api_parser.py # API端点解析
|
|
1111
|
+
│ ├── response_analyzer.py # 响应类型分析
|
|
1112
|
+
│ ├── sensitive_finder.py # 敏感信息发现
|
|
1113
|
+
│ └── sensitive_finder.py # 敏感信息发现
|
|
1114
|
+
├── testers/ # 测试能力
|
|
1115
|
+
│ ├── sqli_tester.py # SQL注入测试
|
|
1116
|
+
│ ├── idor_tester.py # 越权测试
|
|
1117
|
+
│ ├── auth_tester.py # 认证测试
|
|
1118
|
+
│ ├── jwt_tester.py # JWT测试
|
|
1119
|
+
│ ├── fuzz_tester.py # 模糊测试
|
|
1120
|
+
│ ├── api_fuzzer.py # API模糊测试
|
|
1121
|
+
│ └── browser_tester.py # 浏览器测试
|
|
1122
|
+
├── verifiers/ # 验证能力
|
|
1123
|
+
│ ├── vuln_verifier.py # 漏洞验证(10维度)
|
|
1124
|
+
│ └── response_diff.py # 响应差异对比
|
|
1125
|
+
├── utils/ # 工具能力
|
|
1126
|
+
│ ├── prerequisite.py # 依赖检查
|
|
1127
|
+
│ ├── payload_lib.py # Payload库
|
|
1128
|
+
│ └── base_path_dict.py # API base path字典
|
|
1129
|
+
└── advanced/ # 高级能力
|
|
1130
|
+
├── advanced_recon.py # 高级侦察(子域名/Swagger)
|
|
1131
|
+
├── agentic_analyzer.py # 智能分析
|
|
1132
|
+
├── dynamic_api_analyzer.py # 动态API分析
|
|
1133
|
+
├── deep_api_tester_v35.py # 深度测试v35
|
|
1134
|
+
├── deep_api_tester_v55.py # 深度测试v55
|
|
1135
|
+
├── cloud_storage_tester.py # 云存储测试
|
|
1136
|
+
├── context_manager.py # 上下文管理
|
|
1137
|
+
├── orchestrator.py # 编排器
|
|
1138
|
+
├── reasoning_engine.py # 推理引擎
|
|
1139
|
+
├── strategy_pool.py # 策略池
|
|
1140
|
+
├── scan_engine.py # 扫描引擎
|
|
1141
|
+
├── response_classifier.py # 响应分类
|
|
1142
|
+
├── models.py # 数据模型
|
|
1143
|
+
├── skill_executor.py # Skill执行器
|
|
1144
|
+
├── skill_executor_v2.py # Skill执行器v2
|
|
1145
|
+
├── skill_executor_v3.py # Skill执行器v3
|
|
1146
|
+
└── testing_loop.py # 测试循环
|
|
1147
|
+
```
|
|
1148
|
+
|
|
1149
|
+
### 能力池模块参考
|
|
1150
|
+
|
|
1151
|
+
| 阶段 | 可用模块 | 路径 | 使用场景 | 必须 |
|
|
1152
|
+
|------|----------|------|----------|------|
|
|
1153
|
+
| **采集-发现** | | | 发现API端点时 | |
|
|
1154
|
+
| | `browser_collect.py` | `core/collectors/browser_collect.py` | SPA应用必须使用,采集JS+API+敏感信息 | ✅ |
|
|
1155
|
+
| | `js_parser.py` | `core/collectors/js_parser.py` | 从JS提取API,使用AST+正则双模式 | ✅ |
|
|
1156
|
+
| | `js_collector.py` | `core/collectors/js_collector.py` | 简单JS采集,快速提取 | |
|
|
1157
|
+
| | `browser_collector.py` | `core/collectors/browser_collector.py` | 浏览器基础采集 | |
|
|
1158
|
+
| | `http_client.py` | `core/collectors/http_client.py` | 快速HTTP探测,获取HTML/响应头 | |
|
|
1159
|
+
| | `url_collector.py` | `core/collectors/url_collector.py` | 批量URL收集 | |
|
|
1160
|
+
| | `api_path_finder.py` | `core/collectors/api_path_finder.py` | 从响应/JS中自动发现API路径 | |
|
|
1161
|
+
| | `advanced_recon.py` | `core/advanced_recon.py` | 发现Swagger/子域名枚举,批量资产发现 | |
|
|
1162
|
+
| **采集-敏感信息** | | | 发现敏感信息泄露时 | |
|
|
1163
|
+
| | `sensitive_finder.py` | `core/analyzers/sensitive_finder.py` | 提取password/token/密钥等敏感字段 | |
|
|
1164
|
+
| | `response_analyzer.py` | `core/analyzers/response_analyzer.py` | 分析响应类型,识别JSON/HTML/WAF | |
|
|
1165
|
+
| **测试-漏洞** | | | 测试具体漏洞类型时 | |
|
|
1166
|
+
| | `sqli_tester.py` | `core/testers/sqli_tester.py` | SQL注入测试,检测SQL错误 | |
|
|
1167
|
+
| | `idor_tester.py` | `core/testers/idor_tester.py` | 越权测试,IDOR漏洞检测 | |
|
|
1168
|
+
| | `auth_tester.py` | `core/testers/auth_tester.py` | 认证绕过测试,弱密码检测 | |
|
|
1169
|
+
| | `jwt_tester.py` | `core/testers/jwt_tester.py` | JWT漏洞测试,alg:none等 | |
|
|
1170
|
+
| | `fuzz_tester.py` | `core/testers/fuzz_tester.py` | 参数fuzzing,模糊测试 | |
|
|
1171
|
+
| | `api_fuzzer.py` | `core/api_fuzzer.py` | API端点fuzzing,参数挖掘 | |
|
|
1172
|
+
| | `browser_tester.py` | `core/browser_tester.py` | DOM XSS,浏览器环境测试 | |
|
|
1173
|
+
| | `cloud_storage_tester.py` | `core/cloud_storage_tester.py` | OSS/Bucket安全测试 | |
|
|
1174
|
+
| **验证** | | | 验证漏洞确认时 | |
|
|
1175
|
+
| | `vuln_verifier.py` | `core/verifiers/vuln_verifier.py` | 10维度漏洞验证,确认/排除 | ✅ |
|
|
1176
|
+
| | `response_diff.py` | `core/verifiers/response_diff.py` | 响应对比,排除误报 | |
|
|
1177
|
+
| **辅助** | | | 支撑能力 | |
|
|
1178
|
+
| | `base_path_dict.py` | `core/utils/base_path_dict.py` | 找不到baseURL时,fuzzing父路径 | ✅ |
|
|
1179
|
+
| | `prerequisite.py` | `core/utils/prerequisite.py` | 依赖检查,工具可用性验证 | ✅ |
|
|
1180
|
+
| **高级/编排** | | | 复杂测试场景 | |
|
|
1181
|
+
| | `dynamic_api_analyzer.py` | `core/dynamic_api_analyzer.py` | 动态API分析,运行时分析 | |
|
|
1182
|
+
| | `deep_api_tester_v35.py` | `core/deep_api_tester_v35.py` | 深度测试v35,综合测试 | |
|
|
1183
|
+
| | `deep_api_tester_v55.py` | `core/deep_api_tester_v55.py` | 深度测试v55,高级测试 | |
|
|
1184
|
+
| | `context_manager.py` | `core/context_manager.py` | 管理测试上下文,状态维护 | |
|
|
1185
|
+
| | `orchestrator.py` | `core/orchestrator.py` | 编排多阶段测试流程 | |
|
|
1186
|
+
| | `reasoning_engine.py` | `core/reasoning_engine.py` | 攻击链推理,漏洞关联 | |
|
|
1187
|
+
| | `strategy_pool.py` | `core/strategy_pool.py` | 测试策略选择,自适应测试 | |
|
|
1188
|
+
| | `scan_engine.py` | `core/scan_engine.py` | 扫描编排,批量测试 | |
|
|
1189
|
+
| | `response_classifier.py` | `core/response_classifier.py` | 响应分类,模式识别 | |
|
|
1190
|
+
| | `models.py` | `core/models.py` | 数据模型定义 | |
|
|
1191
|
+
| | `skill_executor.py` | `core/skill_executor.py` | Skill执行主入口 | |
|
|
1192
|
+
| | `skill_executor_v2.py` | `core/skill_executor_v2.py` | Skill执行器v2 | |
|
|
1193
|
+
| | `skill_executor_v3.py` | `core/skill_executor_v3.py` | Skill执行器v3 | |
|
|
1194
|
+
| | `testing_loop.py` | `core/testing_loop.py` | 测试循环,持续测试 | |
|
|
1195
|
+
|
|
1196
|
+
### SPA应用采集流程(必须遵循)
|
|
1197
|
+
|
|
1198
|
+
```
|
|
1199
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
1200
|
+
│ 阶段1: 基础探测 │
|
|
1201
|
+
├─────────────────────────────────────────────────────────────┤
|
|
1202
|
+
│ 1. HTTP探测: http_client.py → curl探测 │
|
|
1203
|
+
│ 参考: core/collectors/http_client.py │
|
|
1204
|
+
│ │
|
|
1205
|
+
│ 2. 技术栈识别: browser_collect.py → 检测Vue/React/Angular │
|
|
1206
|
+
│ 参考: core/collectors/browser_collect.py │
|
|
1207
|
+
│ │
|
|
1208
|
+
│ 3. 判断SPA: /api/* 返回HTML → SPA应用 │
|
|
1209
|
+
│ │
|
|
1210
|
+
│ 4. 【补充】Swagger/接口文档探测: │
|
|
1211
|
+
│ - /swagger-ui.html │
|
|
1212
|
+
│ - /swagger-ui/index.html │
|
|
1213
|
+
│ - /v2/api-docs │
|
|
1214
|
+
│ - /api-docs │
|
|
1215
|
+
│ - /doc.html │
|
|
1216
|
+
│ → 发现Swagger立即解析获取完整API列表 │
|
|
1217
|
+
│ │
|
|
1218
|
+
│ 5. 【补充】nginx反向代理分析: │
|
|
1219
|
+
│ - Server响应头识别后端技术 │
|
|
1220
|
+
│ - 常见端口探测: 8080, 8443, 9000, 5000, 3000 │
|
|
1221
|
+
│ 参考: advanced_recon.py │
|
|
1222
|
+
└─────────────────────────────────────────────────────────────┘
|
|
1223
|
+
↓
|
|
1224
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
1225
|
+
│ 阶段2: JS采集(必须使用Playwright) │
|
|
1226
|
+
├─────────────────────────────────────────────────────────────┤
|
|
1227
|
+
│ 1. 启动浏览器: browser_collect.py │
|
|
1228
|
+
│ 参考: core/collectors/browser_collect.py │
|
|
1229
|
+
│ │
|
|
1230
|
+
│ 2. 访问目标: page.goto(url, wait_until="networkidle") │
|
|
1231
|
+
│ │
|
|
1232
|
+
│ 3. 等待加载: page.wait_for_timeout(5000) │
|
|
1233
|
+
│ │
|
|
1234
|
+
│ 4. 【增强】自动交互触发API: │
|
|
1235
|
+
│ - 自动填写登录表单 (admin/admin123) │
|
|
1236
|
+
│ - 自动点击登录按钮触发API请求 │
|
|
1237
|
+
│ - 捕获登录后的真实API请求 │
|
|
1238
|
+
│ 参考: core/collectors/browser_collect.py (interact=True) │
|
|
1239
|
+
│ │
|
|
1240
|
+
│ 5. 提取JS: js_parser.py → 从HTML提取JS文件列表 │
|
|
1241
|
+
│ 参考: core/collectors/js_parser.py │
|
|
1242
|
+
│ │
|
|
1243
|
+
│ 6. 拦截API: browser_collect.py → 捕获XHR/Fetch请求 │
|
|
1244
|
+
│ 参考: core/collectors/browser_collect.py │
|
|
1245
|
+
│ │
|
|
1246
|
+
│ 7. 采集敏感信息: sensitive_finder.py → localStorage/响应头│
|
|
1247
|
+
│ 参考: core/analyzers/sensitive_finder.py │
|
|
1248
|
+
└─────────────────────────────────────────────────────────────┘
|
|
1249
|
+
↓
|
|
1250
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
1251
|
+
│ 阶段3: JS深度分析(AST+正则双模式) │
|
|
1252
|
+
├─────────────────────────────────────────────────────────────┤
|
|
1253
|
+
│ 1. baseURL配置: js_parser.py → extract_base_urls() │
|
|
1254
|
+
│ 参考: core/collectors/js_parser.py │
|
|
1255
|
+
│ patterns: │
|
|
1256
|
+
│ - r'baseURL\s*[:=]\s*["\']([^"\']+)["\']' │
|
|
1257
|
+
│ - r'axios\.create\s*\(\s*\{([^}]+)\}' │
|
|
1258
|
+
│ │
|
|
1259
|
+
│ 2. API路径提取: │
|
|
1260
|
+
│ → js_parser.py → extract_api_patterns() (正则) │
|
|
1261
|
+
│ → js_parser.py → prepare_js_for_agent() (Agent解析) │
|
|
1262
|
+
│ 【重要】混淆JS无法AST时,准备内容供Agent解析 │
|
|
1263
|
+
│ 参考: core/collectors/js_parser.py │
|
|
1264
|
+
│ │
|
|
1265
|
+
│ 3. 敏感信息: sensitive_finder.py → 提取IP/域名/凭证 │
|
|
1266
|
+
│ 参考: core/analyzers/sensitive_finder.py │
|
|
1267
|
+
│ │
|
|
1268
|
+
│ 4. base_path获取: base_path_dict.py → get_base_path... │
|
|
1269
|
+
│ 参考: core/utils/base_path_dict.py │
|
|
1270
|
+
└─────────────────────────────────────────────────────────────┘
|
|
1271
|
+
↓
|
|
1272
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
1273
|
+
│ 阶段2: JS采集(必须使用Playwright) │
|
|
1274
|
+
├─────────────────────────────────────────────────────────────┤
|
|
1275
|
+
│ 1. 启动浏览器: browser_collect.py │
|
|
1276
|
+
│ 参考: core/collectors/browser_collect.py │
|
|
1277
|
+
│ │
|
|
1278
|
+
│ 2. 访问目标: page.goto(url, wait_until="networkidle") │
|
|
1279
|
+
│ │
|
|
1280
|
+
│ 3. 等待加载: page.wait_for_timeout(5000) │
|
|
1281
|
+
│ │
|
|
1282
|
+
│ 4. 提取JS: js_parser.py → 从HTML提取JS文件列表 │
|
|
1283
|
+
│ 参考: core/collectors/js_parser.py │
|
|
1284
|
+
│ │
|
|
1285
|
+
│ 5. 拦截API: browser_collect.py → 捕获XHR/Fetch请求 │
|
|
1286
|
+
│ 参考: core/collectors/browser_collect.py │
|
|
1287
|
+
│ │
|
|
1288
|
+
│ 6. 采集敏感信息: sensitive_finder.py → localStorage/响应头│
|
|
1289
|
+
│ 参考: core/analyzers/sensitive_finder.py │
|
|
1290
|
+
└─────────────────────────────────────────────────────────────┘
|
|
1291
|
+
↓
|
|
1292
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
1293
|
+
│ 阶段3: JS深度分析(AST+正则双模式) │
|
|
1294
|
+
├─────────────────────────────────────────────────────────────┤
|
|
1295
|
+
│ 1. baseURL配置: js_parser.py → extract_base_urls() │
|
|
1296
|
+
│ 参考: core/collectors/js_parser.py │
|
|
1297
|
+
│ patterns: │
|
|
1298
|
+
│ - r'baseURL\s*[:=]\s*["\']([^"\']+)["\']' │
|
|
1299
|
+
│ - r'axios\.create\s*\(\s*\{([^}]+)\}' │
|
|
1300
|
+
│ │
|
|
1301
|
+
│ 2. API路径提取: │
|
|
1302
|
+
│ → js_parser.py → extract_api_patterns() (正则) │
|
|
1303
|
+
│ → js_parser.py → extract_with_ast() (AST) │
|
|
1304
|
+
│ 参考: core/collectors/js_parser.py │
|
|
1305
|
+
│ │
|
|
1306
|
+
│ 3. 敏感信息: sensitive_finder.py → 提取IP/域名/凭证 │
|
|
1307
|
+
│ 参考: core/analyzers/sensitive_finder.py │
|
|
1308
|
+
│ │
|
|
1309
|
+
│ 4. base_path获取: base_path_dict.py → get_base_path... │
|
|
1310
|
+
│ 参考: core/utils/base_path_dict.py │
|
|
1311
|
+
└─────────────────────────────────────────────────────────────┘
|
|
1312
|
+
↓
|
|
1313
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
1314
|
+
│ 阶段4: API测试 │
|
|
1315
|
+
├─────────────────────────────────────────────────────────────┤
|
|
1316
|
+
│ 1. base_path拼接: base_path_dict.py → generate_fuzz_paths() │
|
|
1317
|
+
│ 参考: core/utils/base_path_dict.py │
|
|
1318
|
+
│ │
|
|
1319
|
+
│ 2. SQL注入: sqli_tester.py → 测试SQL注入 │
|
|
1320
|
+
│ 参考: core/testers/sqli_tester.py │
|
|
1321
|
+
│ │
|
|
1322
|
+
│ 3. 越权测试: idor_tester.py → 测试IDOR │
|
|
1323
|
+
│ 参考: core/testers/idor_tester.py │
|
|
1324
|
+
│ │
|
|
1325
|
+
│ 4. 认证测试: auth_tester.py → 测试认证绕过 │
|
|
1326
|
+
│ 参考: core/testers/auth_tester.py │
|
|
1327
|
+
│ │
|
|
1328
|
+
│ 5. JWT测试: jwt_tester.py → 测试JWT漏洞 │
|
|
1329
|
+
│ 参考: core/testers/jwt_tester.py │
|
|
1330
|
+
│ │
|
|
1331
|
+
│ 6. Fuzzing: fuzz_tester.py → 参数fuzzing │
|
|
1332
|
+
│ 参考: core/testers/fuzz_tester.py │
|
|
1333
|
+
│ │
|
|
1334
|
+
│ 7. 发现Swagger: advanced_recon.py → 解析获取完整API │
|
|
1335
|
+
│ 参考: core/advanced_recon.py │
|
|
1336
|
+
└─────────────────────────────────────────────────────────────┘
|
|
1337
|
+
↓
|
|
1338
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
1339
|
+
│ 阶段5: 漏洞验证(10维度) │
|
|
1340
|
+
├─────────────────────────────────────────────────────────────┤
|
|
1341
|
+
│ 1. vuln_verifier.py → 10维度验证 │
|
|
1342
|
+
│ 参考: core/verifiers/vuln_verifier.py │
|
|
1343
|
+
│ │
|
|
1344
|
+
│ 2. response_diff.py → 响应对比排除误报 │
|
|
1345
|
+
│ 参考: core/verifiers/response_diff.py │
|
|
1346
|
+
│ │
|
|
1347
|
+
│ 3. response_analyzer.py → 响应类型分析 │
|
|
1348
|
+
│ 参考: core/analyzers/response_analyzer.py │
|
|
1349
|
+
└─────────────────────────────────────────────────────────────┘
|
|
1350
|
+
```
|
|
1351
|
+
|
|
1352
|
+
### 完整模块参考(按阶段分类)
|
|
1353
|
+
|
|
1354
|
+
---
|
|
1355
|
+
|
|
1356
|
+
## 一、采集阶段(Collector)
|
|
1357
|
+
|
|
1358
|
+
| 模块 | 路径 | 功能描述 |
|
|
1359
|
+
|------|------|---------|
|
|
1360
|
+
| `http_client.py` | `core/collectors/http_client.py` | HTTP请求客户端,支持GET/POST/HEAD等,用于快速探测目标、获取响应头 |
|
|
1361
|
+
| `js_parser.py` | `core/collectors/js_parser.py` | JS源码解析,AST+正则双模式提取API路径、baseURL、敏感信息、IP/域名 |
|
|
1362
|
+
| `browser_collect.py` | `core/collectors/browser_collect.py` | Playwright无头浏览器采集,捕获XHR/Fetch请求、JS文件、localStorage、响应头 |
|
|
1363
|
+
| `js_collector.py` | `core/collectors/js_collector.py` | 简单JS采集器,快速提取HTML中的JS文件列表 |
|
|
1364
|
+
| `browser_collector.py` | `core/collectors/browser_collector.py` | 浏览器采集基础版,模拟浏览器行为 |
|
|
1365
|
+
| `url_collector.py` | `core/collectors/url_collector.py` | URL采集器,批量收集页面中的链接和URL |
|
|
1366
|
+
| `api_path_finder.py` | `core/collectors/api_path_finder.py` | API路径发现,从响应/JS中自动发现API端点 |
|
|
1367
|
+
|
|
1368
|
+
---
|
|
1369
|
+
|
|
1370
|
+
## 二、分析阶段(Analyzer)
|
|
1371
|
+
|
|
1372
|
+
| 模块 | 路径 | 功能描述 |
|
|
1373
|
+
|------|------|---------|
|
|
1374
|
+
| `api_parser.py` | `core/analyzers/api_parser.py` | API端点解析,提取路径、方法、参数、请求体格式 |
|
|
1375
|
+
| `response_analyzer.py` | `core/analyzers/response_analyzer.py` | 响应类型分析,区分JSON/HTML/WAF,判断响应是否正常 |
|
|
1376
|
+
| `sensitive_finder.py` | `core/analyzers/sensitive_finder.py` | 敏感信息发现,提取password/token/密钥/IP/域名/凭证 |
|
|
1377
|
+
| `dynamic_api_analyzer.py` | `core/dynamic_api_analyzer.py` | 动态API分析,运行时分析和行为追踪 |
|
|
1378
|
+
| `agentic_analyzer.py` | `core/agentic_analyzer.py` | 智能分析,AI驱动的漏洞模式识别 |
|
|
1379
|
+
| `smart_analyzer.py` | `core/smart_analyzer.py` | 智能分析,启发式漏洞检测 |
|
|
1380
|
+
| `response_classifier.py` | `core/response_classifier.py` | 响应分类,模式匹配和分类 |
|
|
1381
|
+
|
|
1382
|
+
---
|
|
1383
|
+
|
|
1384
|
+
## 三、测试阶段(Tester)
|
|
1385
|
+
|
|
1386
|
+
| 模块 | 路径 | 功能描述 |
|
|
1387
|
+
|------|------|---------|
|
|
1388
|
+
| `sqli_tester.py` | `core/testers/sqli_tester.py` | SQL注入测试,检测SQL错误、布尔盲注、时间盲注 |
|
|
1389
|
+
| `idor_tester.py` | `core/testers/idor_tester.py` | 越权测试(IDOR),检测水平/垂直越权漏洞 |
|
|
1390
|
+
| `auth_tester.py` | `core/testers/auth_tester.py` | 认证测试,检测弱密码、暴力破解、认证绕过 |
|
|
1391
|
+
| `jwt_tester.py` | `core/testers/jwt_tester.py` | JWT测试,检测alg:none、签名弱密钥、token泄露 |
|
|
1392
|
+
| `fuzz_tester.py` | `core/testers/fuzz_tester.py` | 参数fuzzing,模糊测试发现隐藏参数 |
|
|
1393
|
+
| `api_fuzzer.py` | `core/api_fuzzer.py` | API端点fuzzing,参数挖掘和边界测试 |
|
|
1394
|
+
| `browser_tester.py` | `core/browser_tester.py` | 浏览器测试,DOM XSS、客户端漏洞检测 |
|
|
1395
|
+
| `cloud_storage_tester.py` | `core/cloud_storage_tester.py` | 云存储测试,OSS/Bucket权限配置错误检测 |
|
|
1396
|
+
| `deep_api_tester_v35.py` | `core/deep_api_tester_v35.py` | 深度测试v35,综合漏洞测试 |
|
|
1397
|
+
| `deep_api_tester_v55.py` | `core/deep_api_tester_v55.py` | 深度测试v55,高级测试场景 |
|
|
1398
|
+
| `testing_loop.py` | `core/testing_loop.py` | 测试循环,持续迭代测试 |
|
|
1399
|
+
|
|
1400
|
+
---
|
|
1401
|
+
|
|
1402
|
+
## 四、验证阶段(Verifier)
|
|
1403
|
+
|
|
1404
|
+
| 模块 | 路径 | 功能描述 |
|
|
1405
|
+
|------|------|---------|
|
|
1406
|
+
| `vuln_verifier.py` | `core/verifiers/vuln_verifier.py` | 10维度漏洞验证,确认/排除漏洞,输出验证报告 |
|
|
1407
|
+
| `response_diff.py` | `core/verifiers/response_diff.py` | 响应差异对比,排除误报,确定真实漏洞 |
|
|
1408
|
+
|
|
1409
|
+
---
|
|
1410
|
+
|
|
1411
|
+
## 五、辅助阶段(Utils)
|
|
1412
|
+
|
|
1413
|
+
| 模块 | 路径 | 功能描述 |
|
|
1414
|
+
|------|------|---------|
|
|
1415
|
+
| `base_path_dict.py` | `core/utils/base_path_dict.py` | API base path字典,找不到baseURL时fuzzing父路径 |
|
|
1416
|
+
| `payload_lib.py` | `core/utils/payload_lib.py` | Payload库,SQL注入、XSS、命令注入等Payload集合 |
|
|
1417
|
+
| `prerequisite.py` | `core/utils/prerequisite.py` | 依赖检查,验证工具可用性 |
|
|
1418
|
+
|
|
1419
|
+
---
|
|
1420
|
+
|
|
1421
|
+
## 六、高级能力(Advanced)
|
|
1422
|
+
|
|
1423
|
+
| 模块 | 路径 | 功能描述 |
|
|
1424
|
+
|------|------|---------|
|
|
1425
|
+
| `advanced_recon.py` | `core/advanced_recon.py` | 高级侦察,Swagger/子域名枚举、批量资产发现 |
|
|
1426
|
+
| `context_manager.py` | `core/context_manager.py` | 上下文管理,测试状态维护、会话管理 |
|
|
1427
|
+
| `orchestrator.py` | `core/orchestrator.py` | 编排器,多阶段测试流程编排 |
|
|
1428
|
+
| `reasoning_engine.py` | `core/reasoning_engine.py` | 推理引擎,攻击链推理、漏洞关联分析 |
|
|
1429
|
+
| `strategy_pool.py` | `core/strategy_pool.py` | 策略池,测试策略选择、自适应测试 |
|
|
1430
|
+
| `scan_engine.py` | `core/scan_engine.py` | 扫描引擎,批量扫描编排 |
|
|
1431
|
+
| `models.py` | `core/models.py` | 数据模型,测试结果/漏洞数据结构定义 |
|
|
1432
|
+
| `skill_executor.py` | `core/skill_executor.py` | Skill执行器主入口 |
|
|
1433
|
+
| `skill_executor_v2.py` | `core/skill_executor_v2.py` | Skill执行器v2 |
|
|
1434
|
+
| `skill_executor_v3.py` | `core/skill_executor_v3.py` | Skill执行器v3 |
|
|
1435
|
+
| `runner.py` | `core/runner.py` | 测试运行器 |
|
|
1436
|
+
| `api_interceptor.py` | `core/api_interceptor.py` | API拦截器,请求/响应拦截修改 |
|
|
1437
|
+
|
|
1438
|
+
---
|
|
1439
|
+
|
|
1440
|
+
### 场景→模块映射(按阶段)
|
|
1441
|
+
|
|
1442
|
+
| 阶段 | 场景 | 推荐模块 | 路径 |
|
|
1443
|
+
|------|------|---------|------|
|
|
1444
|
+
| **采集** | SPA应用发现API | `browser_collect.py` + `js_parser.py` | `core/collectors/` |
|
|
1445
|
+
| **采集** | 快速探测目标 | `http_client.py` | `core/collectors/http_client.py` |
|
|
1446
|
+
| **采集** | 自动交互触发API | `browser_collect.py` (interact=True) | `core/collectors/browser_collect.py` |
|
|
1447
|
+
| **采集** | JS采集(混淆JS-Agent解析) | `js_parser.py` (prepare_js_for_agent) | `core/collectors/js_parser.py` |
|
|
1448
|
+
| **采集** | base_path多维度获取 | `base_path_dict.py` (get_base_path_multi_dimensional) | `core/utils/base_path_dict.py` |
|
|
1449
|
+
| **采集** | 登录即测 | `browser_collect.py` (analyze_login_requests) | `core/collectors/browser_collect.py` |
|
|
1450
|
+
| **采集** | URL批量采集 | `url_collector.py` | `core/collectors/url_collector.py` |
|
|
1451
|
+
| **采集** | API路径自动发现 | `api_path_finder.py` | `core/collectors/api_path_finder.py` |
|
|
1452
|
+
| **采集** | Swagger/子域名 | `advanced_recon.py` | `core/advanced_recon.py` |
|
|
1453
|
+
| **分析** | 响应类型分析 | `response_analyzer.py` | `core/analyzers/response_analyzer.py` |
|
|
1454
|
+
| **分析** | 敏感信息发现 | `sensitive_finder.py` | `core/analyzers/sensitive_finder.py` |
|
|
1455
|
+
| **分析** | API端点解析 | `api_parser.py` | `core/analyzers/api_parser.py` |
|
|
1456
|
+
| **分析** | 动态API分析 | `dynamic_api_analyzer.py` | `core/dynamic_api_analyzer.py` |
|
|
1457
|
+
| **分析** | 响应分类 | `response_classifier.py` | `core/response_classifier.py` |
|
|
1458
|
+
| **分析** | 智能分析 | `agentic_analyzer.py` / `smart_analyzer.py` | `core/` |
|
|
1459
|
+
| **测试** | SQL注入测试 | `sqli_tester.py` | `core/testers/sqli_tester.py` |
|
|
1460
|
+
| **测试** | 越权测试 | `idor_tester.py` | `core/testers/idor_tester.py` |
|
|
1461
|
+
| **测试** | 认证绕过测试 | `auth_tester.py` | `core/testers/auth_tester.py` |
|
|
1462
|
+
| **测试** | JWT漏洞测试 | `jwt_tester.py` | `core/testers/jwt_tester.py` |
|
|
1463
|
+
| **测试** | 参数fuzzing | `fuzz_tester.py` | `core/testers/fuzz_tester.py` |
|
|
1464
|
+
| **测试** | API端点fuzzing | `api_fuzzer.py` | `core/api_fuzzer.py` |
|
|
1465
|
+
| **测试** | DOM XSS测试 | `browser_tester.py` | `core/browser_tester.py` |
|
|
1466
|
+
| **测试** | OSS/Bucket测试 | `cloud_storage_tester.py` | `core/cloud_storage_tester.py` |
|
|
1467
|
+
| **测试** | 深度综合测试 | `deep_api_tester_v55.py` | `core/deep_api_tester_v55.py` |
|
|
1468
|
+
| **测试** | 持续测试循环 | `testing_loop.py` | `core/testing_loop.py` |
|
|
1469
|
+
| **验证** | 漏洞验证(10维度) | `vuln_verifier.py` | `core/verifiers/vuln_verifier.py` |
|
|
1470
|
+
| **验证** | 响应对比排除误报 | `response_diff.py` | `core/verifiers/response_diff.py` |
|
|
1471
|
+
| **辅助** | base_path缺失 | `base_path_dict.py` | `core/utils/base_path_dict.py` |
|
|
1472
|
+
| **辅助** | Payload库 | `payload_lib.py` | `core/utils/payload_lib.py` |
|
|
1473
|
+
| **辅助** | 依赖检查 | `prerequisite.py` | `core/utils/prerequisite.py` |
|
|
1474
|
+
| **编排** | 上下文管理 | `context_manager.py` | `core/context_manager.py` |
|
|
1475
|
+
| **编排** | 测试编排 | `orchestrator.py` / `scan_engine.py` | `core/` |
|
|
1476
|
+
| **编排** | 攻击链推理 | `reasoning_engine.py` | `core/reasoning_engine.py` |
|
|
1477
|
+
| **编排** | 策略选择 | `strategy_pool.py` | `core/strategy_pool.py` |
|
|
1478
|
+
| **执行** | Skill执行 | `skill_executor*.py` | `core/skill_executor*.py` |
|
|
1479
|
+
| **数据** | 数据模型 | `models.py` | `core/models.py` |
|
|
1480
|
+
| **测试** | 深度综合测试v35 | `deep_api_tester_v35.py` | `core/deep_api_tester_v35.py` |
|
|
1481
|
+
|
|
1482
|
+
### Base Path获取完整流程
|
|
1483
|
+
|
|
1484
|
+
```
|
|
1485
|
+
【优先级1】从JS配置中获取
|
|
1486
|
+
├── axios.create配置中的baseURL值
|
|
1487
|
+
├── VUE_APP_API环境变量
|
|
1488
|
+
└── process.env.APP_API配置
|
|
1489
|
+
|
|
1490
|
+
【优先级2】从nginx反向代理推断
|
|
1491
|
+
├── 响应头Server字段分析
|
|
1492
|
+
├── 从已发现API路径反推父路径
|
|
1493
|
+
└── get_base_path_candidates(discovered_path)
|
|
1494
|
+
|
|
1495
|
+
【优先级3】使用base_path_dict字典
|
|
1496
|
+
├── COMMON_API_PREFIXES: ["/api", "/webapi", "/auth", ...]
|
|
1497
|
+
├── generate_fuzz_paths(api, prefixes)
|
|
1498
|
+
└── 对每个候选路径进行测试验证
|
|
1499
|
+
|
|
1500
|
+
【使用示例】
|
|
1501
|
+
from core.utils.base_path_dict import get_base_path_candidates, generate_fuzz_paths
|
|
1502
|
+
|
|
1503
|
+
# 从发现的API路径获取候选base_path
|
|
1504
|
+
candidates = get_base_path_candidates("/api/v1/user/login")
|
|
1505
|
+
# 结果: ["/api/v1", "/api", "/"]
|
|
1506
|
+
|
|
1507
|
+
# 生成fuzzing路径
|
|
1508
|
+
fuzz_paths = generate_fuzz_paths("user/login")
|
|
1509
|
+
# 结果: ["/api/user/login", "/webapi/user/login", ...]
|
|
1510
|
+
```
|
|
1511
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
1512
|
+
│ 阶段1: 基础探测 │
|
|
1513
|
+
├─────────────────────────────────────────────────────────────┤
|
|
1514
|
+
│ 1. HTTP探测: curl -I http://target.com │
|
|
1515
|
+
│ 2. 技术栈: 检查HTML中Vue/React/Angular标识 │
|
|
1516
|
+
│ 3. 判断SPA: /api/* 返回HTML → SPA应用 │
|
|
1517
|
+
└─────────────────────────────────────────────────────────────┘
|
|
1518
|
+
↓
|
|
1519
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
1520
|
+
│ 阶段2: JS采集(必须使用Playwright) │
|
|
1521
|
+
├─────────────────────────────────────────────────────────────┤
|
|
1522
|
+
│ 1. 启动浏览器: sync_playwright() │
|
|
1523
|
+
│ 2. 访问目标: page.goto(url, wait_until="networkidle") │
|
|
1524
|
+
│ 3. 等待加载: page.wait_for_timeout(5000) │
|
|
1525
|
+
│ 4. 提取JS: re.findall(r'<script[^>]+src=["\']([^"\']+)') │
|
|
1526
|
+
└─────────────────────────────────────────────────────────────┘
|
|
1527
|
+
↓
|
|
1528
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
1529
|
+
│ 阶段3: JS深度分析(必须分析每个JS文件) │
|
|
1530
|
+
├─────────────────────────────────────────────────────────────┤
|
|
1531
|
+
│ 1. baseURL配置: │
|
|
1532
|
+
│ patterns: │
|
|
1533
|
+
│ - r'baseURL\s*[:=]\s*["\']([^"\']+)["\']' │
|
|
1534
|
+
│ - r'axios\.create\s*\(\s*\{([^}]+)\}' │
|
|
1535
|
+
│ 关键发现: baseURL:"" 为空 → 相对路径 │
|
|
1536
|
+
│ │
|
|
1537
|
+
│ 2. API路径: │
|
|
1538
|
+
│ patterns: │
|
|
1539
|
+
│ - r'["\'](/(?:user|auth|admin|login)[^"\']*)["\']' │
|
|
1540
|
+
│ - r'axios\.[a-z]+\(["\']([^"\']+)["\']' │
|
|
1541
|
+
│ │
|
|
1542
|
+
│ 3. 环境变量: │
|
|
1543
|
+
│ patterns: │
|
|
1544
|
+
│ - r'VUE_APP_\w+' │
|
|
1545
|
+
│ - r'process\.env\.(\w+)' │
|
|
1546
|
+
└─────────────────────────────────────────────────────────────┘
|
|
1547
|
+
↓
|
|
1548
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
1549
|
+
│ 阶段4: API测试 │
|
|
1550
|
+
├─────────────────────────────────────────────────────────────┤
|
|
1551
|
+
│ 1. 逐个测试发现的API端点 │
|
|
1552
|
+
│ 2. GET: 检查Content-Type → JSON=真实API, HTML=SPA路由 │
|
|
1553
|
+
│ 3. POST: 测试登录接口 → SQL注入/XSS │
|
|
1554
|
+
│ 4. 记录: 401/403=需认证, 200+JSON=检查是否未授权 │
|
|
1555
|
+
└─────────────────────────────────────────────────────────────┘
|
|
1556
|
+
↓
|
|
1557
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
1558
|
+
│ 阶段5: 漏洞验证(10维度) │
|
|
1559
|
+
├─────────────────────────────────────────────────────────────┤
|
|
1560
|
+
│ □ 维度1: 响应类型 □ 维度2: 状态码 □ 维度3: 响应长度 │
|
|
1561
|
+
│ □ 维度4: WAF拦截 □ 维度5: 敏感信息 □ 维度6: 一致性 │
|
|
1562
|
+
│ □ 维度7: SQL注入 □ 维度8: IDOR □ 维度9: 认证绕过 │
|
|
1563
|
+
│ □ 维度10: 信息泄露 │
|
|
1564
|
+
└─────────────────────────────────────────────────────────────┘
|
|
1565
|
+
```
|
|
1566
|
+
|
|
1567
|
+
### 关键配置发现对照表
|
|
1568
|
+
|
|
1569
|
+
| baseURL值 | 含义 | 架构 |
|
|
1570
|
+
|-----------|------|------|
|
|
1571
|
+
| `""` (空) | 相对路径 | nginx反向代理到后端 |
|
|
1572
|
+
| `"https://api.xxx.com"` | 绝对路径 | 前端直接调用独立API |
|
|
1573
|
+
| 不存在 | 同源请求 | 后端在同一域名下 |
|
|
1574
|
+
|
|
1575
|
+
### 调用原则
|
|
1576
|
+
|
|
1577
|
+
```
|
|
1578
|
+
1. 按需选择:不是所有模块都要用
|
|
1579
|
+
2. 动态调整:根据目标调整测试策略
|
|
1580
|
+
3. 灵活组合:发现问题时追加测试模块
|
|
1581
|
+
4. 渐进式:先轻量后深度
|
|
1582
|
+
5. 自主编写:特殊情况下可直接编写测试脚本
|
|
1583
|
+
6. 扩展能力:基于能力池编写扩展脚本
|
|
1584
|
+
7. 验证优先:发现异常先验证再报告
|
|
1585
|
+
```
|
|
1586
|
+
|
|
1587
|
+
### 能力输入输出规范
|
|
1588
|
+
|
|
1589
|
+
**采集能力:**
|
|
1590
|
+
```
|
|
1591
|
+
http_client: 输入{url, method, headers, body} → 输出{status, headers, body, elapsed}
|
|
1592
|
+
js_parser: 输入{html, js_urls, base_url} → 输出{api_patterns, base_urls,tokens, endpoints}
|
|
1593
|
+
browser_collect: 输入{url, wait_until, interact} → 输出{apis, storage, forms, page_title}
|
|
1594
|
+
```
|
|
1595
|
+
|
|
1596
|
+
**分析能力:**
|
|
1597
|
+
```
|
|
1598
|
+
response_analyzer: 输入{response, expected_type} → 输出{type, is_suspicious,sensitive_fields, parsed_json}
|
|
1599
|
+
sensitive_finder: 输入{content, check_fields} → 输出{found, severity}
|
|
1600
|
+
```
|
|
1601
|
+
|
|
1602
|
+
**测试能力:**
|
|
1603
|
+
```
|
|
1604
|
+
sqli_tester: 输入{target_url, method, param_name, payloads} → 输出{vulnerable, payload_used, error_detected}
|
|
1605
|
+
idor_tester: 输入{target_url, param_name, test_ids, auth_token} → 输出{vulnerable, leaked_ids, severity}
|
|
1606
|
+
auth_tester: 输入{login_url, test_mode, max_attempts} → 输出{vulnerable, bypass_payload, weak_credential}
|
|
1607
|
+
```
|
|
1608
|
+
|
|
1609
|
+
**验证能力:**
|
|
1610
|
+
```
|
|
1611
|
+
vuln_verifier: 输入{type, original_request, suspicious_response} → 输出{verified, is_false_positive, reason, dimensions}
|
|
1612
|
+
```
|
|
1613
|
+
|
|
1614
|
+
### 能力组合模式
|
|
1615
|
+
|
|
1616
|
+
```
|
|
1617
|
+
SPA应用:browser_collect → api_parser → idor_tester → vuln_verifier (10维度验证)
|
|
1618
|
+
传统Web:http_client → js_parser → sqli_tester → vuln_verifier
|
|
1619
|
+
高安全目标:browser_collect → response_analyzer → fuzz_tester (低速) → vuln_verifier
|
|
1620
|
+
快速扫描:http_client → response_analyzer → sqli_tester → vuln_verifier
|
|
1621
|
+
```
|
|
1622
|
+
|
|
1623
|
+
---
|
|
1624
|
+
|
|
1625
|
+
## examples/ 目录结构
|
|
1626
|
+
|
|
1627
|
+
```
|
|
1628
|
+
examples/ # 组合示例
|
|
1629
|
+
├── usage-examples.md # 基础使用示例
|
|
1630
|
+
├── target-based-combos.md # 按目标组合示例
|
|
1631
|
+
│ ├── 示例1: SPA应用完整测试链
|
|
1632
|
+
│ ├── 示例2: 传统Web API快速扫描
|
|
1633
|
+
│ ├── 示例3: 高安全性目标测试
|
|
1634
|
+
│ ├── 示例4: 按漏洞类型选择能力
|
|
1635
|
+
│ └── 示例5: 自定义能力组合
|
|
1636
|
+
└── vulnerability-chain.md # 攻击链组合
|
|
1637
|
+
```
|
|
1638
|
+
|
|
1639
|
+
### 按目标类型组合
|
|
1640
|
+
|
|
1641
|
+
| 目标 | 发现 | 分析 | 测试 | 验证 |
|
|
1642
|
+
|------|------|------|------|------|
|
|
1643
|
+
| SPA应用 | browser_collect | api_parser, response_analyzer | idor_tester, sqli_tester | vuln_verifier (10维度) |
|
|
1644
|
+
| 传统Web | http_client, js_parser | api_parser | sqli_tester, auth_tester | vuln_verifier |
|
|
1645
|
+
| 高安全目标 | browser_collect | response_analyzer | fuzz_tester (低速) | response_diff |
|
|
1646
|
+
| 快速扫描 | http_client | response_analyzer | sqli_tester | vuln_verifier |
|
|
1647
|
+
| GraphQL | browser_collect | graphql_parser | sqli_tester (GraphQL专用) | vuln_verifier |
|
|
1648
|
+
|
|
1649
|
+
---
|
|
1650
|
+
|
|
1651
|
+
## references/ 目录结构
|
|
1652
|
+
|
|
1653
|
+
```
|
|
1654
|
+
references/ # 参考资料
|
|
1655
|
+
├── rest-guidance.md # REST API测试指导
|
|
1656
|
+
├── graphql-guidance.md # GraphQL测试指导
|
|
1657
|
+
├── severity-model.md # 漏洞评级模型
|
|
1658
|
+
├── validation.md # 验证方法论
|
|
1659
|
+
├── asset-discovery.md # 资产发现指导
|
|
1660
|
+
├── test-matrix.md # 测试矩阵
|
|
1661
|
+
└── report-template.md # 报告模板
|
|
1662
|
+
```
|
|
1663
|
+
|
|
1664
|
+
---
|
|
1665
|
+
|
|
1666
|
+
## resources/ 目录结构
|
|
1667
|
+
|
|
1668
|
+
```
|
|
1669
|
+
resources/ # 资源文件
|
|
1670
|
+
├── sqli.json # SQL注入Payload库
|
|
1671
|
+
├── xss.json # XSS Payload库
|
|
1672
|
+
└── dom_xss.json # DOM XSS Payload库
|
|
1673
|
+
```
|
|
1674
|
+
|
|
1675
|
+
---
|
|
1676
|
+
|
|
1677
|
+
## templates/ 目录结构
|
|
1678
|
+
|
|
1679
|
+
```
|
|
1680
|
+
templates/ # 测试模板
|
|
1681
|
+
├── api_test.yaml # API测试模板
|
|
1682
|
+
├── auth_test.yaml # 认证测试模板
|
|
1683
|
+
└── vuln_scan.yaml # 漏洞扫描模板
|
|
1684
|
+
```
|
|
1685
|
+
|
|
1686
|
+
---
|
|
1687
|
+
|
|
1688
|
+
完成测试后,按以下格式报告:
|
|
1689
|
+
|
|
1690
|
+
```markdown
|
|
1691
|
+
## 测试概要
|
|
1692
|
+
|
|
1693
|
+
| 项目 | 数量 |
|
|
1694
|
+
|------|------|
|
|
1695
|
+
| 扫描目标 | xxx |
|
|
1696
|
+
| 发现可疑点 | x |
|
|
1697
|
+
| 验证确认 | x |
|
|
1698
|
+
| 排除误报 | x |
|
|
1699
|
+
|
|
1700
|
+
## 能力使用记录
|
|
1701
|
+
|
|
1702
|
+
| 阶段 | 使用能力 | 输入 | 输出 |
|
|
1703
|
+
|------|----------|------|------|
|
|
1704
|
+
| 采集 | browser_collect | url=xxx | apis=[...] |
|
|
1705
|
+
| 分析 | response_analyzer | status=200, body=... | type=json |
|
|
1706
|
+
| 测试 | idor_tester | userId=[1,2] | vulnerable=true |
|
|
1707
|
+
| 验证 | vuln_verifier (10维度) | type=idor | verified=true |
|
|
1708
|
+
|
|
1709
|
+
## 漏洞列表
|
|
1710
|
+
|
|
1711
|
+
| 编号 | 类型 | 严重性 | 端点 | PoC | 验证维度 |
|
|
1712
|
+
|------|------|--------|------|-----|---------|
|
|
1713
|
+
| 1 | 敏感信息泄露 | HIGH | /api/user/info | GET /api/user/info 返回password字段 | 维度1,5,10 |
|
|
1714
|
+
| 2 | IDOR | HIGH | /api/order/list | GET /api/order/list?userId=123 | 维度1,3,6,8 |
|
|
1715
|
+
|
|
1716
|
+
## 验证维度详情
|
|
1717
|
+
|
|
1718
|
+
| 漏洞 | 维度1响应类型 | 维度3长度 | 维度5敏感信息 | 维度8业务数据 |
|
|
1719
|
+
|------|-------------|---------|-------------|-------------|
|
|
1720
|
+
| #1 | json ✓ | 正常 ✓ | password泄露 ✓ | - |
|
|
1721
|
+
| #2 | json ✓ | 正常 ✓ | - | userId泄露 ✓ |
|
|
1722
|
+
|
|
1723
|
+
## 误报记录
|
|
1724
|
+
|
|
1725
|
+
| 可疑点 | 初步判断 | 验证维度 | 排除原因 |
|
|
1726
|
+
|--------|----------|----------|----------|
|
|
1727
|
+
| /api/admin/users返回200 | 可能未授权 | 维度1,4,6 | 返回HTML页面+WAF特征,是WAF拦截页 |
|
|
1728
|
+
|
|
1729
|
+
## 漏洞链构造
|
|
1730
|
+
|
|
1731
|
+
### 攻击链1
|
|
1732
|
+
1. 用户枚举:GET /api/user/check?phone=138xxx → 获取userId
|
|
1733
|
+
2. 订单查询:GET /api/order/list?userId=xxx → 获取orderNo
|
|
1734
|
+
3. 退款操作:POST /api/refund?orderNo=xxx&amount=0.01 → 退款成功
|
|
1735
|
+
|
|
1736
|
+
## 修复建议
|
|
1737
|
+
|
|
1738
|
+
1. 删除响应中的password字段
|
|
1739
|
+
2. 添加userId归属校验
|
|
1740
|
+
3. 退款接口添加权限校验
|
|
1741
|
+
```
|
|
1742
|
+
|
|
1743
|
+
---
|
|
1744
|
+
|
|
1745
|
+
## 总结
|
|
1746
|
+
|
|
1747
|
+
### 核心思维
|
|
1748
|
+
|
|
1749
|
+
1. **不只是测试,要理解** - 理解接口在做什么
|
|
1750
|
+
2. **不只是单个漏洞,要构造链** - 发现一个点,思考能做什么
|
|
1751
|
+
3. **不只是工具,要用脑子** - 思考攻击者会怎么做
|
|
1752
|
+
4. **不只是发现,要验证** - 确认漏洞真实存在(10维度验证)
|
|
1753
|
+
5. **不只是利用,要闭环** - 发现→分析→验证→确认/排除
|
|
1754
|
+
|
|
1755
|
+
### 检测口诀
|
|
1756
|
+
|
|
1757
|
+
```
|
|
1758
|
+
看到接口想认证
|
|
1759
|
+
看到认证想绕过
|
|
1760
|
+
看到数据想遍历
|
|
1761
|
+
看到金额想篡改
|
|
1762
|
+
看到用户想枚举
|
|
1763
|
+
看到订单想越权
|
|
1764
|
+
看到token想泄露
|
|
1765
|
+
看到修改想权限
|
|
1766
|
+
看到异常想验证
|
|
1767
|
+
看到200想确认
|
|
1768
|
+
```
|
|
1769
|
+
|
|
1770
|
+
### 验证口诀(10维度)
|
|
1771
|
+
|
|
1772
|
+
```
|
|
1773
|
+
维度1看类型:JSON业务HTML拦截
|
|
1774
|
+
维度2看状态:200成功4xx客户端
|
|
1775
|
+
维度3看长度:过短拦截过长数据
|
|
1776
|
+
维度4看WAF:安全设备特征识别
|
|
1777
|
+
维度5看敏感:password token secret
|
|
1778
|
+
维度6看一致:多次请求是否同
|
|
1779
|
+
维度7SQL注入:错误特征要确认
|
|
1780
|
+
维度8用户数据:业务信息才真实
|
|
1781
|
+
维度9认证绕过:token返回才算
|
|
1782
|
+
维度10信息泄露:非公开信息才算
|
|
1783
|
+
```
|
|
1784
|
+
|
|
1785
|
+
---
|
|
1786
|
+
|
|
1787
|
+
## 参考资源
|
|
1788
|
+
|
|
1789
|
+
如有疑问,可参考:
|
|
1790
|
+
- OWASP API Security Top 10 - `references/`
|
|
1791
|
+
- REST API测试指导 - `references/rest-guidance.md`
|
|
1792
|
+
- GraphQL测试指导 - `references/graphql-guidance.md`
|
|
1793
|
+
- 漏洞评级模型 - `references/severity-model.md`
|
|
1794
|
+
- 验证方法论 - `references/validation.md`
|
|
1795
|
+
- Payload库 - `resources/*.json`
|
|
1796
|
+
- 测试模板 - `templates/*.yaml`
|
|
1797
|
+
- 使用示例 - `examples/`
|