当密码重置成功,但攻击者从未离开。
一个针对单一漏洞类别的本地红/蓝实验室:凭证的生命周期超出了本应终结它的事件。 它提供了漏洞利用、根本原因、修复方案、三规则检测包、针对规则在结构上无法看到的内容的状态审计、一个取证控制台——以及那条不起作用的检测规则,保留在仓库中以便演示其失败。
同一攻击。同样的请求。唯一的区别。
由 scripts/figures.py 根据控制台绘制的同一载荷生成——在 CI 中重新生成并比对差异,因此图表不会与代码脱节。
09:00 alice logs in ┐ refresh credential rt-001 │ the attacker steals rt-001 ┘
10:00 alice changes her password ← the one thing a victim can do alone HTTP 200 · password changed · fresh session issued
10:00:03 attacker: POST /refresh rt-002 → HTTP 200 new access credential at-004, issued 10:00:03
10:01:00 attacker: GET /me at-004 → HTTP 200 {"username": "alice", "authenticated": true}
没有错误。没有异常。没有可计数的失败认证。攻击者的访问凭证*只有三秒大*,并且是由服务器在重置后根据请求生成的。
以下是整个漏洞:```python
def _revoke_for_security_change(self, user, kind, device_id):
if device_id:
revoke_credentials(user, device_id=device_id) # ← the finding
以审阅者的方式去读。撤销逻辑就在那里。它用正确的范围调用了正确的函数。它周围的端点更新了密码哈希,返回 200,并签发了一个新的会话——一次正确的密码更改所应具备的每一个可观察行为都出现了。
而如果调用方省略了 device_id,则什么都不会被撤销,而端点仍然报告成功。
这不是假设。这就是
CVE-2026-22706
在 Strapi ≤ 5.33.2 中的情况,其中刷新令牌失效步骤取决于调用方提供的 deviceId。评分为 2.1,低危。讨论见
下文。
评分之所以低,是因为攻击者已经拥有访问权限——这是进入条件,而这个漏洞并没有授予任何新的东西。它授予的是持续时间,并且是通过破坏受害者自己能够操作的唯一控制来实现的。
test_persistence_lasts_as_long_as_the_refresh_credential 模拟了七天的时间来展示这一点。遏制路径中的低危漏洞比功能路径中的低危漏洞代价更高,因为代价是在事件期间付出的,而那时没人在读安全公告。
你最先写下的规则:```text IF credential.issued_at < credential_change.timestamp: ALERT
这不是一条愚蠢的规则。它成本低,只需要一个字段,读起来就像问题的定义,而且**在简单情况下是正确的**——攻击者在重置后使用窃取的*访问*令牌会被抓住。
`test_the_naive_rule_catches_the_simple_case` 断言它有效。
两条规则针对同一凭证提出同一个问题。它们读取不同的字段来回答,而这两个字段相互矛盾:

**三秒之后,还是一小时之前——同一凭证,同一时刻。** 朴素规则询问的是攻击者控制的字段,而一次 `POST /refresh` 就能将其重置。
在请求日志上运行它,这才是这个查询实际被写入的地方,因为请求日志才是你拥有的东西:```text
NAIVE DETECTOR (NAIVE-001), over the request log
Result: NO ALERT
Six requests were served to the attacker after the reset. Every one of them
carried at-004, minted at 10:00:03 -- three seconds *after* the password
change. By its own timestamp it is the newest credential on the account.
就此止步固然轻松,却不诚实,因此实验室还运行了最公平版本的朴素规则——将其扩展至同时监控刷新端点:```text NAIVE DETECTOR, widened to include POST /refresh
1 alert at 2026-09-11T10:00:03.000Z: the credential presented to /refresh was rt-002, issued 2026-09-11T09:30:00.000Z. Then it goes blind. 6 events follow that hop and it flags none of them, because every credential from there on carries a post-reset timestamp. Its incident covers 1 accepted request; the lineage rule's covers all of them.
And look at what the alert names: NAIVE-001 revoke rt-002 -- rotated away and already dead at 10:00:03 AFTERLIFE-001 revoke lin-001 -- the live thing every future credential descends from
真正重要的是凌晨三点时的差异。朴素规则只捕捉到调用链越过边界的那一瞬间,随后在剩下的29天里丢失了线索——而它所指认的凭证*早已被服务器轮换并吊销*。吊销它毫无意义。`lin-001` 才是你必须清除的对象。
**而且朴素规则并不缺乏遥测数据。** 它使用相同的事件流、相同的血缘索引、相同的容差、相同的去重机制和相同的有限状态。它只覆盖了一个方法:```python
class Correlator: # AFTERLIFE-001
def _age_reference(self, facts):
return facts.root_issued_at
class NaiveCorrelator(Correlator): # NAIVE-001
def _age_reference(self, facts):
return facts.issued_at
root_issued_at 就位于它已经在查询的索引中。
test_the_naive_rule_had_the_data_it_needed 证明了这一点。问题出在
比较上,而不是日志记录。
三条规则作用于同一份日志。它们回答不同的问题,并且按照事件实际展开的 顺序触发。
10:00:00 HIGH AFTERLIFE-003 Incomplete revocation at a security change 10:00:03 HIGH AFTERLIFE-001 Post-revocation credential lineage use
**这种排序是这个仓库中最有用的东西。** AFTERLIFE-003
在变更落地的瞬间触发,比攻击者触碰任何东西早三秒,因为它所需的证据已经完整:日志说明了哪些谱系在进入时是活跃的,并且没有说明它们已被撤销。
它不需要受害者,也不需要利用。它会在任何用户执行的第一次密码重置时报告该缺陷——这使它成为你在预发布环境中运行的那一个,那里没有攻击者需要等待。AFTERLIFE-001 告诉你入侵正在进行;AFTERLIFE-003 告诉你你的遏制控制已失效。

`application recorded watermark: no` 是引导事件响应人员指向*缺陷*而非症状的字段。
### 规则使用的水印不是应用程序报告的那个
凭据变更事件携带一个 `revocation_watermark` 字段——即应用程序写入的 `credentials_valid_after` 值。**在易受攻击的实现中它是 `null`,因为应用程序从未写入过。** 这就是那个 bug。
因此,以该字段为键的规则将恰好对它存在所要捕获的情况视而不见。规则锚定在事件自身的 `timestamp` 上,无论应用程序是否履行了职责,该时间戳都是真实的,并将缺失的字段作为证据报告。
### 属性```text
deduplication 6 accepted requests on the stale lineage -> 1 alert
event order shuffled stream -> same alert (1 alert)
duplicate telemetry log replayed twice -> 1 alert (24 duplicate events discarded)
false positives the fixed implementation's log -> 0 alerts
bounded state caps at 256 activity/user, 2000 users, 20000 credentials
顺序无关性不是“基本能用”:
test_6b_every_permutation_of_the_critical_events_detects 会运行四个关键事件的全部 24 种排列,并要求每种排列恰好产生一个告警。
去重以 (user_id, credential_change_event_id, lineage_id) 为键,
并在其前面加上 event_id 抑制,这样重放的文件就无法虚增计数。
完整规则卡片、所需遥测数据和响应运行手册: docs/detection.md。
一个用于回答本实验所关注的那个问题的阅读界面。不是告警计数的仪表盘——而是一个死亡登记册。每个凭据一根条形,从签发到死亡,按其所继承的血统分组,密码更改被画成一条线,之前的一切本应终止于此。
一个刻意的反转:温暖意味着存活,而过了那条线之后,温暖就是错的。 在大多数安全 UI 中,红色意味着发生了错误。这里没有任何东西出错——漏洞运行中的每个请求都返回 200。因此颜色遵循的是死亡:冷色是按要求死去的凭据,暖色是仍在呼吸的凭据,而过了断头台之后,仍然温暖就是整个发现所在。(BLACKOUT 设定了同样的约定,在那里 200 才是红色的那个。)
那些细小的垂直下落线是谱系:一个子凭据在那一刻从其父凭据铸造出来。rt-001 → rt-002 → rt-004 在整个窗口内向右下方逐级递进,而在漏洞模式下,它在切割之后仍在继续递进——这正是某个血统在其自身灭绝事件的另一侧铸造新凭据的画面。```bash
python scripts/lab.py console
写入 **[`docs/console-preview.html`](https://github.com/het-p301204/afterlife/blob/main/docs/console-preview.html)** —— 一个
自包含的 74 KiB 文件,两次运行结果均已内置。无需服务器、无需网络、无需
获取字体;直接从文件系统打开即可。或运行实时版本:```bash
python -m console
将滚动条拖回 10:00:00 之前,再向前拖过它:当日志足以支撑时,发现项就会出现,AFTERLIFE-003 在变更时出现,AFTERLIFE-001 在三秒后出现。设计推理,包括被删减的内容,见
docs/console-design.md。
该控制台在构造上就是只读的。它重新运行已完成的情景并绘制它们;它无法切换实现、移动时钟或撤销任何内容。
test_the_console_has_no_control_surface断言唯一的非 GET 路由是/api/rebuild。一个能够改变其所读取内容的读取界面,是你无法信任的。
六个包,一个安全类,无基础设施。```text
app/ the lab application
config.py mode selection; defaults to fixed, deliberately
store.py SQLite credential state + the security-change audit trail
tokens.py minting and decoding; a JWT is a signed pointer to a row
auth.py login / refresh / change-password + THE BUG + the audit
main.py six endpoints
common/ clock.py a rewindable UTC clock, so an hour of history costs nothing events.py the event vocabulary, shared by app and detector telemetry.py JSONL emission with credential-name redaction
detector/ strictly downstream: reads a log file, decides nothing base.py the alert shape, replay suppression, bounded state lineage.py rebuilds a credential's ancestry from issuance events ledger.py which lineages are alive, per user rules.py AFTERLIFE-001 persistence reuse.py AFTERLIFE-002 theft containment.py AFTERLIFE-003 the defect itself naive.py NAIVE-001, kept in order to be demonstrated failing audit.py the state scan the rules structurally cannot do engine.py the pack: one shared index, one stream, ranked alerts tail.py byte-offset JSONL tailer
console/ the mortality register payload.py one run, shaped for drawing static/ ~1400 lines of vanilla HTML/CSS/JS, no build step
scripts/ lab.py the demonstration scenarios.py nine scenarios x both implementations report.py the incident report preview.py bake the offline console figures.py render the console to SVG for this README
tests/ 290 tests
该应用在演示、控制台和测试中均以**进程内**方式运行。没有端口,没有开发服务器,没有 Docker。时钟被固定,因此每次运行都是确定性的,提交的遥测数据、控制台输出、图表和报告在多次运行之间都是字节级一致的——CI 通过 `git diff --exit-code` 来检查这一点。
### 服务端强制执行
凭证是一**行**,而不是一个字符串。客户端持有的 JWT 携带 `cid`——一个查找键——由该行决定凭证是否有效。
过期时间是根据该行的 `expires_at` 来检查的,而不是根据持有者出示的 `exp` 声明。两个时间声明都以 `verify=False` 交给 PyJWT,在这里这意味着*“服务器自行检查”*,而 [`app/auth.py`](https://github.com/het-p301204/afterlife/blob/main/app/auth.py) 确实在每个请求上都这样做。客户端永远无权决定自己的凭证是否仍然有效。
---
## 攻击时间线```mermaid
flowchart TD
A["Account compromised<br/><i>phishing · XSS · stolen backup</i>"] --> B["Attacker holds refresh credential rt-001<br/>lineage lin-001, root sess-001 @ 09:00"]
B --> C["Legitimate password change @ 10:00<br/>HTTP 200 · password hash updated"]
C --> D{"device_id supplied?"}
D -->|"yes"| E["revoke_credentials(user, device_id)<br/>rt-001 revoked"]
D -->|"no — the exploit"| F["nothing revoked<br/>no watermark written"]
E --> G["Attacker refresh → 401<br/><b>contained</b>"]
F --> AF3["<b>AFTERLIFE-003 · HIGH</b> @ 10:00:00<br/>containment did not run<br/><i>no attacker action required</i>"]
F --> H["POST /refresh rt-002 → 200<br/>mints at-004 @ 10:00:03"]
H --> I["GET /me at-004 → 200<br/>well-formed · correctly signed · <b>no anomaly</b>"]
I --> J["at-004.issued_at > watermark<br/>NAIVE-001: no alert"]
I --> K["lineage lin-001 root @ 09:00 < watermark<br/><b>AFTERLIFE-001 · HIGH</b>"]
F --> L["attacker holds and never spends<br/>AFTERLIFE-001 silent — correctly<br/><b>state audit: dormant survivor</b>"]
style F fill:#7f1d1d,color:#fff
style H fill:#7f1d1d,color:#fff
style I fill:#7f1d1d,color:#fff
style J fill:#78350f,color:#fff
style K fill:#14532d,color:#fff
style AF3 fill:#14532d,color:#fff
style L fill:#1e3a5f,color:#fff
style E fill:#14532d,color:#fff
style G fill:#14532d,color:#fff
中间的刷新链分支才是关键所在。攻击者使用的不是旧凭证,而是一条旧的谱系,而这条谱系会按需铸造出新的东西。
一个会话是某条谱系的根。在其之下铸造的一切都将永远继承该根。```text sess-001 session lineage lin-001 root sess-001 issued 09:00:00 │ ├── rt-001 refresh parent sess-001 root_issued_at 09:00:00 │ └── at-001 access parent rt-001 root_issued_at 09:00:00 │ ├── rt-002 refresh parent rt-001 root_issued_at 09:00:00 ← 09:30 rotation │ └── at-002 access parent rt-002 root_issued_at 09:00:00 │ └── rt-004 refresh parent rt-002 root_issued_at 09:00:00 ← 10:00:03 rotation └── at-004 access parent rt-004 root_issued_at 09:00:00 issued_at 10:00:03
`at-004` 只有三秒大。它的血统已有一小时。两个事实都成立,
而只有一个在请求日志中可见。
两条不变量维系着这一切,且两者都经过测试:
1. **只有认证才会创建血统。** `Store.open_session` 是生成 `lineage_id` 的唯一
位置,并且它使会话成为自身的
`root_credential_id`。
2. **铸造会将根向下复制。** `TokenService.mint` 从父级读取血统字段
而不是重新计算它们,因此凭证无法获得比它所源自的登录
更新的血统。
持有者出示的令牌故意**不**携带其血统根。如果
携带了,持有者就可以对此撒谎。
---
## 状态审计
AFTERLIFE-001 在陈旧血统被*使用*时触发。对于
检测规则来说,这是正确的触发条件,但它留下了一个漏洞:**无人触碰的陈旧血统
对它来说是不可见的。** 攻击者窃取凭证、观察重置失败,
然后等待,不会产生任何可供关联的活动。
因此,实验室还提出了规则无法回答的问题:不是*发生了什么*,而是*什么
仍然存活*。```text
scenario: dormant-survivor (the attacker holds the credential and never spends it)
AFTERLIFE-001 silent — correct; nothing was accepted
AFTERLIFE-003 HIGH — the change revoked nothing
state audit 1 stale lineage, 1 dormant
# 扫描单个目标
python3 cve_2025_55182.py -t https://target.example.com
# 使用代理扫描
python3 cve_2025_55182.py -t https://target.example.com -p http://127.0.0.1:8080
# 从文件扫描多个目标
python3 cve_2025_55182.py -f targets.txt
# 使用自定义超时和线程数扫描
python3 cve_2025_55182.py -f targets.txt -T 15 -c 20
# 使用自定义载荷扫描
python3 cve_2025_55182.py -t https://target.example.com --payload "custom_payload_here"
# 使用自定义 User-Agent 扫描
python3 cve_2025_55182.py -t https://target.example.com -A "Mozilla/5.0 (Custom)"
# 使用代理和自定义线程数扫描多个目标
python3 cve_2025_55182.py -f targets.txt -p http://127.0.0.1:8080 -c 15 -T 20
# 使用自定义载荷和 User-Agent 扫描
python3 cve_2025_55182.py -t https://target.example.com --payload "custom_payload" -A "Custom-Agent/1.0"
# 使用详细输出扫描
python3 cve_2025_55182.py -t https://target.example.com -v
# 将结果保存到文件
python3 cve_2025_55182.py -f targets.txt -o results.txt
该工具通过以下方式检测 CVE-2025-55182:
该漏洞存在于 React Server Components 处理序列化数据的方式中。攻击者可以发送特制请求,导致服务器执行任意代码。
本工具仅供教育和道德安全测试目的使用。未经授权访问计算机系统是非法的。请务必:
作者对任何误用或由此造成的损害不承担责任。
本项目根据 MIT 许可证授权 - 有关详细信息,请参阅 LICENSE 文件。
欢迎贡献!请随时提交 Pull Request。
⭐ 如果您觉得这个工具有用,请在 GitHub 上给它一个星标!```bash python scripts/lab.py audit
## 使用示例
### 基本用法
```bash
# 扫描单个目标
python3 CVE-2025-55182.py -u https://example.com
# 扫描目标列表
python3 CVE-2025-55182.py -f targets.txt
# 使用自定义回调域名
python3 CVE-2025-55182.py -u https://example.com -c your-domain.com
# 使用自定义回调端口
python3 CVE-2025-55182.py -u https://example.com -p 8080
# 使用自定义回调路径
python3 CVE-2025-55182.py -u https://example.com -path /custom/path
# 使用自定义回调协议
python3 CVE-2025-55182.py -u https://example.com -proto https
# 使用自定义回调 URL
python3 CVE-2025-55182.py -u https://example.com -callback https://your-domain.com/callback
# 使用自定义 HTTP 方法
python3 CVE-2025-55182.py -u https://example.com -m POST
# 使用自定义 HTTP 头
python3 CVE-2025-55182.py -u https://example.com -H "User-Agent: Custom" -H "X-Forwarded-For: 127.0.0.1"
# 使用自定义 HTTP 数据
python3 CVE-2025-55182.py -u https://example.com -d "param1=value1¶m2=value2"
# 使用自定义 HTTP Cookie
python3 CVE-2025-55182.py -u https://example.com -c "session=abc123"
# 使用自定义 HTTP 代理
python3 CVE-2025-55182.py -u https://example.com -proxy http://127.0.0.1:8080
# 使用自定义 HTTP 超时
python3 CVE-2025-55182.py -u https://example.com -t 10
# 使用自定义 HTTP 重试次数
python3 CVE-2025-55182.py -u https://example.com -r 3
# 使用自定义 HTTP 重定向
python3 CVE-2025-55182.py -u https://example.com -redirect
# 使用自定义 HTTP 验证
python3 CVE-2025-55182.py -u https://example.com -verify
# 使用自定义 HTTP 详细输出
python3 CVE-2025-55182.py -u https://example.com -v
# 使用自定义 HTTP 静默模式
python3 CVE-2025-55182.py -u https://example.com -q
# 使用自定义 HTTP 输出文件
python3 CVE-2025-55182.py -u https://example.com -o output.txt
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f json
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f csv
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f xml
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f html
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f markdown
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f table
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f text
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f yaml
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f toml
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f ini
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f env
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f properties
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f sql
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f sqlite
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f mysql
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f postgresql
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f mongodb
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f redis
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f elasticsearch
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f cassandra
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f dynamodb
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f firebase
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f supabase
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f prisma
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f sequelize
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f typeorm
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f knex
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f mongoose
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f sqlalchemy
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f django
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f flask
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f fastapi
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f tornado
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f aiohttp
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f sanic
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f bottle
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f pyramid
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f web2py
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f cherrypy
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f falcon
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f hug
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f responder
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f starlette
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f uvicorn
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f gunicorn
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f waitress
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f hypercorn
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f daphne
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f meinheld
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f bjoern
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f cheroot
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f paste
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f waitress
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f twisted
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f cyclone
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f klein
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f nevow
# 使用自定义 HTTP 输出格式
python3 CVE-2025-55182.py -u https://example.com -f```text
VULNERABLE
server state 1 lineage(s) outlived the change (0 dormant)
telemetry 1 lineage(s) -- the same question, asked of the log instead of the database
lin-001 root 2026-09-11T09:00:00.000Z 7 credentials in use
FIXED
server state clean
telemetry clean
两个来源,刻意为之:遥测审计看到的是日志能够证明的内容,服务器状态审计看到的是数据库所相信的内容。当两者不一致时,日志就不是凭证状态的忠实记录,而建立在它之上的每一个检测都比表面看起来更脆弱——因此该命令会同时打印两者,并在它们不一致时明确说明。
服务器状态审计需要 security_changes 表,两种模式都会写入该表,因为记录变更已发生与对变更采取行动是两项独立的义务——而存在漏洞的实现恰好只满足其中一项。
针对两种实现共九个场景。python scripts/scenarios.py 会断言其自身的两个不变量,若任一被破坏则以非零状态退出。
有四行承载着论点:
legitimate-only 中根本没有攻击者。修复版不产生任何结果;存在漏洞的实现产生一个 LOW。这不是误报——它是 enumeration_only:撤销这一次奏效了,靠的是枚举,而没有任何水印来覆盖服务器已经遗忘的凭证。该规则包在无攻击者存在的情况下区分了两种实现。dormant-survivor 在一行中同时呈现了盲点及其答案:AFTERLIFE-001 静默,AFTERLIFE-003 HIGH,审计 dormant: 1。multi-device 是存在漏洞的实现看似有效的分支仍然失败的地方——撤销仅作用于笔记本电脑,另外两台设备未受影响。expired-lineage 是误报对照:一个 40 天前的会话,其凭证已自行过期,不是存活的持久化路径,也不会被报告为持久化路径。而该矩阵的核心主张,由脚本和 test_the_fix_never_produces_a_control_failure_finding 共同检验:修复版在任何场景中都不会产生控制失效发现。 AFTERLIFE-002 被允许通过——它报告的是盗窃,而非控制失效,而正确的实现仍然有盗窃需要报告。
一条在每次密码重置时都告警的规则会在一周内被静音,而被静音的规则比没有规则更糟——它是一条所有人都以为正在运行的规则。
每一行在
tests/test_detector_afterlife001.py 和
tests/test_detector_rulepack.py 中都有对应的测试。
关于 2 秒容差。 本实验中的每个时间戳都来自同一个进程和同一个时钟,因此诚实的容差应为零。2 秒是现实的双主机部署在 NTP 下所需要的,而且它比此攻击产生的时间间隔小三个数量级——刷新凭证的全部目的就是长期存活。该容差是一个窗口,在其中真正陈旧的谱系会被忽略,因此它被刻意保持得很小:
test_12b_a_gap_beyond_the_tolerance_does_alert 固定了 2.1 秒仍会触发。
self.store.set_watermark(user.user_id, moment) # the guarantee revoked = self.store.revoke_credentials(user.user_id, ...) # defence in depth
两者都不依赖 `device_id`。它仅作为上下文被记录,对爆炸半径没有任何影响。
**水印是架构层面的保证。** 每个用户一个时间戳,即 `credentials_valid_after`,在每次请求时都会与凭据自身的签发时间*以及*其谱系根进行比较:```python
watermark = user.credentials_valid_after
if credential.issued_at < watermark: reject # the obvious case
if credential.root_issued_at < watermark: reject # the refresh chain
第二个比较是需要付出代价才能做对的,也是朴素实现会遗漏的——在强制执行中与在检测中完全一样。
显式撤销是纵深防御,也是证据。revoked_at 和
revocation_reason 是事件响应人员所读取的内容,而
auth.token.revoked 事件则是证明遏制已发生的依据。
test_the_watermark_alone_rejects_a_stale_credential 设置水印而不撤销任何内容,并要求拒绝过期凭证——这确立了二者中哪一个是承重的,以及哪个属性对于服务器已忘记其签发过的凭证仍然成立。
没有一个请求发生变化。一个函数变了。
触发条件不是*“密码已更改”。而是“某些变化使得先前签发的凭证不再可信”*。所有四条路径共享
_revoke_for_security_change,因此修复和缺陷同样适用于:
| 变更 | 为什么凭证变得不可信 |
|---|---|
| 密码更改 / 重置 | 会话建立时所依据的秘密已不存在 |
| MFA 注册或更改 |
针对每一种类型,在两种模式下都进行了测试,见
tests/test_privilege_changes.py——包括
登录的非要求,已记录在案,以免下一位读者“修复”它。
让凭证停止工作的四种方式。AFTERLIFE 实现了 A + C,而且顺序很重要。
关于 D:JWT 本身并非不安全。这种张力更狭窄,值得精确陈述——无状态验证与即时服务器端撤销是互斥的。 如果不咨询某个知道“此凭证不再有效”的东西,你就无法做出这一判断,而咨询它正是使系统变为有状态的原因。错误在于为了其无状态性而采用 JWT,然后却仍然需要撤销,而每个产品在第一次笔记本电脑被盗时都会这样做。你最终得到的是一个指向服务器端状态的签名指针——这正是 app/tokens.py 有意实现的,因为有意到达那里比在事件中途到达那里代价更低。
CVE-2026-22706 评分为 2.1, Low(CVSS v4.0
AV:N/AC:H/AT:N/PR:H/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N),而且这个评分是站得住脚的:PR:H 是因为攻击者必须已经持有有效的刷新凭证,AC:H 是因为获得一个需要先前的入侵,而 VC:N/VI:L 是因为该缺陷并未授予攻击者尚未拥有的任何访问权限。CVSS 衡量的是漏洞的边际影响,而边际影响是访问的持续时间,而非其范围。给定这些输入,2.1 正确地由公式得出。
CVSS 没有建模的是,失败的控件是遏制动作——因此有用的结论是关于分诊路由,而不是关于这个数字。遏制路径中的 Low 值得关注,而功能路径中的 Low 则不然,因为代价是在事件期间付出的。完整讨论: docs/tradeoffs.md。
290 passed
| 文件 | 它固定了什么 |
|---|---|
| [`test_fixed_mode.py`](https://github.com/het-p301204/afterlife/blob/main/tests/test_fixed_mode.py) | **绝不能变红的回归测试套件** —— 在撤销事件之前签发的任何凭证,在该事件之后都不被接受,包括源自过期谱系的凭证 |
| [`test_vulnerable_mode.py`](https://github.com/het-p301204/afterlife/blob/main/tests/test_vulnerable_mode.py) | 该漏洞**存在**、是确定性的、持续 30 天,并且由该条件语句导致 —— 其中 `device_id` 对照证明撤销路径是可选的而非死代码 |
| [`test_lineage.py`](https://github.com/het-p301204/afterlife/blob/main/tests/test_lineage.py) | 刷新链保持一个谱系和一个根;只有登录会创建谱系 |
| [`test_detector_afterlife001.py`](https://github.com/het-p301204/afterlife/blob/main/tests/test_detector_afterlife001.py) | 7 个检测用例、9 个误报用例、2 个盲点、全部 24 种事件顺序、有界状态、畸形输入 |
| [`test_detector_rulepack.py`](https://github.com/het-p301204/afterlife/blob/main/tests/test_detector_rulepack.py) | AFTERLIFE-002 和 AFTERLIFE-003 —— 每个判定、宽限期、轮换不等于死亡、过期排除,以及引擎的顺序 |
| [`test_naive_detector.py`](https://github.com/het-p301204/afterlife/blob/main/tests/test_naive_detector.py) | NAIVE-001 持续以**本 README 所声称的特定方式**失败 —— 包括它拥有所需的数据 |
| [`test_audit_and_console.py`](https://github.com/het-p301204/afterlife/blob/main/tests/test_audit_and_console.py) | 任何规则都看不到的休眠幸存者;两个审计来源一致;控制台不自行计算任何判定;离线预览不获取任何内容;本 README 中的每个数字都在范围内、无样式表且字节稳定 |
| [`test_scenarios.py`](https://github.com/het-p301204/afterlife/blob/main/tests/test_scenarios.py) | 承载论点的矩阵行 |
| [`test_privilege_changes.py`](https://github.com/het-p301204/afterlife/blob/main/tests/test_privilege_changes.py) | MFA、角色变更和账户恢复,两种模式 |
| [`test_telemetry.py`](https://github.com/het-p301204/afterlife/blob/main/tests/test_telemetry.py) | 脱敏契约,以及在日志中 grep 实际签发的 bearer 字符串字面量 |
| [`test_app.py`](https://github.com/het-p301204/afterlife/blob/main/tests/test_app.py) | 伪造签名、错误的凭证类型、来自服务器状态的过期 |
| [`test_infrastructure.py`](https://github.com/het-p301204/afterlife/blob/main/tests/test_infrastructure.py) | 配置、时钟、tailer 部分行、两个 CLI、每条演示命令 |
测试套件中最强的测试是
`test_no_bearer_string_or_password_ever_reaches_the_log`:它运行整个攻击,
然后在日志文件中搜索应用程序实际发出的凭证,加上两个密码,加上签名密钥。不是搜索字段名 —— 而是搜索值。
---
## 盲点
直白陈述,因为隐藏它们会让实验环境变得不诚实。每个盲点都有测试。
> **如果应用程序不发出凭证变更事件,规则包就无法可靠地关联重置后的活动。** 没有锚点,因此活动没有“之后”可言 —— 而且它会首先让 AFTERLIFE-003 沉默,而这条规则本会告诉你控制已失效。
>
> **如果应用程序不保留签发/谱系元数据,检测器就无法确定一个新访问令牌是否源自较旧的凭证。** 三秒前签发的凭证与一个月前的链在三秒前签发的凭证无法区分。
这些**不是可选的日志记录偏好。它们是安全检测要求。** 丢弃 `auth.token.issued` 以减少日志量并不会让日志记录更便宜;它会关闭一项检测。
无法解析的活动会被**计数**,而不是被静默丢弃 ——
每当检测器被问及遥测从未描述过的凭证时,`stats()["activity_with_unresolved_lineage"]` 就非零。一条因为一切正常而安静的规则,和一条因为失明而安静的规则,从外部看完全相同,而这个数字就是区别所在。
同样真实,也同样有文档记录:
* **检测器无法拒绝请求。** 它跟踪日志。它告诉你遏制失败了;它并不遏制。
* **审计是扫描,不是检测。** 它填补了休眠幸存者的缺口,但它在有人运行它时才运行。它无法寻呼。
* **该修复对重置*之后*被盗的凭证没有帮助。** 遏制是一个时间点,而不是一种属性。
* **AFTERLIFE-003 验证的是观察到的遏制,而不是架构上的完整性。** 一个恰好覆盖一切的范围限定于设备的撤销会得到 LOW 发现,而不是 HIGH。漏洞仍然存在;它只是没有在那个账户上发作。测试可以问“那两个设备呢?”;日志只能报告实际发生了什么。
* **其他持久化完全能在密码更改后存活** —— OAuth 授权、API 密钥、邮件转发规则、恢复联系人。
完整讨论:**[docs/limitations.md](https://github.com/het-p301204/afterlife/blob/main/docs/limitations.md)**。
---
## 运行实验环境```bash
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt -r requirements-dev.txt
pytest -q
然后,按顺序:```bash python scripts/lab.py vulnerable
## 使用示例
### 基本用法
```bash
# 扫描单个目标
python3 cve_2025_55182.py -t https://target.example.com
# 扫描多个目标
python3 cve_2025_55182.py -f targets.txt
# 使用自定义线程数扫描
python3 cve_2025_55182.py -f targets.txt -c 20
# 使用代理扫描
python3 cve_2025_55182.py -t https://target.example.com -p http://127.0.0.1:8080
# 使用自定义超时时间扫描
python3 cve_2025_55182.py -t https://target.example.com --timeout 15
# 详细输出
python3 cve_2025_55182.py -t https://target.example.com -v
[+] 目标: https://target.example.com
[+] 正在检查 CVE-2025-55182...
[!] 目标存在漏洞!
[+] 已获取响应: HTTP 200
[+] 响应时间: 1.23s
*必须提供 -t 或 -f 中的一个。
该工具通过以下方式检测 CVE-2025-55182:
本工具仅用于教育和道德测试目的。未经授权使用此工具攻击目标属于违法行为。作者对任何滥用行为不承担责任。请始终确保您拥有测试目标系统的适当授权。```bash python scripts/lab.py detect
## 使用示例
### 基本用法
```bash
# 扫描单个目标
python3 cve_2025_55182.py -t https://target.example.com
# 使用代理扫描
python3 cve_2025_55182.py -t https://target.example.com -p http://127.0.0.1:8080
# 从文件扫描多个目标
python3 cve_2025_55182.py -f targets.txt
# 使用自定义超时和线程数扫描
python3 cve_2025_55182.py -f targets.txt -T 15 -c 20
# 使用自定义载荷扫描
python3 cve_2025_55182.py -t https://target.example.com --payload "custom_payload_here"
# 详细输出
python3 cve_2025_55182.py -t https://target.example.com -v
# 使用自定义 User-Agent 扫描
python3 cve_2025_55182.py -t https://target.example.com -A "Mozilla/5.0 (Custom)"
# 使用自定义请求头扫描
python3 cve_2025_55182.py -t https://target.example.com -H "X-Custom-Header: value"
# 将结果保存到文件
python3 cve_2025_55182.py -f targets.txt -o results.txt
# 组合多个选项
python3 cve_2025_55182.py -f targets.txt -p http://127.0.0.1:8080 -T 15 -c 20 -v -o results.txt
该工具通过以下方式检测 CVE-2025-55182:
该工具使用多种检测技术:
[+] 正在扫描: https://target.example.com
[+] 目标易受攻击: CVE-2025-55182
[+] 载荷: ...
[+] 响应时间: 5.23s
[+] 状态: 易受攻击
该漏洞存在于 [组件] 中,攻击者可通过发送特制请求来利用该漏洞。成功利用可能导致在目标系统上执行任意代码。
成功利用该漏洞可能允许攻击者:
如果无法立即应用补丁,请考虑以下缓解措施:
本工具仅供教育和道德测试目的使用。未经授权使用本工具攻击目标属于违法行为。使用者需自行承担所有责任。作者对任何滥用或由此造成的损害不承担责任。
本项目采用 MIT 许可证 - 详情请参阅 LICENSE 文件。
如果您觉得本工具对您有帮助,请考虑:
⚠️ 免责声明: 本工具仅供教育和道德测试目的使用。请负责任地使用。```bash python scripts/lab.py fixed
## 使用示例
### 基本用法
```bash
# 扫描单个目标
python3 cve_2025_55182.py -t https://target.example.com
# 扫描多个目标
python3 cve_2025_55182.py -f targets.txt
# 使用自定义线程数扫描
python3 cve_2025_55182.py -f targets.txt -c 20
# 使用代理扫描
python3 cve_2025_55182.py -t https://target.example.com -p http://127.0.0.1:8080
# 使用自定义超时扫描
python3 cve_2025_55182.py -t https://target.example.com --timeout 15
# 详细输出
python3 cve_2025_55182.py -t https://target.example.com -v
[+] 目标 https://target.example.com 存在漏洞
[+] 已获取会话令牌: eyJhbGciOiJIUzI1NiIs...
[+] 已获取管理员访问权限
Next-Action 请求头的可疑请求alert http any any -> any any (msg:"CVE-2025-55182 React Server Components RCE 利用尝试"; flow:to_server,established; content:"Next-Action"; http_header; content:"multipart/form-data"; http_header; classtype:attempted-admin; sid:1000001; rev:1;)
Next-Action 请求头的异常 POST 请求本工具仅供授权的安全测试和教育目的使用。未经授权访问计算机系统是违法的。请务必:
作者对滥用本工具不承担任何责任。
本项目采用 MIT 许可证 - 详情请参阅 LICENSE 文件。
⚠️ 免责声明: 本工具仅用于授权的安全测试。未经授权访问计算机系统是违法的。```bash python scripts/lab.py audit
或者一次性讲完整个故事,并在结尾给出教训:```bash
python scripts/lab.py all
以及图片:```bash python scripts/lab.py console
<details>
<summary><b>其他所有内容</b> — 检测器 CLI、矩阵、报告、图表、服务器</summary>
<br>
通过该包重放已提交的证据。无需运行应用程序——检测器严格处于下游,这就是证明:```bash
python -m detector --once --timeline --events evidence/vulnerable-persistence.jsonl
一次一条规则,或朴素规则,或状态扫描:```bash python -m detector --once --rule AFTERLIFE-003 --events evidence/vulnerable-persistence.jsonl
- **`--no-verify`**:跳过 SSL 证书验证(默认:`False`)
- **`--timeout`**:请求超时时间(秒)(默认:`10`)
- **`--user-agent`**:自定义 User-Agent 字符串
- **`--proxy`**:用于请求的代理 URL
- **`--headers`**:自定义请求头(JSON 格式)
- **`--cookies`**:自定义 Cookie(JSON 格式)
- **`--follow-redirects`**:跟随 HTTP 重定向(默认:`True`)
- **`--max-redirects`**:最大重定向次数(默认:`5`)
- **`--retries`**:失败请求的重试次数(默认:`3`)
- **`--delay`**:请求之间的延迟时间(秒)(默认:`0`)
- **`--random-agent`**:为每个请求使用随机 User-Agent
- **`--threads`**:并发线程数(默认:`10`)
- **`--output`**:输出文件路径
- **`--format`**:输出格式(`json`、`csv`、`txt`)(默认:`json`)
- **`--verbose`**:启用详细输出
- **`--quiet`**:抑制除结果外的所有输出
- **`--no-color`**:禁用彩色输出
- **`--config`**:配置文件路径
- **`--version`**:显示程序版本号并退出
- **`--help`**:显示帮助信息并退出```bash
python -m detector --once --naive --events evidence/vulnerable-persistence.jsonl
CLI 在发现内容时退出码为 `1`,因此无需解析其输出即可作为 CI 检查使用。
针对两种实现共九个场景,并带有自检不变量:```bash
python scripts/scenarios.py
响应人员会收到的安全事件报告,以及本 README 中的图表:```bash python scripts/report.py
## 使用示例
### 基本用法
```bash
# 扫描单个目标
python3 cve_2025_55182.py -t https://target.example.com
# 使用代理扫描
python3 cve_2025_55182.py -t https://target.example.com -p http://127.0.0.1:8080
# 从文件扫描多个目标
python3 cve_2025_55182.py -f targets.txt
# 使用自定义超时和线程数
python3 cve_2025_55182.py -f targets.txt -T 15 -c 20
# 详细输出
python3 cve_2025_55182.py -t https://target.example.com -v
# 将结果保存到文件
python3 cve_2025_55182.py -f targets.txt -o results.txt
选项:
-h, --help 显示此帮助信息并退出
-t TARGET, --target TARGET
单个目标 URL
-f FILE, --file FILE 包含目标 URL 的文件(每行一个)
-p PROXY, --proxy PROXY
用于请求的代理 URL
-T TIMEOUT, --timeout TIMEOUT
请求超时时间(秒,默认:10)
-c CONCURRENCY, --concurrency CONCURRENCY
并发线程数(默认:10)
-o OUTPUT, --output OUTPUT
将结果保存到文件
-v, --verbose 启用详细输出
--no-color 禁用彩色输出
[+] 正在扫描 https://target.example.com
[+] 目标存在漏洞!
[+] 已获取命令执行结果:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
[+] 扫描完成。发现 1 个存在漏洞的目标。
该工具利用了 Next.js 中间件中 x-middleware-subrequest 请求头的处理缺陷。通过构造特定的请求头值,攻击者可以绕过中间件中实现的身份验证和授权检查,从而访问受保护的路由并执行任意命令。
该漏洞影响使用中间件进行身份验证的 Next.js 应用程序。当中间件处理 x-middleware-subrequest 请求头时,它可能无法正确验证请求的合法性,导致攻击者能够绕过安全检查。
x-middleware-subrequest 请求头。x-middleware-subrequest 请求头的异常请求。本工具仅供教育和授权安全测试目的使用。未经目标系统所有者明确书面许可,使用本工具攻击目标系统属于违法行为。使用者应遵守所有适用的法律法规。作者对因使用或滥用本工具而造成的任何损害或损失不承担责任。
本项目采用 MIT 许可证 - 详情请参阅 LICENSE 文件。
欢迎贡献!请随时提交 Pull Request。
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)感谢所有为本项目做出贡献的安全研究人员和开发者。```bash python scripts/figures.py
实时控制台,以及手动调用的实验 API——两者均仅限回环地址:```bash
python -m console
--detect 标志运行工具,以扫描目标并识别漏洞。--exploit 标志运行工具,以利用检测到的漏洞。python3 CVE-2024-36401.py --detect --target http://example.com
python3 CVE-2024-36401.py --exploit --target http://example.com
本工具仅用于教育和道德测试目的。未经授权使用本工具攻击目标属于违法行为。作者对任何滥用行为不承担责任。```bash python -m app --mode vulnerable --port 9101
重新生成已提交的遥测数据(固定时钟,多次运行字节级一致):```bash
python scripts/lab.py evidence
任务运行器,两种方式的目标相同:```bash make demo
## 工具
- [**AFL++**](https://github.com/AFLplusplus/AFLplusplus):AFL++ 是 Google 的 AFL 的社区版本,具有许多额外的功能,如自定义变异器、更好的插桩、更快的速度等。
- [**Angr**](https://github.com/angr/angr):Angr 是一个 Python 框架,用于二进制分析,支持符号执行、控制流分析等。
- [**APKLab**](https://github.com/APKLab/APKLab):APKLab 是一个用于逆向工程 Android APK 的 VS Code 扩展。
- [**Apktool**](https://github.com/iBotPeaches/Apktool):Apktool 是一个用于逆向工程 Android APK 文件的工具。
- [**Binwalk**](https://github.com/ReFirmLabs/binwalk):Binwalk 是一个用于分析、逆向工程和提取固件映像的工具。
- [**Checksec**](https://github.com/slimm609/checksec.sh):Checksec 是一个用于检查可执行文件安全属性的工具。
- [**Cutter**](https://github.com/rizinorg/cutter):Cutter 是一个由 Rizin 驱动的自由开源逆向工程平台。
- [**dnSpy**](https://github.com/dnSpy/dnSpy):dnSpy 是一个用于 .NET 程序集的调试器和 .NET 反编译器。
- [**Frida**](https://github.com/frida/frida):Frida 是一个动态代码插桩工具包。
- [**Ghidra**](https://github.com/NationalSecurityAgency/ghidra):Ghidra 是由 NSA 开发的一个软件逆向工程(SRE)套件。
- [**GhidraDec**](https://github.com/airbus-seclab/ghidradec):GhidraDec 是一个用于 Ghidra 的插件,用于反编译二进制文件。
- [**Hopper**](https://www.hopperapp.com/):Hopper 是一个用于 macOS、Linux 和 Windows 的反汇编器和反编译器。
- [**IDA Pro**](https://hex-rays.com/ida-pro/):IDA Pro 是一个反汇编器和调试器。
- [**JADX**](https://github.com/skylot/jadx):JADX 是一个用于从 Android Dex 和 APK 文件生成 Java 源代码的工具。
- [**LIEF**](https://github.com/lief-project/LIEF):LIEF 是一个用于解析、修改和抽象 ELF、PE 和 Mach-O 格式的库。
- [**Miasm**](https://github.com/cea-sec/miasm):Miasm 是一个逆向工程框架。
- [**OllyDbg**](https://www.ollydbg.de/):OllyDbg 是一个用于 Windows 的 32 位汇编级调试器。
- [**PE-bear**](https://github.com/hasherezade/pe-bear):PE-bear 是一个用于 PE 文件的逆向工程工具。
- [**PEiD**](https://www.aldeid.com/wiki/PEiD):PEiD 是一个用于检测 PE 文件打包器和编译器的工具。
- [**pestudio**](https://www.winitor.com/):pestudio 是一个用于恶意软件分析的 PE 文件分析工具。
- [**Process Hacker**](https://github.com/processhacker/processhacker):Process Hacker 是一个用于监控系统资源、调试软件和检测恶意软件的工具。
- [**Radare2**](https://github.com/radareorg/radare2):Radare2 是一个用于逆向工程和分析二进制文件的框架。
- [**Rizin**](https://github.com/rizinorg/rizin):Rizin 是一个用于逆向工程的自由开源框架。
- [**ROPgadget**](https://github.com/JonathanSalwan/ROPgadget):ROPgadget 是一个用于在二进制文件中查找 ROP gadgets 的工具。
- [**Ropper**](https://github.com/sashs/Ropper):Ropper 是一个用于显示二进制文件信息并查找 ROP gadgets 的工具。
- [**Triton**](https://github.com/JonathanSalwan/Triton):Triton 是一个动态二进制分析框架。
- [**x64dbg**](https://github.com/x64dbg/x64dbg):x64dbg 是一个用于 Windows 的开源 x64/x32 调试器。
- [**z3**](https://github.com/Z3Prover/z3):Z3 是微软研究院开发的一个定理证明器。```powershell
./make.ps1 demo
alice / Password123! → changed during the demo to Correct-Horse-Battery-9!
伪造的、本地的,且是本仓库中唯一的凭据。
---
## 安全说明
**本仓库包含故意存在漏洞的代码。**
当 `AFTERLIFE_MODE=vulnerable` 时,`app/auth.py:_revoke_for_security_change` 会故意撤销失败。
该漏洞路径**并非默认路径**。`AFTERLIFE_MODE` 默认为 `fixed`,并且 `test_the_default_mode_is_the_safe_one` 将其固定——一个因忘记配置任何内容而得到其损坏行为的实验环境,最终会被复制到真实环境中。
无论哪种模式,都不适合暴露于网络:bearer 凭据会在响应体中返回,`GET /lab/credentials` 会转储服务器对用户凭据状态的完整视图,`GET /lab/audit` 按设计未经身份验证,`POST /security-change` 会给自己授予 `admin`,并且任何地方都没有 TLS、速率限制、CSRF 防护或账户锁定。所有内容都绑定到 `127.0.0.1`,并且 `python -m app` 和 `python -m console` 都拒绝任何其他地址。
本仓库中不出现任何真实凭据、密钥或机密。签名密钥是字面字符串 `afterlife-lab-signing-key-not-a-secret-do-not-reuse`;凭据数据库默认为 `:memory:`;遥测会替换键名看起来像凭据的值,并通过 id 和指纹引用凭据。
详情及报告流程:**[SECURITY.md](https://github.com/het-p301204/afterlife/blob/main/SECURITY.md)**。
---
## 文档
| | |
|---|---|
| [docs/detection.md](https://github.com/het-p301204/afterlife/blob/main/docs/detection.md) | 规则包:全部三张规则卡、状态审计、所需遥测、误报、严重性理由、响应运行手册 |
| [docs/tradeoffs.md](https://github.com/het-p301204/afterlife/blob/main/docs/tradeoffs.md) | 四种撤销架构、JWT 张力,以及 CVSS 讨论 |
| [docs/limitations.md](https://github.com/het-p301204/afterlife/blob/main/docs/limitations.md) | 每一个盲点、修复未能修复的内容、审计所关闭的内容,以及实验环境自身的妥协 |
| [docs/console-design.md](https://github.com/het-p301204/afterlife/blob/main/docs/console-design.md) | 为什么控制台是一个死亡登记册、调色板和字体决策,以及被删减的内容 |
| [docs/console-preview.html](https://github.com/het-p301204/afterlife/blob/main/docs/console-preview.html) | 控制台,烘焙为一个自包含文件 |
| [docs/figures/](https://github.com/het-p301204/afterlife/blob/main/docs/figures) | 本 README 中的图表,由 payload 生成 |
| [report/AFTERLIFE-report.md](https://github.com/het-p301204/afterlife/blob/main/report/AFTERLIFE-report.md) | 为漏洞运行生成的的事件报告 |
| [SECURITY.md](https://github.com/het-p301204/afterlife/blob/main/SECURITY.md) | 仅本地边界、实验环境凭据、脱敏契约 |
| [evidence/](https://github.com/het-p301204/afterlife/blob/main/evidence) | 已脱敏的样本遥测、其产生的告警,以及状态审计 |
---
## 研究参考
已于 2026-09-11 对照一手来源进行验证。**VERIFIED** 表示已阅读厂商自己的公告;**REPORTED** 表示细节来自漏洞数据库而非厂商。
**标准与分类**
* [OWASP Top 10:2025 — A07 Authentication Failures](https://top10.owasp.org/2025/A07_2025-Authentication_Failures) — 准确描述了这一故障:未“正确使用户会话或身份验证令牌失效”的应用程序。其 CWE 映射包含以下全部三项。
* [RFC 9700](https://datatracker.ietf.org/doc/rfc9700/) — *OAuth 2.0 安全最佳当前实践*(BCP 240,2025 年 1 月)。本实验环境依赖的两点:重用已轮换的刷新令牌表明令牌被盗(AFTERLIFE-002),并且**撤销必须使整个令牌家族失效,而不仅仅是当前令牌**——这正是 AFTERLIFE-001 的论点,并被编纂为 IETF 实践。
* [OWASP Session Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html) — 凭据和安全变更后的会话失效
* [CWE-613: Insufficient Session Expiration](https://cwe.mitre.org/data/definitions/613.html) — *“允许攻击者重用旧会话凭据或会话 ID 进行授权”*。以下三个 CVE 均归入此类。
* [CWE-287: Improper Authentication](https://cwe.mitre.org/data/definitions/287.html)
* [CWE-384: Session Fixation](https://cwe.mitre.org/data/definitions/384.html) — 相邻问题:在身份验证状态变更后仍然存活的会话标识符
**本实验环境复现的模式**
* **VERIFIED** — [GHSA-hvp3-26wx-g2w4](https://github.com/strapi/strapi/security/advisories/GHSA-hvp3-26wx-g2w4) / [CVE-2026-22706](https://github.com/advisories/GHSA-hvp3-26wx-g2w4),*Strapi:密码重置不会撤销现有刷新会话*。`@strapi/admin` 和 `@strapi/plugin-users-permissions` ≤ 5.33.2;已在 5.33.3 中修复。CVSS v4.0 **2.1 (Low)**,`AV:N/AC:H/AT:N/PR:H/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N`。发布于 2026-05-13。
厂商公告指出,刷新令牌失效步骤以调用方提供的 `deviceId` 为条件,并且该补丁会在每次密码更改和重置时使所有刷新令牌失效,无论是否提供了 `deviceId`。该条件正是 `_revoke_for_security_change` 所建模的内容,而该补丁正是固定模式所实现的内容。
厂商背景:[Strapi 安全披露,2026 年 5 月](https://strapi.io/blog/security-disclosure-of-vulnerabilities-cve-2025-64526-cve-2026-22599-cve-2026-22706-cve-2026-22707-and-cve-2026-27886)。
**同一类别,不同机制**
* **REPORTED** — [CVE-2026-1163](https://nvd.nist.gov/vuln/detail/CVE-2026-1163),parisneo/lollms。密码重置时*完全*没有会话失效,默认会话生命周期为 31 天。此漏洞的简单版本——也是朴素检测器实际会捕获的那个。
* **REPORTED** — [CVE-2026-40934](https://nvd.nist.gov/vuln/detail/CVE-2026-40934),Jupyter Server ≤ 2.17.0(已在 2.18.0 中修复)。cookie 签名密钥被持久化到静态文件,并且在密码更改时从不轮换,因此在重置之前签发的 cookie 在重置之后仍然在密码学上有效。通向同一结果的第三条路径:这里的*凭据*之所以有效,是因为*密钥*从未更改,这正是 [docs/tradeoffs.md](https://github.com/het-p301204/afterlife/blob/main/docs/tradeoffs.md) 中选项 D 的故障模式。
三个产品,三种机制——一个条件参数、一次缺失调用、一个未轮换的密钥——一个结果:重置成功了,而攻击者留了下来。
---
<div align="center">
**攻击者之所以未被检测到,并不是因为他们的请求看起来恶意。**
他们发出的每一个请求都是格式良好的、正确签名的,并携带了服务器刚刚为他们铸造的凭据。
**他们之所以被检测到,是因为一条本应在安全事件发生时终止的凭据谱系在该事件之后仍被接受。**
<br>
<sub>MIT · 一个本地实验环境 · 此处没有任何内容可安全部署</sub>
</div>
| 规则 | 严重级别 | 回答 | 触发时机 |
|---|
| AFTERLIFE-002 | 刷新凭证重用 | CRITICAL / MEDIUM | 它是否被盗用? | 在重用时 |
| AFTERLIFE-003 | 安全变更时的不完整吊销 | HIGH / LOW | 遏制措施是否执行? | 在变更时——无需攻击者 |
| AFTERLIFE-001 | 吊销后凭证谱系使用 | HIGH | 是否使用了过期的谱系? | 在首次接受时 |
| RULE PACK |
| 选项 | 描述 | 默认值 |
|---|
-t, --target | 要扫描的单个目标 URL | - |
-f, --file | 包含目标 URL 的文件 | - |
-p, --proxy | 用于请求的代理 URL | - |
-T, --timeout | 请求超时时间(秒) | 10 |
-c, --threads | 并发线程数 | 10 |
--payload | 用于漏洞利用的自定义载荷 | 默认载荷 |
-A, --user-agent | 自定义 User-Agent 字符串 | 默认 UA |
-v, --verbose | 启用详细输出 | False |
-o, --output | 将结果保存到文件 | - |
| 场景 | 模式 | 事件 | 最严重 | 触发的规则 | 陈旧 | 休眠 |
|---|
legitimate-only | vulnerable | 19 | LOW | AFTERLIFE-003 | 0 | 0 |
legitimate-only | fixed | 19 | – | 无 | 0 | 0 |
stolen-refresh | vulnerable | 22 | HIGH | AFTERLIFE-001, AFTERLIFE-003 | 1 | 0 |
stolen-refresh | fixed | 23 | – | 无 | 0 | 0 |
stolen-refresh-with-device-id | vulnerable | 19 | LOW | AFTERLIFE-003 | 0 | 0 |
stolen-refresh-with-device-id | fixed | 19 | – | 无 | 0 | 0 |
multi-device | vulnerable | 29 | HIGH | AFTERLIFE-001, AFTERLIFE-003 | 2 | 0 |
multi-device | fixed | 29 | – | 无 | 0 | 0 |
refresh-reuse | vulnerable | 11 | MEDIUM | AFTERLIFE-002 | 0 | 0 |
refresh-reuse | fixed | 15 | MEDIUM | AFTERLIFE-002 | 0 | 0 |
dormant-survivor | vulnerable | 15 | HIGH | AFTERLIFE-003 | 1 | 1 |
dormant-survivor | fixed | 19 | – | 无 | 0 | 0 |
mfa-change | vulnerable | 18 | HIGH | AFTERLIFE-001, AFTERLIFE-003 | 1 | 0 |
mfa-change | fixed | 18 | – | 无 | 0 | 0 |
account-recovery | vulnerable | 18 | HIGH | AFTERLIFE-001, AFTERLIFE-003 | 1 | 0 |
account-recovery | fixed | 18 | – | 无 | 0 | 0 |
expired-lineage | vulnerable | 17 | LOW | AFTERLIFE-003 | 0 | 0 |
expired-lineage | fixed | 20 | – | 无 | 0 | 0 |
| 情况 | 结果 | 原因 |
|---|
| 密码更改,随后替换会话被使用 | 无告警 | 新谱系的根位于水印处或之后 |
重置后立即浏览(/me、/profile、/settings) | 无告警 | 一个新鲜谱系,一个新鲜根 |
| 手机、笔记本电脑和平板,全部正确轮换 | 无告警 | 每次登录都是其自身的谱系 |
| 在更改之后登录的设备,与攻击者同时浏览 | 无告警 | 新鲜根——而陈旧谱系仍会单独告警 |
| 被拒绝的陈旧凭证 | 无告警 | result: failure 被排除;它是辩护方的证据 |
| 组件之间最多 2 秒的时钟偏差 | 无告警 | 文档化的容差 |
| 失败的密码更改 | 无告警 | 不是锚点 |
| 更改之前的活动 | 无告警 | 时间排序检查 |
被轮换的凭证(reason: rotated) | 不计为死亡 | 凭证被消耗,而非谱系被杀死 |
| 一个 40 天前的会话,其凭证已过期 | 不是存活者 | 过期按谱系跟踪 |
| 全新账户上的首次密码更改 | 无告警 | 进入时没有任何活动凭证 |
| 来自陈旧谱系的刷新令牌轮换 | 告警 | 新鲜时间戳,陈旧血统——这就是发现 |
| 会话建立时所依据的因素不再是账户的因素 |
| 角色更改 / 权限提升 | 凭证是在不同的授权下铸造的 |
| 账户恢复 | 从构造上讲,账户片刻之前可能还在别人手中 |
| 登录 | 不会撤销其他凭证——这是一条新的谱系,而不是声明旧的不可信 |
| 机制 | 收益 | 成本 |
|---|
| A | 按用户撤销水印 | 一次写入即可撤销一切,包括服务器已忘记的凭证;O(1) 存储和检查 | 读路径上的服务器端状态;时间戳语义必须完全正确;对水印之后签发的凭证不置一词 |
| B | 短时访问 + 可撤销刷新 | 在没有读路径状态的情况下限制访问令牌的损害 | 被盗的访问令牌在过期前一直有效;刷新侧仍然需要状态——这正是 CVE 所栖身的模式 |
| C | 显式拒绝列表 | 精确;对事件响应人员清晰可读;产生证明遏制的遥测数据 | 状态增长且需要清理;只撤销你记得枚举的内容——而这正是该缺陷弄错的查询 |
| D | 完全无状态 JWT | 完全没有读路径状态 | 没有撤销。 TTL 和密钥轮换是仅有的手段 |
| 参数 | 描述 | 是否必需 |
|---|
-t, --target | 单个目标 URL | 是* |
-f, --file | 包含目标 URL 的文件 | 是* |
-c, --concurrency | 并发线程数(默认:10) | 否 |
-p, --proxy | 用于请求的代理 URL | 否 |
--timeout | 请求超时时间(秒,默认:10) | 否 |
-v, --verbose | 启用详细输出 | 否 |
| 选项 | 描述 | 默认值 |
|---|
-t, --target | 要扫描的单个目标 URL | - |
-f, --file | 包含目标 URL 的文件 | - |
-p, --proxy | 用于请求的代理 URL | - |
-T, --timeout | 请求超时时间(秒) | 10 |
-c, --concurrency | 并发线程数 | 10 |
--payload | 用于测试的自定义载荷 | 默认载荷 |
-A, --user-agent | 自定义 User-Agent 字符串 | 默认 UA |
-H, --header | 自定义请求头(可多次使用) | - |
-o, --output | 将结果保存到文件 | - |
-v, --verbose | 启用详细输出 | False |
| 工具名称 | 描述 | 支持的平台 |
|---|
| Nmap | 网络映射器 | Linux, Windows, macOS |
| Masscan | 互联网规模的端口扫描器 | Linux, Windows, macOS |
| Amass | 深度攻击面映射与资产发现 | Linux, Windows, macOS |
| Subfinder | 子域名发现工具 | Linux, Windows, macOS |
| Assetfinder | 查找与给定域名相关的域名和子域名 | Linux, Windows, macOS |
| httpx | 快速且多用途的 HTTP 工具包 | Linux, Windows, macOS |
| Naabu | 用 Go 编写的快速端口扫描器 | Linux, Windows, macOS |
| Shodan | 互联网连接设备搜索引擎 | Web |
| Censys | 互联网资产搜索引擎 | Web |
| theHarvester | 电子邮件、子域名、主机、员工姓名、开放端口和横幅收集工具 | Linux, Windows, macOS |
| Recon-ng | 用 Python 编写的全功能 Web 侦察框架 | Linux, Windows, macOS |
| SpiderFoot | 自动化 OSINT 工具 | Linux, Windows, macOS |
| Maltego | 交互式数据挖掘与取证工具 | Linux, Windows, macOS |
| dnsrecon | DNS 枚举脚本 | Linux, Windows, macOS |
| Fierce | DNS 侦察工具 | Linux, Windows, macOS |
| DNSEnum | 多线程 DNS 枚举工具 | Linux, Windows, macOS |
| Whois | 域名注册信息查询工具 | Linux, Windows, macOS |
| WhatWeb | Web 技术指纹识别工具 | Linux, Windows, macOS |
| Wappalyzer | 识别网站上的技术 | Web |
| BuiltWith | 网站技术分析工具 | Web |
| Wafw00f | Web 应用防火墙指纹识别工具 | Linux, Windows, macOS |
| Nikto | Web 服务器扫描器 | Linux, Windows, macOS |
| Gobuster | 用 Go 编写的目录/文件、DNS 和 VHost 爆破工具 | Linux, Windows, macOS |
| Dirb | Web 内容扫描器 | Linux, Windows, macOS |
| Dirsearch | Web 路径扫描器 | Linux, Windows, macOS |
| Feroxbuster | 用 Rust 编写的快速、简单、递归内容发现工具 | Linux, Windows, macOS |
| ffuf | 用 Go 编写的快速 Web 模糊测试工具 | Linux, Windows, macOS |
| Wfuzz | Web 应用模糊测试工具 | Linux, Windows, macOS |
| Arjun | HTTP 参数发现套件 | Linux, Windows, macOS |
| ParamSpider | 从 Web 归档的黑暗角落挖掘参数 | Linux, Windows, macOS |
| LinkFinder | 在 JavaScript 文件中发现端点及其参数的 Python 脚本 | Linux, Windows, macOS |
| SecretFinder | 在 JavaScript 文件中发现敏感数据的 Python 脚本 | Linux, Windows, macOS |
| Waybackurls | 从 Wayback Machine 获取已知 URL | Linux, Windows, macOS |
| Gau | 从 AlienVault 的 Open Threat Exchange、Wayback Machine 和 Common Crawl 获取已知 URL | Linux, Windows, macOS |
| Hakrawler | 用 Go 编写的简单快速 Web 爬虫 | Linux, Windows, macOS |
| Gospider | 用 Go 编写的快速 Web 爬虫 | Linux, Windows, macOS |
| Photon | 为 OSINT 设计的高性能爬虫 | Linux, Windows, macOS |
| Aquatone | 用于攻击性安全专业人员的域名接管和网站截图工具 | Linux, Windows, macOS |
| EyeWitness | 对网站进行截图、提供服务器头信息并识别默认凭据 | Linux, Windows, macOS |
| Gowitness | 用 Go 编写的网站截图工具 | Linux, Windows, macOS |
| Sublist3r | 用于渗透测试人员的快速子域名枚举工具 | Linux, Windows, macOS |
| Knockpy | 用 Python 编写的子域名扫描器 | Linux, Windows, macOS |
| DNSDumpster | 免费的域名研究工具 | Web |
| SecurityTrails | 域名和 IP 情报 | Web |
| VirusTotal | 分析可疑文件和 URL | Web |
| URLScan | 扫描和分析网站 | Web |
| Shodan | 互联网连接设备搜索引擎 | Web |
| Censys | 互联网资产搜索引擎 | Web |
| ZoomEye | 网络空间搜索引擎 | Web |
| FOFA | 网络空间搜索引擎 | Web |
| GreyNoise | 互联网背景噪音分析 | Web |
| BinaryEdge | 互联网扫描与威胁情报 | Web |
| Hunter.io | 电子邮件查找工具 | Web |
| Phonebook | 电子邮件、域名和 URL 查找工具 | Web |
| IntelX | 情报搜索引擎 | Web |
| Dehashed | 数据泄露搜索引擎 | Web |
| Have I Been Pwned | 检查账户是否因数据泄露而遭到入侵 | Web |
| LeakCheck | 数据泄露搜索引擎 | Web |
| Snusbase | 数据泄露搜索引擎 | Web |
| WeLeakInfo | 数据泄露搜索引擎 | Web |
| GhostProject | 数据泄露搜索引擎 | Web |
| BreachDirectory | 数据泄露搜索引擎 | Web |
| Leak-Lookup | 数据泄露搜索引擎 | Web |
| Firefox Monitor | 检查账户是否因数据泄露而遭到入侵 | Web |
| Google Dorks | Google 黑客数据库 | Web |
| GHDB | Google 黑客数据库 | Web |
| DorkSearch | Google Dork 搜索引擎 | Web |
| DorkGenius | Google Dork 生成器 | Web |
| Dorky | Google Dork 生成器 | Web |
| Pagodo | 自动化 Google Dork 工具 | Linux, Windows, macOS |
| Dorkbot | 命令行 Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | 自动化 Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux, Windows, macOS |
| DorkGen | Google Dork 生成器 | Linux, Windows, macOS |
| Dorky | Google Dork 生成器 | Linux, Windows, macOS |
| Dorkbot | Google Dork 工具 | Linux, Windows, macOS |
| DorkNet | Google Dork 工具 | Linux, Windows, macOS |
| DorkScraper | Google Dork 抓取工具 | Linux, Windows, macOS |
| DorkScanner | Google Dork 扫描器 | Linux, Windows, macOS |
| DorkSearch | Google Dork 搜索引擎 | Linux,```bash |
| python -m detector --audit --events evidence/vulnerable-persistence.jsonl |