dotgibson/htpx

GitHub: dotgibson/htpx

一个 ATT&CK 标签标注的红蓝队配对语料库与终端浏览工具,让攻击手法与检测方法可并排查阅、按需填充并一键复制。

Stars: 0 | Forks: 0

# ⚔️ htpx **每一次攻击,连同其检测。** 一个带有 ATT&CK 标签、红队↔蓝队配对的 语料库 —— 在浏览攻击时查看其对应的检测方法,填充 `{{slots}}`,并剪贴。 `fzf` · `mitre-attack` · `purple-team` [![showcase](https://img.shields.io/badge/showcase-live-7aa2f7?style=flat-square)](https://dotgibson.github.io/dotfiles-web/) ![purple team](https://img.shields.io/badge/purple--team-bb9af7?style=flat-square) **companion** — 结构化的、带 ATT&CK 标签的、红队↔蓝队配对的渗透测试参考 将攻击性语料库重构为机器可读的条目,以便相同的内容可以**被搜索、打上 ATT&CK 标签、进行目标替换,并与其 蓝队检测相配对** —— 这正是独立终端 companion 应有的形态。 对于其所涵盖的配对红队↔蓝队**攻击/检测切片,条目就是 事实来源**:当它们与 `hacktheplanet` / `PURPLE-TEAM.md` 存在交集时,扁平文件的代码块是从条目中*生成*的(位于 `companion:gen` 标记内),且 CI 会拒绝任何偏移。扁平文件中那些*不属于*干净的配对 攻击的内容 —— 技术文章、dorks、多步骤链 —— 仍保持手写并 作为权威来源。完整的模型请参阅下文的_事实来源_。 ## 这里有什么 ``` companion/ ├── htpx # fzf browser: search → preview attack + its detection → fill slots → clip ├── gen-views.sh # render entry-backed blocks into the flat views (+ --check drift gate) └── entries/ ├── red/*.md # attacks (frontmatter + command template) └── blue/*.md # detections (frontmatter + SPL), paired back to red ``` 此目录是**主机无关的**(主机无关是因为它存放在自己的代码库 `dotgibson/htpx` 中,并像 `core/` 一样被 vendored 回来):`gen-views.sh` 的扁平视图目标默认指向 此代码库的 `PURPLE-TEAM.md` + `offensive/hacktheplanet`(相对于代码库根目录),但 可以通过 `$COMPANION_TARGETS` 进行覆盖(如果目标不存在则会被跳过,因此即使在没有扁平视图的独立 checkout 下,状态依然是绿色的),并且 `htpx` 会通过它找到的第一个 `clip`/`pbcopy`/`wl-copy`/`xclip`/`xsel` 进行复制(否则输出到 stdout),而不是 要求使用 Core 的 `clip` 助手。 ## 条目 schema(Markdown + YAML frontmatter) 顶部是类型化的元数据(可被 grep、`yq` 查询);正文是 原始的复制粘贴内容(可在 `bat`/`glow` 中渲染,可被 `rg` 搜索)。每个条目一个文件。 ``` id: stable kebab key title: human label section: matches a hacktheplanet fold name phase: engagement phase attack: { tactic: TA0006, techniques: [T1558.003] } # MITRE ATT&CK platform: [windows, linux, network] source: citation pair: # or null ``` 命令模板将语料库的 `` 占位符标准化为 `{{slots}}`(`{{rhost}}`、`{{lhost}}`、`{{user}}`、`{{password}}`、`{{domain}}`、 `{{hostname}}`、`{{nthash}}`、`{{port}}`、`{{share}}`)。 ## 使用方法 ``` export RHOST=10.10.10.5 DOMAIN=corp.local USER_T=svc_sql PASS='…' htpx # pick an attack; preview shows it + its blue detection; # the command is slot-filled and copied via `clip` ``` `htpx` 在 bootstrap 后即可在 shell 中使用:`companion/` 符号链接到 `~/companion`, 并且 `offensive.zsh` 定义了一个 `htpx` 函数。从 checkout 处你也可以直接运行 `./htpx`。它需要 `fzf`;如果存在 `bat`(预览)和 `clip`(Core 剪贴板)则会 使用它们,否则回退到 `cat`/stdout。没有 `yq` 依赖 —— `htpx` 仅使用 `awk` 读取它所需的 frontmatter 中的标量顶级字段(`title:`、`pair:`)(嵌套的 `attack:` 块是供人类/grepper 使用的)。 ## 差异化优势 `pair:` 字段使得 **purple pivot** 几乎零成本:选择一个攻击即可 在其旁边预览其检测方法(参见 Kerberoast ↔ `4769`,DCSync ↔ `4662`)。 没有主流工具会将攻击与它们触发的遥测数据配对提供。 ## 语料库 71 个配对概念 + 1 个未配对的侦察条目(SMB enum),涵盖 Credential Access、Privilege Escalation、Lateral Movement、Persistence、Execution、Defense Evasion、Collection、Exfiltration 和 Discovery —— 包括本地 AD、多云切片 (Entra/M365、AWS、GCP)、Kubernetes、Okta、Google Workspace、CI/CD(GitHub Actions、 GitLab、Jenkins)、Harbor 容器注册表、HashiCorp Vault、Terraform Cloud、 Snowflake 数据云、Cloudflare 边缘网络、npm + PyPI 包注册表, 以及 Slack: | Attack (red) | Detection (blue) | ATT&CK | | --------------------------------- | ----------------------------------------------------- | --------- | | Kerberoast SPNs | `4769` RC4 TGS | T1558.003 | | AS-REP roast | `4771` pre-auth `0x18` | T1558.004 | | Password spray (kerbrute) | `4625` one source, many accounts | T1110.003 | | DCSync | `4662` replication | T1003.006 | | Pass-the-hash lateral | `4624` type-3 fan-out | T1550.002 | | NTLM relay | `4624` workstation mismatch | T1557.001 | | Coerce DC (PetitPotam/printerbug) | `5145` named-pipe access | T1187 | | AD CS ESC1 (certipy) | `4886` SAN mismatch | T1649 | | Remote LSASS dump (lsassy) | `4656` dump-shaped handle | T1003.001 | | RDP session hijack (tscon) | `4688` tscon `/dest:rdp-tcp#` | T1563.002 | | Shadow Credentials (certipy) | `5136` msDS-KeyCredentialLink write | T1556 | | RBCD (impacket) | `5136` msDS-AllowedToActOnBehalfOfOtherIdentity write | T1098 | | Unconstrained delegation → DC TGT | `4624` DC machine-acct → non-DC _(soft)_ | T1558 | | DPAPI domain backup key | `5145` protected_storage pipe | T1555 | | SeImpersonate → SYSTEM (Potato) | `4688` service-acct → SYSTEM shell _(moderate)_ | T1134.001 | | Device-code phishing (Entra) | Entra sign-in `deviceCode` flow _(KQL, cloud)_ | T1528 | | Golden Ticket (forged TGT) | `4769` TGS with no preceding `4768` | T1558.001 | | GPP cpassword (SYSVOL) | `5145` SYSVOL `Groups.xml` read | T1552.006 | | NTDS.dit dump (ntdsutil/VSS) | `4688` ntdsutil/vssadmin + `8222` | T1003.003 | | WMI exec (impacket-wmiexec) | `4688` `WmiPrvSE.exe` child shell | T1047 | | Scheduled-task persistence | `4698` task created (suspicious action) | T1053.005 | | WMI subscription persistence | Sysmon `19`/`20`/`21` consumer/binding | T1546.003 | | Silver Ticket (forged TGS) | `4624` Kerberos logon, no `4769` _(soft)_ | T1558.002 | | DCShadow (rogue DC) | `4742` `GC/` SPN write + `5137`/`4662` | T1207 | | Illicit consent grant (Entra) | Entra audit "Consent to application" _(KQL, cloud)_ | T1528 | | SP credential backdoor (Entra) | Entra audit "Add SP credentials" _(KQL, cloud)_ | T1098.001 | | Privileged pod → node escape (K8s) | audit: privileged/hostPID/hostPath pod create | T1610/T1611 | | Pod exec / attach (K8s) | audit: `pods/exec` subresource create | T1609 | | Cluster-admin binding (K8s) | audit: roleRef `cluster-admin` binding | T1098 | | MFA reset → takeover (Okta) | System Log `user.mfa.factor.reset_all` | T1556.006 | | API token persistence (Okta) | System Log `system.api_token.create` | T1098 | | Rogue IdP backdoor (Okta) | System Log `system.idp.lifecycle.create` | T1556 | | IAM access-key backdoor (AWS) | CloudTrail `CreateAccessKey` actor≠target _(cloud)_ | T1098.001 | | Console takeover (AWS) | CloudTrail Create/UpdateLoginProfile _(cloud)_ | T1098 | | SA key creation (GCP) | Cloud Audit `CreateServiceAccountKey` _(cloud)_ | T1098.001 | | Rogue self-hosted runner (GitHub) | audit `self_hosted_runner.created` _(cloud)_ | T1543 | | Branch-protection tamper (GitHub) | audit `protected_branch.destroy` / `protected_branch.policy_override` _(cloud)_ | T1562.001 | | Deploy-key/PAT backdoor (GitHub) | audit `repo.create_deploy_key` / `personal_access_token.access_granted` _(cloud)_ | T1098 | | Backdoored image over trusted tag (Harbor) | audit `operation=push` artifact _(registry)_ | T1525 | | Robot-account backdoor (Harbor) | audit `operation=create` `resource_type=robot` _(registry)_ | T1098 | | Artifact deletion (Harbor) | audit `operation=delete` artifact/repository _(registry)_ | T1070 | | Rogue runner association (GitLab) | audit `set_runner_associated_projects` _(cloud)_ | T1543 | | Protected-branch tamper (GitLab) | audit `protected_branch_removed` / `protected_branch_created` _(cloud)_ | T1562.001 | | Access/deploy-token backdoor (GitLab) | audit `project_access_token_created` / `personal_access_token_created` / `deploy_token_created` _(cloud)_ | T1098 | | Bulk KV secret read (Vault) | audit `read` breadth over `secret/` paths _(secrets)_ | T1555 | | Rogue AppRole backdoor (Vault) | audit create/update on `auth/approle/role/` _(secrets)_ | T1098 | | Audit-device disable (Vault) | audit `delete` on `sys/audit/` path _(secrets)_ | T1562.001 | | Rogue agent pool (Terraform) | audit `agent_pool` `create` _(IaC)_ | T1543 | | Org/team token backdoor (Terraform) | audit `authentication_token` `create` _(IaC)_ | T1098 | | Variable injection (Terraform) | audit `variable` `create`/`update` _(IaC)_ | T1072 | | Script Console RCE (Jenkins) | audit `/script`/`/scriptText` request _(CI)_ | T1059 | | User API token backdoor (Jenkins) | audit `generateNewToken` request _(CI)_ | T1098 | | Job/pipeline backdoor (Jenkins) | audit `/createItem`/`/job//configSubmit` request _(CI)_ | T1072 | | Data exfil via COPY INTO (Snowflake) | `QUERY_HISTORY` `QUERY_TYPE=UNLOAD` _(data)_ | T1567.002 | | Backdoor user + ACCOUNTADMIN (Snowflake) | `QUERY_HISTORY` `CREATE_USER`/priv `GRANT` _(data)_ | T1136.003 | | Network-policy tamper (Snowflake) | `QUERY_HISTORY` `NETWORK POLICY` change _(data)_ | T1562.007 | | Illicit OAuth grant (Workspace) | token audit `authorize` _(cloud)_ | T1528 | | Super-admin grant (Workspace) | admin audit `GRANT_DELEGATED_ADMIN_PRIVILEGES` _(cloud)_ | T1098.003 | | External mail forwarding (Workspace) | `email_forwarding_out_of_domain` _(cloud)_ | T1114.003 | | API token backdoor (Cloudflare) | audit `resource.type=api_token` `create` _(edge)_ | T1098 | | WAF/firewall rule disable (Cloudflare) | audit `firewall_rule`/`ruleset` `delete`/`update` _(edge)_ | T1562.001 | | Malicious Worker deploy (Cloudflare) | audit `resource.type=worker`/`workers_script` `create`/`update` _(edge)_ | T1648 | | Malicious package publish (npm) | audit `package.publish` off-CI actor _(registry)_ | T1195.002 | | Rogue maintainer add (npm) | audit `package.owner_add` / `team.user_add` _(registry)_ | T1098 | | Publish-2FA disable (npm) | audit `package.edit` `mfa=none` _(registry)_ | T1562.001 | | Malicious release upload (PyPI) | journal `new release` not via trusted publisher _(registry)_ | T1195.002 | | Rogue collaborator add (PyPI) | journal `add Owner` / `add Maintainer` _(registry)_ | T1098 | | Rogue trusted publisher (PyPI) | journal add `trusted publisher` _(registry)_ | T1098 | | Malicious app install (Slack) | audit `app_installed` broad scopes _(SaaS)_ | T1098 | | External shared channel (Slack) | audit `shared_channel_invite_sent` _(SaaS)_ | T1567 | | 2FA enforcement disable (Slack) | audit `pref.two_factor_auth_changed` off _(SaaS)_ | T1562.001 | 既然有了偏移检测门,语料库的扩展就变得机械化:编写红队+蓝队条目 配对,标记匹配的扁平块,然后运行 `gen-views.sh`。对于**本地**配对, 蓝队检测会生成到 `PURPLE-TEAM.md` 中(云配对仅属于 companion —— 见下文)。当命令可映射到插槽时,红队部分会生成到 `hacktheplanet` 中(即使是多步骤也是如此 —— 见 RBCD); 只有带有内联注释或分散在现有折叠部分的命令才会保持手写。 无论哪种方式,条目都驱动着 `htpx` 和配对 预览。**全新**的技术(Shadow Credentials、RBCD)首先被编写为 条目,然后通过桥接流入*两个*扁平视图。 **云配对仅属于 companion。** Device-code-phishing 配对是本地 AD 之外的第一个 实例:其检测是 Entra 登录日志(KQL),这不应放在 `PURPLE-TEAM.md` 的 Windows 安全日志 SPL 框架中,因此它不会生成到 任何扁平视图中 —— 它只存在于条目中,在那里 `htpx` 仍然提供 完整的 purple pivot。这清楚地证明了条目是本地扁平引用的超集(并且是独立/云端拆分后的自然接缝)。 ## 事实来源(已决定 —— 混合模式) “条目是否将成为权威?”这一问题已经**解决**,但并不是 最初的二元模式。`hacktheplanet` 有 489 行,其中大部分是_技术文章_ —— dorks、枚举排序、条件建议、警告 —— 这些都不符合 条目 schema;从死板的条目生成整个文件要么会丢失这些 文章,要么会使 schema 臃肿成自由格式的 markdown。因此: - **对于配对的红队↔蓝队攻击/检测切片,条目是权威的。** 那部分才是真正符合 `{id, title, attack, command}` 结构,并且 能从 ATT&CK 标签、插槽填充和 purple pivot 中受益的部分。 - **扁平文件在其他所有方面保持权威** —— schema 无法承载的 文章。 - **在存在交集的地方,条目通过生成优先。** 扁平文件使用 `companion:gen ID` … `companion:end ID` 标记选择加入一个块 —— markdown 中的 HTML 注释(`PURPLE-TEAM.md`), 即 shell 风格的 `hacktheplanet` 中的 `#` 注释。 `gen-views.sh` 会从条目重新生成被标记的块,并且 `gen-views.sh --check`(在 CI 中运行,`.github/workflows/companion.yml`)会在发生偏移时 失败。标记之外的内容永远不会被触碰。 这在交集处消除了偏移,_既不需要_进行 60 个条目的迁移,_也无需_ 放弃丰富的文章。工作流程:编辑条目 → `gen-views.sh` → 提交两者。 **两端已连接。** 渲染形态取决于条目的颜色: - **蓝队**(`PURPLE-TEAM.md`) —— `**title**` + 文章 + 围栏 `spl` 检测 块。它的 SPL 没有目标插槽,因此没有占位符转换。 - **红队**(`hacktheplanet`) —— 仅包含该文件简洁的、 命令优先的内部风格中的原始命令行,条目的 `{{slots}}` 会反向映射到它的 `` 词汇表(`{{rhost}}`→``,`{{nthash}}`→``, …;见 `gen-views.sh` 中的 `SLOT_TO_ANGLE`)。仅标记命令连续且 干净映射的攻击(Kerberoast、AS-REP、DCSync);对于行分散在折叠部分或带有 内联注释的攻击(SMB enum、pass-the-hash) 保持手写 —— 条目仅拥有它能干净拥有的部分。 ## 待定决策(在从 MVP 毕业之前) 1. **ATT&CK 标注是 100% 手动的** —— 目前没有任何来源包含技术 ID。 用_相同的_技术 ID 标注两种颜色会将 `pair:` 变成一个 可推导的关联(而不仅仅是一个手动维护的链接)。 2. **独立 vs 代码库内 —— 已解决。** 它现在存放在自己的代码库 (`dotgibson/htpx`)中,并通过 `git subtree` 被 vendored 回 `dotfiles-Kali` 的 `offensive/companion/` 中(来源记录在 Kali 的 `companion.lock` 中, 通过 `scripts/sync-companion.sh` 重新同步)。Kali 消费它;此代码库是 事实来源。
标签:AMSI绕过, Cutter, 威胁检测, 紫队, 防御加固