diff --git a/docs/_source.html b/docs/_source.html index 2e90ea1..7c6f168 100644 --- a/docs/_source.html +++ b/docs/_source.html @@ -319,6 +319,7 @@ Reports Check your machine Install + If you're infected Commands Report a bug Install snare @@ -736,6 +737,94 @@

Pick your machine

+
+ Found something? +

What to do, in the order that matters

+

The instinct is to clean the repositories first. That is the wrong + order, and on an infected machine it is wasted work — this family injects into + commits on their way out, so it re-infects whatever you just cleaned.

+ +
+
    +
  1. 1 · Rotate your credentialsStealing them is the objective; the + file in your repository is delivery, not payload. Removing it does not un-steal + a token. npm write tokens first — a stolen one lets the worm publish + trojanised versions of your other packages under your name, which is how one + laptop becomes a supply-chain incident.
  2. +
  3. 2 · Clean the machine you push fromBefore touching any + repository. If several repositories are flagged, the common factor is almost + always the machine that pushed to them, not several separate accidents.
  4. +
  5. 3 · Then clean the repositoriessnare fix is a dry + run by default and always backs up first. Only add --push once you + have read what it would change.
  6. +
  7. 4 · Then tell your collaboratorsThey may be infected from the + same source, and if you rewrote history their clones will break with no + explanation.
  8. +
+ +

1 · Rotate

+
Do this first
+
snare rotate        # the ordered checklist, plus a GitHub audit
+

In order: npm tokens + (npmjs.com/settings/~/tokens — write and "bypass 2FA" first), then + GitHub PATs, OAuth apps and SSH keys, then cloud keys + (AWS — including Secrets Manager in every region you use — GCP, Azure), then + everything else the process could read: .env files in any project you + had open, kubeconfig, Vault tokens, database URLs, VPN, AI-service keys, wallet + keys and seed phrases. Finally your clipboard — this family has a + documented clipboard stealer, so a password pasted out of a manager while infected + should be treated as seen.

+ +

2 · Clean the machine

+
Before touching any repo
+
snare doctor          # machine, persistence spots, your GitHub account
+snare guard scan      # one-shot process check
+snare guard install   # kill the loader on sight, from login onwards
+

guard scan saying "clean" does not mean you + were never infected. It reports what is running right now. The + loader fires when a build runs or an editor opens the folder, does its work, and + exits. A clean process check alongside infected repositories is the expected + result, not a contradiction.

+ +

3 · Clean the repositories

+
Dry run first — always
+
snare fix owner/repo                        # dry run, changes nothing
+snare fix --all                             # dry run over everything flagged
+
+snare fix owner/repo --push                 # clean the branch tips
+snare fix owner/repo --purge-history --push # erase it from all history
+

--purge-history rewrites every commit, so every + SHA changes. Collaborators must delete their clone and re-clone; a + git pull will conflict or silently reintroduce old objects. Forks and + pull-request refs keep the old objects regardless — ask GitHub Support to + garbage-collect them if that matters to you.

+

Afterwards, verify rather than assume. snare scan github + only reads branch tips; run snare scan repo against a fresh clone to + walk full history.

+ +

4 · Tell the others

+
Contacts and templates
+
snare notify owner/repo             # list collaborators, preview the notice
+snare notify owner/repo --issue     # file a GitHub issue @-mentioning them
+snare notify owner/repo --mail      # open a pre-filled mail draft per person
+

Both templates lead with credential rotation and say plainly that + this is not an accusation: the malware injects from an already-infected machine, so + a collaborator whose commit carried it was almost certainly a victim rather than a + cause. Say that early, or you will not get the reply you need.

+ +

If a lot of repositories are flagged

+

Fifteen infected repositories is not fifteen accidents. It points at one machine + that pushed to all of them. Work out which machine that is before cleaning anything, + or you will clean the same repositories twice.

+

Worth knowing what you scaffold new projects with — a starter + template, a create-* command, a downloaded theme, an editor extension. + The delivery mechanism for this family is still unidentified, and + that is the single most useful thing anyone can contribute. If you find yours, + say so in the + discussion.

+
+
+
Reference

Every command, and what it will not do

diff --git a/docs/index.html b/docs/index.html index 9dcdb22..2524a6f 100644 --- a/docs/index.html +++ b/docs/index.html @@ -356,6 +356,7 @@ Reports Check your machine Install + If you're infected Commands Report a bug Install snare @@ -773,6 +774,94 @@

Pick your machine

+
+ Found something? +

What to do, in the order that matters

+

The instinct is to clean the repositories first. That is the wrong + order, and on an infected machine it is wasted work — this family injects into + commits on their way out, so it re-infects whatever you just cleaned.

+ +
+
    +
  1. 1 · Rotate your credentialsStealing them is the objective; the + file in your repository is delivery, not payload. Removing it does not un-steal + a token. npm write tokens first — a stolen one lets the worm publish + trojanised versions of your other packages under your name, which is how one + laptop becomes a supply-chain incident.
  2. +
  3. 2 · Clean the machine you push fromBefore touching any + repository. If several repositories are flagged, the common factor is almost + always the machine that pushed to them, not several separate accidents.
  4. +
  5. 3 · Then clean the repositoriessnare fix is a dry + run by default and always backs up first. Only add --push once you + have read what it would change.
  6. +
  7. 4 · Then tell your collaboratorsThey may be infected from the + same source, and if you rewrote history their clones will break with no + explanation.
  8. +
+ +

1 · Rotate

+
Do this first
+
snare rotate        # the ordered checklist, plus a GitHub audit
+

In order: npm tokens + (npmjs.com/settings/~/tokens — write and "bypass 2FA" first), then + GitHub PATs, OAuth apps and SSH keys, then cloud keys + (AWS — including Secrets Manager in every region you use — GCP, Azure), then + everything else the process could read: .env files in any project you + had open, kubeconfig, Vault tokens, database URLs, VPN, AI-service keys, wallet + keys and seed phrases. Finally your clipboard — this family has a + documented clipboard stealer, so a password pasted out of a manager while infected + should be treated as seen.

+ +

2 · Clean the machine

+
Before touching any repo
+
snare doctor          # machine, persistence spots, your GitHub account
+snare guard scan      # one-shot process check
+snare guard install   # kill the loader on sight, from login onwards
+

guard scan saying "clean" does not mean you + were never infected. It reports what is running right now. The + loader fires when a build runs or an editor opens the folder, does its work, and + exits. A clean process check alongside infected repositories is the expected + result, not a contradiction.

+ +

3 · Clean the repositories

+
Dry run first — always
+
snare fix owner/repo                        # dry run, changes nothing
+snare fix --all                             # dry run over everything flagged
+
+snare fix owner/repo --push                 # clean the branch tips
+snare fix owner/repo --purge-history --push # erase it from all history
+

--purge-history rewrites every commit, so every + SHA changes. Collaborators must delete their clone and re-clone; a + git pull will conflict or silently reintroduce old objects. Forks and + pull-request refs keep the old objects regardless — ask GitHub Support to + garbage-collect them if that matters to you.

+

Afterwards, verify rather than assume. snare scan github + only reads branch tips; run snare scan repo against a fresh clone to + walk full history.

+ +

4 · Tell the others

+
Contacts and templates
+
snare notify owner/repo             # list collaborators, preview the notice
+snare notify owner/repo --issue     # file a GitHub issue @-mentioning them
+snare notify owner/repo --mail      # open a pre-filled mail draft per person
+

Both templates lead with credential rotation and say plainly that + this is not an accusation: the malware injects from an already-infected machine, so + a collaborator whose commit carried it was almost certainly a victim rather than a + cause. Say that early, or you will not get the reply you need.

+ +

If a lot of repositories are flagged

+

Fifteen infected repositories is not fifteen accidents. It points at one machine + that pushed to all of them. Work out which machine that is before cleaning anything, + or you will clean the same repositories twice.

+

Worth knowing what you scaffold new projects with — a starter + template, a create-* command, a downloaded theme, an editor extension. + The delivery mechanism for this family is still unidentified, and + that is the single most useful thing anyone can contribute. If you find yours, + say so in the + discussion.

+
+
+
Reference

Every command, and what it will not do

diff --git a/lib/guard.sh b/lib/guard.sh index 7a7f511..3142761 100644 --- a/lib/guard.sh +++ b/lib/guard.sh @@ -214,20 +214,68 @@ UNIT # ---- Windows (Git Bash): Scheduled Task ---------------------------------- guard_svc_schtasks(){ - local name="snare-guard" bash_exe + local name="snare-guard" bash_exe snare_sh err rc bash_exe="$(command -v bash)" + snare_sh="$SNARE_ROOT/bin/snare" + + # schtasks.exe is a Windows program: it needs a Windows path for the + # executable. Handing it an MSYS path like /usr/bin/bash fails, and the old + # code discarded stderr so the user only ever saw "could not create the + # scheduled task" with nothing to act on. + if command -v cygpath >/dev/null 2>&1; then + bash_exe="$(cygpath -w "$bash_exe" 2>/dev/null || command -v bash)" + fi + # MSYS_NO_PATHCONV stops MSYS rewriting /TN and friends into paths. + export MSYS_NO_PATHCONV=1 + case "$1" in install) - schtasks //Create //TN "$name" //SC ONLOGON //RL LIMITED //F \ - //TR "\"$bash_exe\" -lc 'snare guard run --interval 1'" >/dev/null 2>&1 \ - && grn "scheduled task '$name' created (runs at logon)" || red "could not create the scheduled task" - schtasks //Run //TN "$name" >/dev/null 2>&1 && grn "started" ;; - uninstall) schtasks //Delete //TN "$name" //F >/dev/null 2>&1 && ylw "guard uninstalled" ;; - start) schtasks //Run //TN "$name" >/dev/null 2>&1 && grn "started" ;; - stop) schtasks //End //TN "$name" >/dev/null 2>&1 && ylw "stopped" ;; + err="$(schtasks /Create /TN "$name" /SC ONLOGON /RL LIMITED /F \ + /TR "\"$bash_exe\" -c \"'$snare_sh' guard run --interval 1\"" 2>&1)"; rc=$? + if [ "$rc" = 0 ]; then + grn "scheduled task '$name' created (runs at logon)" + schtasks /Run /TN "$name" >/dev/null 2>&1 && grn "started" + return 0 + fi + red "could not create the scheduled task" + [ -n "$err" ] && echo "$err" | sed 's/^/ /' + echo + # A Startup-folder shortcut needs no privileges and no Task Scheduler. + ylw " Falling back to a Startup entry (no admin rights needed)." + local startup + startup="$(cygpath -u "$APPDATA" 2>/dev/null)/Microsoft/Windows/Start Menu/Programs/Startup" + if [ -d "$startup" ]; then + cat > "$startup/snare-guard.bat" </dev/null 2>&1 && ylw "guard uninstalled" + local startup + startup="$(cygpath -u "$APPDATA" 2>/dev/null)/Microsoft/Windows/Start Menu/Programs/Startup" + [ -f "$startup/snare-guard.bat" ] && { rm -f "$startup/snare-guard.bat"; ylw "startup entry removed"; } + return 0 ;; + start) schtasks /Run /TN "$name" >/dev/null 2>&1 && grn "started" || \ + dim "start it manually: snare guard run --interval 1 &" ;; + stop) schtasks /End /TN "$name" >/dev/null 2>&1 && ylw "stopped" ;; status) - if schtasks //Query //TN "$name" >/dev/null 2>&1; then grn "scheduled task '$name' registered" - else ylw "guard not registered — 'snare guard install'"; fi + if schtasks /Query /TN "$name" >/dev/null 2>&1; then grn "scheduled task '$name' registered" + else + local startup + startup="$(cygpath -u "$APPDATA" 2>/dev/null)/Microsoft/Windows/Start Menu/Programs/Startup" + if [ -f "$startup/snare-guard.bat" ]; then grn "startup entry registered" + else ylw "guard not registered — 'snare guard install'"; fi + fi _guard_common_status ;; esac } diff --git a/lib/notify.sh b/lib/notify.sh index 81f633d..875fa47 100644 --- a/lib/notify.sh +++ b/lib/notify.sh @@ -53,13 +53,41 @@ grep -rn "folderOpen" .vscode/tasks.json 2>/dev/null head -c 4 public/fonts/*.woff2 2>/dev/null # a real font prints wOF2 \`\`\` -### Then +### Then, in this order + +**1. Rotate your credentials first.** Stealing them is what this family is *for* — +the file in the repository is delivery, not payload. Removing it does not +un-steal a token. + +- **npm tokens first** — https://www.npmjs.com/settings/~/tokens — start with + write / "bypass 2FA". A stolen npm token lets the worm publish trojanised + versions of *your other packages* under your name. This is the step that + stops one machine becoming a supply-chain incident. +- GitHub PATs and OAuth apps — https://github.com/settings/tokens — and SSH + keys — https://github.com/settings/keys +- Cloud keys (AWS — check Secrets Manager per region — GCP, Azure) +- \`.env\` files in any project you had open, kubeconfig, Vault, database URLs, + VPN, AI-service keys, wallet keys and seed phrases +- **Your clipboard.** This family has a documented clipboard stealer; a password + pasted out of a manager while infected should be treated as seen. + +**2. Check your own machine before you clean anything.** This family injects +into commits *from an already-infected machine*, so cleaning a repository while +your machine is still infected just re-injects into it. -1. **Delete your local clone and re-clone.** If history was rewritten, a \`git pull\` - will conflict — you must re-clone. -2. **Rotate credentials**: GitHub tokens (github.com/settings/tokens), SSH keys, - npm tokens, \`.env\` values, and anything copied to your clipboard. -3. Check your GitHub account for repos, keys or OAuth apps you did not create. +\`\`\`bash +snare doctor # this machine, persistence spots, your account +snare guard scan # one-shot process check +snare rotate # the checklist above, plus a GitHub audit +\`\`\` + +**3. Delete your local clone and re-clone.** If history was rewritten a +\`git pull\` will conflict — you must re-clone, not pull. + +**4. Check your GitHub account** for repositories, keys, OAuth apps or Actions +workflows you did not create. This family leaves behind a workflow that +exfiltrates secrets on every push, and it survives long after the dropper is +removed. Scanned and cleaned with [snare](https://github.com/) — \`snare scan repo .\` to check your own clones. MD @@ -149,10 +177,35 @@ PLEASE CHECK: grep -rn "0xa322E5f3D311D3080e6f0121063e9aDC2490Ef1a" . head -c 4 public/fonts/*.woff2 -THEN: -- Delete old clones and re-clone (a pull may conflict if history was rewritten). -- Rotate GitHub tokens, SSH keys, npm tokens, .env values, and anything you - copied to your clipboard. Check your account for repos/keys you did not create. +THEN, IN THIS ORDER: + +1. ROTATE YOUR CREDENTIALS FIRST. Stealing them is what this family is for - + the file in the repo is delivery, not payload. Removing it does not + un-steal a token. + - npm tokens first (write / "bypass 2FA"): + https://www.npmjs.com/settings/~/tokens + A stolen npm token lets it publish trojanised versions of your other + packages under your name. + - GitHub PATs and OAuth apps: https://github.com/settings/tokens + - SSH keys: https://github.com/settings/keys + - Cloud keys (AWS - check Secrets Manager per region - GCP, Azure) + - .env files, kubeconfig, Vault, database URLs, VPN, AI-service keys, + crypto wallet keys and seed phrases + - Your clipboard: this family has a clipboard stealer, so anything you + copied while infected should be treated as seen. + +2. CHECK YOUR MACHINE before cleaning any repo - this family injects from an + already-infected machine, so cleaning first just lets it re-inject: + snare doctor + snare guard scan + snare rotate + +3. Delete old clones and re-clone (a pull will conflict if history was + rewritten - you must re-clone, not pull). + +4. Check your GitHub account for repos, keys, OAuth apps or Actions workflows + you did not create. This family leaves a workflow that exfiltrates secrets + on every push and survives the dropper being removed. Happy to walk you through it. """