关于 authoring-security-skills
面向 secskills 插件集合维护者的安全技能编写指南,说明如何组织、路由、评估和验证技能。重点在于精确触发条件与安全判断,而非罗列命令。
主要功能
- 01选择插件与技能层级
- 02编写具体加载描述
- 03组织必需的技能章节
- 04登记 ATT&CK 覆盖
- 05添加路由评估用例
- 06运行验证检查
适用场景
- 01向插件添加安全技能
- 02拆分或合并重叠技能
- 03修复技能路由行为
- 04处理验证器或评估失败
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ trilwu/ secskills --skill authoring-security-skills安装后在 Claude Code 中输入/authoring-security-skills确认已加载。
详细介绍
编写安全技能
一项技能只有在包含模型原本容易出错的内容时,才值得占用上下文预算。模型已经知道 nmap -sV 的作用,但它无法可靠地牢记其中的纪律——报告前要追溯到已证实的影响,修复前要先保全证据,绝不发布未经真实环境噪声测试的规则。
这种判断力才是交付成果。命令只是围绕它搭建的脚手架。
适用情况
- 向
secskills-offense、-defense或-core添加新技能 - 拆分过于臃肿的技能,或合并两个有重叠的技能
- 修复因错误请求而加载,或未能因正确请求而加载的技能
- 解决
validate.py、sync_attack.py或run_evals.py报出的失败
不适用情况
- 核查你所写内容的事实准确性——这属于
verifying-skill-accuracy,是本流程之后运行的独立关卡 - 修改现有且已定稿技能的文案
- 与技能无关的仓库级工作(清单、市场、CI)
步骤 1:选择插件
一项技能只能归属于一个插件。这种划分旨在避免蓝队用户接触攻击利用内容,反之亦然。
| 插件 | 包含内容 | 判断标准 |
|---|---|---|
secskills-offense | 攻击利用、攻击者手法,以及针对目标开展的测试 | 这会在交战过程中针对某人的系统运行吗? |
secskills-defense | DFIR、威胁搜寻、检测、情报、事件响应 | 这是事后读取制品,还是用于构建检测? |
secskills-core | 双重用途:逆向工程、代码/密码学/供应链审查、AI 安全、ATT&CK 映射、报告 | 它在攻防两方面都同样适用吗? |
如果一项技能适合两个插件,选择 core,不要重复创建。跨插件引用是预期做法;对于只安装了一个插件的读者,这些引用会退化为不起作用的文本——这是有意为之,因此切勿为了避免交叉引用而复制技能。
步骤 2:选择层级
领域技能涵盖整个领域的方法论,并针对宽泛的日常语言请求触发。数量应少,且彼此不重叠。
流程技能涵盖一种罕见、明确且无法从一般知识中推断出来的目标与工具链组合——例如使用 blutter 的 reversing-flutter-apps。它们本来就应该范围狭窄。
两条规则有助于确保层级有效:
- 每项流程技能都必须能从其领域技能到达。 在领域技能中添加识别检查和路由说明。无法到达的流程技能毫无用处。
- 流程技能必须交接后续工作。 恢复符号并不等于完成评估——要指出由哪项技能继续后续工作。
不确定时,问问自己:它适用于该领域的大多数交战(领域技能),还是仅在拿到特定制品时适用(流程技能)?
步骤 3:撰写描述
这是技能中杠杆效应最高的文本。 Claude 会据此决定是否加载该技能,而且它要与另外 71 项技能竞争。即使技能正文无可挑剔,描述含糊也会导致它永远不会运行。
验证器会强制检查以下规则:使用第三人称、长度为 60–1024 个字符,并包含触发条件。验证器无法强制执行但评审者会检查的规则:
- 先说明技能做什么,再用
Use when ...列出具体情形。 - 根据用户手头实际拥有的内容构建触发条件——文件名、魔数、框架和工具名称、错误字符串、具有识别性的症状,而不是抽象概念。
- 指明能将此技能与最相近技能区分开的证据。
# Good — names artifacts, tools, and the symptom
description: Reverse engineer and intercept traffic from Flutter/Dart mobile
apps using blutter, reFlutter, and Frida. Use when an APK or IPA contains
libflutter.so, libapp.so, App.framework, or flutter_assets, when jadx shows
only a thin Dart wrapper, or when Burp sees no traffic from an app that is
clearly online.
# Bad — overlaps the domain skill and triggers on the wrong requests
description: Advanced mobile reverse engineering techniques for modern apps.
第 4 步:编写正文
必需章节:
## When to Use——写明具体情境,而不是类别。## When NOT to Use——说明何时应使用其他技能,并将其同级技能名称用反引号括起来。这样可以避免技能争用相同的关键词。
安全技能还需包含:
## Rationalizations to Reject——列出那些听起来合理、却会导致漏掉发现的捷径,并逐条说明其错误之处。这是整个技能集里价值最高的章节;它体现了命令列表无法传达的判断力。
攻击性技能还需包含符合该领域实际暴露面的范围与授权说明,不要使用套话。侦察涉及第三方资产与作为个人数据的 OSINT;密码破解涉及账户锁定带来的可用性风险;无线电频谱工作涉及窃听与频谱法律,因为无线电信号无法局限在目标范围内。泛泛地说“先取得许可”毫无价值。
如果技能的工作流需要读取公开参考资料——公告、规范、RFC、供应商报告、ATT&CK 页面——请在 ## References 之前加入标准的 ## Reading External Sources 区块。从包含该区块的技能(producing-threat-intelligence、auditing-supply-chain)中原样复制;该区块在各技能中必须保持一致,以免出现偏差。它会通过 defuddle.md 处理公开文档,大幅节省令牌,并提供完整、可检索的文本。
不要将该区块加入网络活动针对目标的技能。云元数据端点、目标自身的服务、数据外传主机、网络钓鱼 URL 和 C2 都必须直接获取——经由第三方提取器处理会破坏命令、泄露行动 URL;对于活跃的对手基础设施,还会向操作者通风报信。
按步骤实际发生的先后顺序组织,并明确说明。 如果技能正文像一堆无序的技巧,就只会被抽样浏览,而不会被遵循。将最先执行的操作标为立即执行,依赖其输出的操作标为随后执行,接触目标的操作标为行动阶段——这样,中途加载技能的读者就知道当前该做什么。顺序还承载着安全保障:行动阶段中的任何操作都必须以获得授权为前提;只有各阶段区分明确,这一点才清晰可见。
技能是一套供人执行的指令,而不是一份读完即可的文档。 如果容易跳过第一步,就应在正文中明确指出这种失败模式:加载技能后只回复“已阅读并理解”就是一种失败。开篇要求“接触任何内容之前先记录范围”的技能,恰恰最容易被匆忙的读者概括带过,而不是实际执行。
写出判断依据,而不是帮助记忆:
| 写这个 | 别写这个 |
|---|---|
| 为什么选择某种技术而非其他技术,以及它何时会失效 | 一份工具参数列表 |
| 报告发现前必须通过哪些验证 | “报告漏洞” |
| 明确指出该领域容易出错之处 | 泛泛的最佳实践提醒 |
将 SKILL.md 控制在 600 行以内;将载荷列表和长表格移至 references/ 目录,仅在读者指向时才加载。不要串联引用:SKILL.md 可以指向一个参考文件,但该文件不得再引导读者去查看第三个文件。
注意:验证器会将每个用反引号括起来的参考路径解析为实际文件——因此,正文中的示例路径会导致构建失败。只写真实文件名。
第 5 步:在 ATT&CK 索引中注册
如果某项技能既未映射,也未声明为不映射,sync_attack.py 就会失败。 编辑 secskills-core/ttp-index.json,绝不要编辑 SKILL.md 中生成的区块。
进行映射——将该技能添加到它涵盖的每项技术的 skills 数组中:
{"id": "T1595", "name": "Active Scanning", "tactics": ["TA0043"],
"skills": ["performing-reconnaissance", "enumerating-network-services"]}
或者,说明为什么 Enterprise ATT&CK 不适用:
"_unmapped": {
"securing-ai-systems": "MITRE ATLAS (AML.T####) and the OWASP Top 10 for LLM / Agentic Applications"
}
然后重新生成——## ATT&CK Coverage 区块由程序生成,因此手动编辑始终是错误的:
python3 scripts/sync_attack.py --write
步骤 6:添加评估用例
路由确实可能出错;评估集就是用来捕获这些错误的。在
evals/cases.jsonl 中添加用例——每行一个 JSON 对象:
{"id": "adcs-esc1-certipy-vuln-template",
"query": "certipy find -vulnerable flagged a template with ENROLLEE_SUPPLIES_SUBJECT and low-priv enrollment — how do I turn this into domain admin?",
"expect_skill": "abusing-adcs",
"also_acceptable": ["attacking-active-directory"],
"expected_behavior": ["Identify this as an ESC1 escalation path",
"Request a cert specifying an alternate UPN",
"PKINIT with the cert to obtain the target's TGT/NT hash"],
"trap_for": ["attacking-active-directory", "attacking-kerberos-delegation"]}
按照真实用户的输入方式编写 query——包含工具输出、错误信息和手头的产物。经过净化的查询毫无证明力。
trap_for 是重要字段。 它列出此查询不得路由到的技能。每个新技能都应出现在至少一个相邻技能用例的 trap_for 中,并且自身至少要有一个用例,用来防止查询被路由到最接近的相邻技能。这是抑制描述逐渐泛化的唯一机制性约束。
步骤 7:验证
提交 PR 前,以下三项都必须通过:
python3 scripts/validate.py --strict # form, manifests, verified count
python3 scripts/sync_attack.py --check # ATT&CK blocks match the index
python3 scripts/run_evals.py --check # every skill covered, no bad refs
然后更新插件的 .claude-plugin/plugin.json 和
.claude-plugin/marketplace.json 中的版本——验证器会强制检查两者一致——并在
CHANGELOG.md 中添加条目。如果技能数量有变化,还要更新插件描述中的技能数量;数量不匹配时,validate.py 会发出警告。
步骤 8:不要盖上已验证的标记
新内容按定义就是未经验证的草稿。绝不要给刚写好的技能添加 verified: 日期。 将其交给
verifying-skill-accuracy,逐项将所有可核查的声明追溯到一手来源,并且只有在覆盖了全部内容后才盖章。
三个验证器全部通过,不等于完成验证。它们检查的是格式;本仓库的首次验证发现,即使 CI 全绿,文件中仍有 31 处事实错误。
应避免的借口
- “描述差不多就行;重要的是正文。” 从未加载的技能没有正文。描述质量是决定这项工作是否会被使用的最大因素。
- “我会把描述写得宽泛些,确保它能触发。” 宽泛的描述会抢走精确描述的相邻技能的流量,导致实际工作加载了错误的技能。精确性才能让整个集合协同运作。
- “这和现有技能有重叠,但我的覆盖得更好。” 那就修复现有技能。两个技能争夺同一个查询,会降低两者的效果。
- “大部分都是命令——这些规范不言自明。” 如果不言自明,就没必要写下来。模型本来就知道命令目录;它缺少的是判断力。
- “我手动添加 ATT&CK 块,更快。” 这是生成的内容。手动修改会在下次同步时被覆盖,而且在此之前无法通过
--check。 - “评估只是走个过场。” 在大型集合中,路由错误是最常见的实际故障,而
trap_for用例是捕获描述悄然变宽的唯一手段。 - “我测试过这些命令,所以它们已验证。” 在你的机器上测试只能确认它们在那里能运行,不能证明读者所用版本中的标识符、默认值和 ID 都正确。这需要单独验证。
参考资料
verifying-skill-accuracy——此步骤之后进行的事实核查关卡CONTRIBUTING.md——合并标准、项目风格和 PR 要求secskills-core/ttp-index.json——技术到技能的映射evals/README.md——评估工具和用例格式