reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,155 @@
# 客户端 / 现代 Web 靶场 Playbook(DOM XSS · 原型污染 · agent-browser)
> 来源:Gin & Juice / Juice Shop 类合法靶场实战摩擦(2026-07)
> 适用:PortSwigger scanner-eval、OWASP Juice Shop、BB 前端面
> **MUST** 先 scope + case-guard;命中≠打穿
## 0. 何时读本文件
```text
□ 页面有大量前端 JS(React/Angular/Vue)
□ 漏洞清单写着 DOM XSS / prototype pollution / CSTI
□ curl 只能摸到 API,需要浏览器确认 sink
□ Windows 上 URL 带 [] 被 curl 吃掉(见下)
```
## 1. Windows curl 坑(`[]` 被当范围)
**错误:**
```bash
curl "https://target/?__proto__[x]=1" # Windows curl: bad range in position ...
```
**正确(必须):**
```bash
curl.exe --globoff -sS "https://target/?__proto__[test]=polluted"
curl.exe --globoff -sS -G "https://target/catalog" --data-urlencode "__proto__[test]=polluted"
```
PowerShell 里优先:
```powershell
curl.exe --globoff -sS --data-urlencode "q=test" "https://target/search"
```
## 2. 三阶段:Surface → Sink → Chain
| 阶段 | 做什么 | 产出 |
|------|--------|------|
| Surface | 抓 HTML/JS,列 src、表单 action、API | `recon/js-urls.txt` |
| Sink | 搜 `innerHTML` / `eval` / `location.hash` / `document.write` / `__proto__` | 候选 sink 列表 |
| Chain | 找可控 source 能否到 sink(需 200 非数字 / 未转义反射 / merge 对象) | E-* + 是否 validated |
### 2.1 静态 sink 扫(本机)
```powershell
# 下载页面脚本后
rg -n "innerHTML|outerHTML|document\.write|eval\(|location\.hash|__proto__|parseFromString" recon\js\
```
### 2.2 agent-browser 最小环
```powershell
agent-browser open "https://target/page"
agent-browser wait 2000
agent-browser snapshot -i
agent-browser screenshot work\case\screenshots\page.png
agent-browser eval "document.getElementById('stockCheckResult')?.innerHTML"
agent-browser close
```
**纪律:**
```text
□ 每次页面变化后重新 snapshot(ref 会失效)
□ 用 eval 验证 sink,不要只靠猜
□ 截图进 evidence/ 或 screenshots/
```
## 3. DOM XSS:库存类 `innerHTML = fetchBody` 模式
典型代码(Gin & Juice 类):
```javascript
fetch(path, { method, headers: { 'Content-Type': window.contentType }, body: payload(data) })
.then(res => res.status === 200
? res.text().then(t => isNaN(t) ? t : t + " units")
: "Could not fetch stock levels!")
.then(res => document.getElementById("stockCheckResult").innerHTML = res)
```
**门闩:**
| 条件 | 结果 |
|------|------|
| status ≠ 200 | 固定错误文案,**无 XSS** |
| status = 200 且 body 为数字 | 显示 `N units`,**无 XSS** |
| status = 200 且 body 非数字 | **raw HTML → sink** |
**验证 sink(浏览器):**
```javascript
// agent-browser eval
var el = document.getElementById('stockCheckResult');
el.innerHTML = '<b id=xssmark>SINK</b>';
!!document.getElementById('xssmark'); // true => sink 实锤
```
**利用前提:** 找到使 API **200 + 非数字 body** 的输入(XXE 回显、错误被错误配置成 200、开放代理等)。
**没到利用仍要写 Evidence:** `status=observed`,写清门闩,避免假阳性「已 XSS」。
## 4. 原型污染(快检)
```powershell
# URL 编码括号,且 --globoff
curl.exe --globoff -sS "https://target/?__proto__%5Bpolluted%5D=yes"
# 浏览器
agent-browser open "https://target/?__proto__%5Bpolluted%5D=yes"
agent-browser eval "({}.polluted || Object.prototype.polluted || 'not-polluted')"
```
```text
□ not-polluted → 该路由没有浅合并 gadget,换 hash/postMessage/库入口
□ polluted → 继续找 gadgets(script src、transport_url、isAdmin 等)
```
## 5. 公共 demo 不稳时
```text
□ Heroku demo 503 → 换本地 Docker / 另一合法靶 / 缩小请求速率
□ Docker Desktop 已安装但 daemon 未 ready → 等引擎或跳过本地容器,记入 timeline
□ 公开实例限流 → 优先读 JS 静态面,少打爆破
```
## 6. Evidence 写法(防误报)
```text
validated: 可复现利用(弹窗/读文件/越权成功)+ repro_command
observed: sink/面存在,门闩未过(如仅 innerHTML 赋值能力、实体被拦)
```
```powershell
powershell -File skills\scripts\append-evidence.ps1 -CaseRoot work\case `
-Id E-005 -Title "DOM XSS sink: #el.innerHTML = apiBody" `
-ReproCommand "agent-browser eval ..." -Severity medium -Status observed `
-RawExcerpt "status===200 && !isNaN gate"
```
## 7. 与其他 skill
| 发现 | 交接 |
|------|------|
| 前端签名/加密参数 | `js-reverse/` |
| 复杂 SPA 交互验证 | `browser-automation/` |
| BOLA 已登录 API | `api-security/` |
## 8. 诚实完成标准
```text
□ 未打穿 ≠ skill 无效:必须留下 surface + sink + 失败原因
□ 禁止把 observed sink 写成 validated exploit
□ timeline 写清:公网 demo 挂了 / Docker 未起 / curl [] 坑
```