npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-redteam-attack-matrix

v1.2.2

Published

DSH 红队攻击矩阵插件:扫工作区对话映射到 MITRE ATLAS / ATT&CK、OWASP LLM Top 10、NVIDIA AI Kill Chain 四套框架,标出已覆盖与缺口,并给出测试时间线

Readme

攻击矩阵 · DSH 插件

把工作区里的对话(用户消息、模型回复、工具调用与结果)扫成一张攻击矩阵: 每次操作命中哪个框架的哪个技术点,标出已覆盖与缺口, 并在下方给出对本组织发起测试的时间线。

当前支持四套框架,每套一个页面:

| 框架 | 面向 | 收录 | 数据来源 | |---|---|---|---| | MITRE ATLAS | AI 系统本身的对抗战术 | 45 技术点 / 16 阶段 | 官方机读数据 atlas-data v2026.09 | | MITRE ATT&CK Enterprise | 企业 / IT 面战术技术 | 46 技术点 / 15 阶段 | MITRE 官方 TAXII 2.1(企业版 collection) | | OWASP Top 10 for LLM Applications 2025 | LLM 应用风险 | LLM01–LLM10 | 官方仓库 2_0_vulns | | NVIDIA AI Kill Chain | AI 应用攻击阶段 | 29 技术点 / 6 阶段 | NVIDIA 官方博客(2025-09-11, Rich Harang) |

ATLAS 和 ATT&CK 是两套东西:ATLAS 打 AI 系统本身,ATT&CK 打企业 IT 面。 红队实操里两者会同时命中(先扫资产、拿凭据,再去打模型),所以并列成两个页面 而不是合并。两个大框架都只收了与「AI/LLM 红队对话」相关的子集,不是全量目录 —— 矩阵的价值在于缺口准,不在于条目多。

它怎么工作

  1. 扫对话(自动):host 每 20 秒读一次当前工作区里所有会话的事件流(user/message、 assistant/message、tool/call、tool/result),把每次操作抽成一条可读记录。 扫描是增量的(按会话 seq 续点),没有新事件时不落盘。面板上没有扫描按钮 —— 这件事不需要人记得去做。
  2. 匹配:用每个技术点的特征词表(detect_keywords)在操作文本里匹配。 命中先记为疑似:自动匹配只负责提示,不负责下结论。
  3. 判定(AI 自动):疑似命中进待判定队列,host 成批交给模型,模型用 matrix_label 逐条下结论 —— 只有「做成了」才记为已确认(利用成功、拿到回显/shell/文件内容、 PoC 跑通、注入或越权确实生效),只是提及或尝试未果保持疑似,误报直接删除。 每条结论都带 reason(看到了什么内容),记进矩阵日志并显示在卡片上。 面板上的「确认覆盖 / 排除」保留为人工覆盖 AI 结论的入口(会标成「人工判定」)。
  4. 落盘:矩阵数据写进工作区自己的 .redteam-attack-matrix.json, 所以切工作区 = 切数据集,互不污染。所有「读—改—写」都串行,避免互相覆盖。
  5. 时间线:按 框架×技术×会话 分组倒序,每组给出 firstAt → lastAt 的区间与可读时长, 时间精确到秒并标明本地时区,并列出这组打过的具体目标(URL / IP[:端口] / 主机名 / nmap 的 -p 端口表 —— 从操作文本里抽出来)。它的用途是回溯「谁在什么时候对谁做了什么」, 所以要经得起对表。时间线可以整份导出 CSV(列含目标、命中词、判定依据、精确到秒的 本地时间与 epoch),导出取全部桶,不只是面板显示的那最近 200 个。 加这个字段之前扫出来的老数据没有 targets,读的时候会从留存的证据片段里现取 —— 不必为了看目标而重扫(重扫会丢掉已有的判定结论)。

界面

┌ 顶栏:工作区下拉 · 重扫 · 清除 · 状态(会话数 · 操作数 · 待判定 · 自动扫描心跳)· 已忽略 N 个会话 / 恢复
├ 框架标签页:ATLAS / ATT&CK / OWASP LLM / NVIDIA      每个框架一页
├ 覆盖率条:已确认 / 疑似 / 总数 · 命中操作次数
├ 技术卡片网格:灰=未覆盖   黄=疑似   **红=已确认**
│   (红色是刻意的:已确认意味着这个技术点**真的打成了**,对防守方是坏消息、
│     对红队是战果 —— 用绿色会读成「好」,语义正好反了)
│   └ 点卡片 → 右侧详情:技术点说明、判定线索、特征词、
│                 攻击操作日志(按会话聚合,带证据片段与判定依据)、确认 / 排除
└ 时间线:每行是「时间区间 + 目标(IP/端口/URL/主机名)+ 次数 + 判定状态」,按时间倒序;右上角「导出 CSV」

清除与重扫的区别

两者都清空命中记录,区别只在扫描续点(每个会话已经扫到哪个 seq):

| | 命中记录与判定结论 | 扫描续点 | 结果 | |---|---|---|---| | 清除 | 清空 | 保留 | 历史事件不会重新入表,从此刻起重来 | | 重扫 | 清空 | 清空 | 按事件重算,历史命中回来 —— 连之前排除掉的桶也一并重建 |

所以「重扫」根治不了噪音:它清完立刻重扫,同一批历史事件会把矩阵原样建回来。 要清噪音得用「清除」。而「清除」是可逆的 —— 想把历史找回来就重扫一次。 清除是破坏性的(矩阵数据没有垃圾箱),所以按钮要点两次才执行。

忽略非目标会话

扫描对象是工作区里的所有会话 —— 包括你正在开发这个插件的那条对话。而它本身 就在不停命中框架关键词:实测写一行含「主机名」的注释,就造出一个 T1082 桶; 把面板上的时间线贴回对话,也会再造一批。逐条排除永远排不完。

所以在卡片详情的攻击操作日志里点「忽略该会话」:把整个会话标成非目标 —— 不再扫描它,并清掉它已有的命中记录。顶栏显示已忽略数量,点「恢复」可撤销 (想让它们的历史命中回来,再点一次「重扫」)。忽略名单优先于扫描水位, 所以「重扫」也不会把它带回来。

安装

dsh plugin --profile web add dsh-redteam-attack-matrix
# 重启 dsh web

包自带 dsh.bundle.patch,装完自动挂载,不需要手工编辑配置。

版本

1.1.1(仓库版本)。src/ 是权威源码,lib/ 由它生成,因此不存在「仓库版本与运行版本不一致」。

1.1.1 相对 1.1.0

新增

  • 对外服务 redteamAttackMatrix:digest() / names() / storePath()。 红队报告插件要靠它拿到「命中矩阵的内容」—— 技术点名字只在本插件的框架表里, 命中详情的存储结构也只有本插件知道。有了这个服务,报告那边不必去猜文件格式和 id→名字; 没有它时报告会退回直接读存储文件(只有 id、没有名字,仍然可用)。

1.1.0 相对 1.0.1

新增

  • 扫描与判定全自动:host 每 20 秒增量扫描(没有新事件时不落盘),疑似命中成批交给模型, 由模型用 matrix_label 逐条定论 —— 面板上没有扫描按钮。每条结论带 reason(看到了什么) 与来源(AI 自动 / 人工),写进日志并显示在卡片上。人工的「确认覆盖 / 排除」保留为覆盖入口。
  • 时间线:每行是 firstAt → lastAt 的区间(精确到秒 + 可读时长),并列出该组打过的 具体目标(URL / IP[:端口] / 主机名 / nmap 端口表);可整份导出 CSV (全部桶、17 列、含 BOM 以便 Excel 正确读中文)。
  • 清除:清空命中记录但保留扫描续点 —— 历史事件不会重新入表。这与「重扫」互补: 重扫连水位一起清、历史原样重建。两者互为逆操作,所以清除不需要垃圾箱。
  • 忽略会话:把整个非目标会话关掉(不再扫描它 + 清掉它已有的记录)。存在的理由很实际: 在「开发这个插件」的工作区里,对话本身会不停命中框架关键词,逐条排除永远排不完。可恢复。

修复

  • ATT&CK 标签页一片空白:技术点的 tactic_ids 写的是 slug(reconnaissance)、 阶段表写的是 TA00xx,46 个技术点被静默丢掉。修正映射,并把 15 个阶段排成标准杀伤链顺序; 同时让「命不中任何阶段」的技术点归入「未归类」而不是从界面上消失。
  • 匹配器缺词边界:rce 命中 source/resource、dos 命中 todos(实测单桶最大 395 次 的假阳性)。纯 ASCII 关键词现在要求词边界,含 CJK 的仍走子串(中文没有词边界)。
  • 证据片段只留最早的 4 条:判定者看不到后面的关键动作(实测漏掉过一次未授权操作)。 改为最早 2 条 + 滚动保留最新 2 条。
  • 自反馈:插件自己的工具调用与研判请求正文不再进矩阵(实测污染过 25 个桶)。
  • 并发读改写丢更新:所有「读—改—写」路径串行化。
  • 「已确认」改用红色:它意味着这个技术点真的打成了,对防守方是坏消息、对红队是战果 —— 用绿色会读成「好」,语义正好反了。

测试:npm test 跑 host 侧 97 项 + client 侧 87 项(含上述每一条的回归线、对外服务那份数据形状,以及「样式只引用注册过的主题 token」)。

1.0.1 / 1.0.0

1.0.1 修的是客户端 RPC 路径:1.0.0 的 lib/client.js 把它写死成了 /dsh-redteam-asset-graph/rpc,于是本插件去打资产图谱的路由 —— 面板请求全 404, 两者同时安装时还会读到对方的数据。现在由生成器按包名替换 __ROUTE_BASE__, 并把实际请求的 url 钉进冒烟测试(原来只记 method,路径写错成别的插件也测不出来)。

1.0.0 的内容(四套框架矩阵、扫描与确认链路、时间线)见 git log 与 tag attack-matrix-v1.0.0。

已知限制

  • 只能扫进程内活着的会话。DSH 的 sessions 是内存态 Service (官方描述:持久化不在这个 store 里),所以重启后已不在内存里的历史会话扫不到。 矩阵自己的数据是落盘的,重启不会丢已有记录,但「重扫」也读不回已经卸载的会话。
  • 自动匹配会误报。特征词表刻意选得具体(宁可漏报不刷屏),但仍然只是提示。 覆盖率以判定结论为准,而判定由模型自动做出、逐条带 reason,人可以随时用 「确认覆盖 / 排除」覆盖它。
  • 判定是模型的判断,不是证据的证明。判据把「没拿到成功证据」一律压回疑似, 但模型仍可能看漏。要拿去做交付结论时,请抽查若干条 reason 对应的证据片段。
  • 判定会占用一次模型回合。待判定攒够 6 条、或者最老的一条已经等了 10 分钟才交一批; 每批最多 8 条、两批之间至少隔 5 分钟;交出去 15 分钟还没有结论的条目会自动退回队列 (唤醒可能根本没被接手)。唤醒的是当前会话的 Agent —— 所以面板上会看到研判请求 作为消息进来,那是设计如此。
  • 框架数据是内置的,不联网拉取。ATT&CK / ATLAS 这类大框架只收与 AI/LLM 测试对话可能相关的子集,不是全量。每个框架的版本与来源写在 面板标签页的 tooltip 里(src/frameworks.js 的 source 字段)。
  • 框架数据里「阶段 id」与「技术点的 tactic_ids」必须对得上。对不上的技术点会被 归到「未归类」组,而不是从界面上消失 —— 这条是踩过坑的:ATT&CK 的技术点写的是 slug(reconnaissance)、阶段表写的是 TA00xx,46 个技术点被静默丢掉, 切到那个标签页就是一片空白。npm test 里有对应的回归线(数据完整性与渲染两层)。

开发

src/ 是权威源码,lib/ 由它生成:

npm run build:lib     # 生成 lib/
npm run check:lib     # 校验与 src/ 是否漂移(prepack 会跑)
npm test              # 扫描链路 + 客户端渲染

test:scan 要解析 @deepseek-ai/dsh-tools。解析不到时它会打印一句「跳过」然后 exit 0 —— npm test 照样绿,但主机侧一条断言都没跑。先按仓库根 README 的 「让主机侧测试真的跑起来」软链依赖,跑出来的项数才算数(host 84 + client 85)。

改之前请先读仓库的 ../../docs/DEVELOPMENT.md—— DSH 插件开发有几条硬约束(静态形态下哪些 API 不存在、组合 patch 的语义、 沙箱与依赖解析),那里记的每一条都是实测踩出来的。

| 文件 | 说明 | |---|---| | src/host.js | applyHost 的函数体(函数头/垫片/收尾在 lib/parts/,不要重复写) | | src/frameworks.js | 框架数据:tactics + techniques + detect_keywords | | src/client.js | 客户端半边,以 return { name, inject, apply } 结尾 | | lib/parts/ | 生成器模板:垫片与包装都在这里 | | tools/build-lib.mjs | 生成器(把 src/frameworks.js 内联进产物) | | cordis.patch.yml | bundle patch,dsh plugin add 靠它自动挂载 |

加技术点 / 改特征词

只改 src/frameworks.js,然后 npm run build:lib。生成器会校验: 框架结构完整、技术点 id 不重复、detect_keywords 是数组,不合格直接终止构建。

加特征词前先问一句:正常开发对话会不会命中它? 一个会命中每次工具调用的词(比如裸的 tool call)会把矩阵变成噪音墙, 而矩阵的价值恰恰在于缺口准。

数据源

面板用的 JSON-RPC 路由已由 lib/parts/host.tail.js 注册(基址 /dsh-redteam-attack-matrix), src/host.js 里用 harness.handle('method', fn) 补句柄,客户端用 host.call 调。

宿主侧读会话靠两个 Service:

  • ctx.get('workspaceRegistry') → list() / get(id);Workspace.sessionIds 已按 canonical cwd 过滤
  • ctx.get('sessions') → get(id);session.snapshotEvents() 拿事件流

会话事件里用来判断的几类:user/message、assistant/message、tool/call、tool/result。 一次「攻击操作」就是其中一条事件,这也是时间线的刻度。