From e7af1929c08ea49d4afb0df7e01199c043a5984f Mon Sep 17 00:00:00 2001 From: LYH Date: Fri, 15 May 2026 20:49:08 +0900 Subject: [PATCH] =?UTF-8?q?feat(cso):=20Phase=208=20Tier=203=20=E2=80=94?= =?UTF-8?q?=20mini-shai-hulud=20campaign=20rules=20(comprehensive=20mode)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds 4 detection rules for the 2026-05-11 npm/PyPI supply chain campaign (GHSA-g7cv-rxg3-hmpx / CVE-2026-45321) into Phase 8 (Skill Supply Chain). - R7 (Claude Code settings hook injection — /proc/*/mem read pattern) - R8 (obfuscated payload heuristic — _0x patterns + crypto-decode) - R9 (auto-run persistence bridge — manifest-undeclared file referenced by hook or tasks.json runOn: folderOpen) - R12 (Session-protocol C2 deny-list — executable context only) All rules surface only under /cso --comprehensive with TENTATIVE marking; daily mode's 8/10 zero-noise contract is preserved. Closes Phase 8 gaps for IDE-config infection vectors that the existing generic-pattern matching (curl/wget/exfiltrat/IGNORE PREVIOUS) does not catch. No new skill, no new phase, no scope-flag changes (per #1011). --- cso/SKILL.md | 14 ++++++++++++++ cso/SKILL.md.tmpl | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/cso/SKILL.md b/cso/SKILL.md index fe12df74e..8ba3e8641 100644 --- a/cso/SKILL.md +++ b/cso/SKILL.md @@ -1054,6 +1054,20 @@ If approved, run the same Grep patterns on globally installed skill files and ch **FP rules:** gstack's own skills are trusted (check if skill path resolves to a known repo). Skills that use `curl` for legitimate purposes (downloading tools, health checks) need context — only flag when the target URL is suspicious or when the command includes credential variables. +**Tier 3 — known-campaign IOCs (comprehensive mode only):** All rules in this tier surface only under `/cso --comprehensive` with TENTATIVE marking — daily mode's 8/10 zero-noise contract is unaffected. Rules below detect the 2026-05-11 "mini-shai-hulud" npm/PyPI supply chain campaign (GHSA-g7cv-rxg3-hmpx / CVE-2026-45321). + +**R7** — Any Claude Code settings file (`.claude/settings.json`, `.claude/settings.local.json`, or the user-global equivalents under `~/.claude/`) `hooks.*.command` field containing a `/proc/.*/mem` read pattern. Direct process-memory introspection from a Claude Code hook has no legitimate use; this is the exact technique used to extract the GitHub Actions Runner OIDC token in the campaign. + +**R8** — `.claude/**/*.{js,mjs,ts,cjs}` or `.vscode/**/*.{js,mjs,ts,cjs}` containing **both** the `_0x[0-9a-f]{4,}` variable pattern (≥3 distinct occurrences) **and** at least one of `createDecipheriv`, `gunzip`, `gunzipSync`, `inflateRawSync`, `inflateSync`. Matches the campaign's obfuscation + runtime-decrypt signature; minified bundles fail the `_0x` half, sourcemap-inline output fails both halves. + +**R9** — File under `.claude/**` or `.vscode/**` where **all three** hold: (a) referenced from any Claude Code settings file (`.claude/settings.json`, `.claude/settings.local.json`, or the user-global equivalents under `~/.claude/`) `hooks.*.command` via `node|bun|python3?|bash|sh ` or direct path invocation, **OR** from a `tasks.json` task with `runOptions.runOn: "folderOpen"`; (b) not declared in `package.json` `files`, the npm tarball, or any lockfile `integrity` hash; (c) not exempt by the Tier 3 FP guards below. Auto-run persistence bridge in TTP form — renaming the payload file does not evade. + +**R12** — Strings `filev2.getsession.org` or `seed{1,2,3}.getsession.org` appearing inside an executable context: a `hooks.*.command` value, a `tasks.json` `command`/`args` field, or a `fetch`/`http.get`/`axios`/`socket.connect`/`curl`/`nc` call inside a `.{js,mjs,ts,cjs,sh,py}` file under `.claude/**`/`.vscode/**`. Documentation or IOC-note mentions do not fire. + +**Tier 3 FP guards:** +- gstack-installed paths trusted: `~/.claude/skills/gstack/`, `~/.claude/skills/gstack-*/`, `~/.claude/hooks/` when content matches distributed checksums (extends the existing "gstack's own skills are trusted" precedent above). +- R9 excluded under `.vscode/extensions/` and inside any directory listed in the root `package.json` `workspaces` field. + ### Phase 9: OWASP Top 10 Assessment For each OWASP category, perform targeted analysis. Use the Grep tool for all searches — scope file extensions to detected stacks from Phase 0. diff --git a/cso/SKILL.md.tmpl b/cso/SKILL.md.tmpl index 2f849ee00..493bc321d 100644 --- a/cso/SKILL.md.tmpl +++ b/cso/SKILL.md.tmpl @@ -302,6 +302,20 @@ If approved, run the same Grep patterns on globally installed skill files and ch **FP rules:** gstack's own skills are trusted (check if skill path resolves to a known repo). Skills that use `curl` for legitimate purposes (downloading tools, health checks) need context — only flag when the target URL is suspicious or when the command includes credential variables. +**Tier 3 — known-campaign IOCs (comprehensive mode only):** All rules in this tier surface only under `/cso --comprehensive` with TENTATIVE marking — daily mode's 8/10 zero-noise contract is unaffected. Rules below detect the 2026-05-11 "mini-shai-hulud" npm/PyPI supply chain campaign (GHSA-g7cv-rxg3-hmpx / CVE-2026-45321). + +**R7** — Any Claude Code settings file (`.claude/settings.json`, `.claude/settings.local.json`, or the user-global equivalents under `~/.claude/`) `hooks.*.command` field containing a `/proc/.*/mem` read pattern. Direct process-memory introspection from a Claude Code hook has no legitimate use; this is the exact technique used to extract the GitHub Actions Runner OIDC token in the campaign. + +**R8** — `.claude/**/*.{js,mjs,ts,cjs}` or `.vscode/**/*.{js,mjs,ts,cjs}` containing **both** the `_0x[0-9a-f]{4,}` variable pattern (≥3 distinct occurrences) **and** at least one of `createDecipheriv`, `gunzip`, `gunzipSync`, `inflateRawSync`, `inflateSync`. Matches the campaign's obfuscation + runtime-decrypt signature; minified bundles fail the `_0x` half, sourcemap-inline output fails both halves. + +**R9** — File under `.claude/**` or `.vscode/**` where **all three** hold: (a) referenced from any Claude Code settings file (`.claude/settings.json`, `.claude/settings.local.json`, or the user-global equivalents under `~/.claude/`) `hooks.*.command` via `node|bun|python3?|bash|sh ` or direct path invocation, **OR** from a `tasks.json` task with `runOptions.runOn: "folderOpen"`; (b) not declared in `package.json` `files`, the npm tarball, or any lockfile `integrity` hash; (c) not exempt by the Tier 3 FP guards below. Auto-run persistence bridge in TTP form — renaming the payload file does not evade. + +**R12** — Strings `filev2.getsession.org` or `seed{1,2,3}.getsession.org` appearing inside an executable context: a `hooks.*.command` value, a `tasks.json` `command`/`args` field, or a `fetch`/`http.get`/`axios`/`socket.connect`/`curl`/`nc` call inside a `.{js,mjs,ts,cjs,sh,py}` file under `.claude/**`/`.vscode/**`. Documentation or IOC-note mentions do not fire. + +**Tier 3 FP guards:** +- gstack-installed paths trusted: `~/.claude/skills/gstack/`, `~/.claude/skills/gstack-*/`, `~/.claude/hooks/` when content matches distributed checksums (extends the existing "gstack's own skills are trusted" precedent above). +- R9 excluded under `.vscode/extensions/` and inside any directory listed in the root `package.json` `workspaces` field. + ### Phase 9: OWASP Top 10 Assessment For each OWASP category, perform targeted analysis. Use the Grep tool for all searches — scope file extensions to detected stacks from Phase 0.