Skip to content

Commit b3aea58

Browse files
author
HackTricks News Bot
committed
Add content from: What the Miasma Campaign Reveals About the New Supply Chain ...
1 parent 901f745 commit b3aea58

1 file changed

Lines changed: 41 additions & 0 deletions

File tree

  • src/pentesting-ci-cd/github-security/abusing-github-actions

src/pentesting-ci-cd/github-security/abusing-github-actions/README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,43 @@ import base64,os;exec(base64.b64decode(os.environ["STAGE2_B64"]))
745745

746746
Drop the line above into a file such as `evil.pth` inside `site-packages` and it will execute during Python startup. This is especially useful in build agents that continuously spawn Python tooling (`pip`, linters, test runners, release scripts).
747747

748+
#### `binding.gyp` / node-gyp execution (`Phantom Gyp`)
749+
750+
Not every install-time execution path lives in `package.json` lifecycle hooks. `node-gyp`'s `configure` step looks for a `binding.gyp` file in the package directory, so a compromised publisher can shift execution into the native build path and bypass controls that only audit `preinstall` / `postinstall`.
751+
752+
Practical implications during an assessment:
753+
754+
- Inspect the **published tarball**, not only the Git repo, for unexpected `binding.gyp`, `node-gyp`, or native-addon metadata in packages that should be pure JavaScript.
755+
- Treat a sudden `binding.gyp` addition as an **execution primitive**, especially if defenders rely on lifecycle-hook monitoring or `--ignore-scripts` as their main intake control.
756+
- Review release jobs that run `npm install`, `npm rebuild`, or other dependency build steps after restoring untrusted artifacts/caches, because a poisoned package can move execution to the native-build path.
757+
758+
#### Wormable npm publishing from CI / stolen maintainer identities
759+
760+
Once code runs in a maintainer workstation or release workflow, a single stolen registry identity can be turned into **self-propagating package compromise**:
761+
762+
1. Harvest maintainer secrets (`~/.npmrc`, PATs, OIDC request env vars, cloud creds, SSH keys).
763+
2. Enumerate which packages the compromised identity or team can publish to.
764+
3. Republish malicious versions across each writable package so downstream `npm install` executions create more credential-generation nodes.
765+
766+
This becomes more dangerous when the release workflow uses **trusted publishing**: if the attacker steals the GitHub Actions OIDC material from a job with `id-token: write`, the poisoned release can still receive **valid provenance** because the legitimate workflow really built it. Provenance answers _which workflow built this artifact_, not _whether the workflow/source tree was clean_.
767+
768+
Useful checks:
769+
770+
- Look for workflows that combine `id-token: write` with `npm publish`, `changesets`, or release bots and **do not require a human approval step**.
771+
- Check whether the compromised identity can enumerate org/team package access (for example with `npm access ls-packages`) and whether package publishing bypasses 2FA.
772+
- Add friction to the propagation loop with **staged publishing** / human 2FA approval and `minimumReleaseAge` quarantine before consuming newly published versions.
773+
774+
#### Repository-local AI assistant persistence
775+
776+
A compromised publisher or repo writer does not need to stop at install-time execution. Another persistence layer is to commit **assistant instruction/config files** into the repository so the next developer who opens the project feeds attacker-controlled instructions into local tooling. High-signal paths include:
777+
778+
- `.claude/settings.json`
779+
- `.cursor/rules`
780+
- `.gemini/`
781+
- editor/IDE task or settings files that steer AI helpers
782+
783+
This is useful after CI compromise because the attacker can push those files with a stolen maintainer token, and the trigger later becomes **repository open / assistant load** instead of `npm install`. During reviews, diff for new assistant-policy files with the same suspicion level as new workflow files or build scripts.
784+
748785
#### Alternate exfil when outbound traffic is filtered
749786

750787
If direct exfiltration is blocked but the workflow still has a write-capable `GITHUB_TOKEN`, the runner can abuse GitHub itself as the transport:
@@ -958,8 +995,12 @@ An organization in GitHub is very proactive in reporting accounts to GitHub. All
958995
- [A Survey of 2024–2025 Open-Source Supply-Chain Compromises and Their Root Causes](https://words.filippo.io/compromise-survey/)
959996
- [Weaponizing the Protectors: TeamPCP’s Multi-Stage Supply Chain Attack on Security Infrastructure](https://unit42.paloaltonetworks.com/teampcp-supply-chain-attacks/)
960997
- [Mini Shai-Hulud: Frequently asked questions about the TeamPCP npm and PyPI supply chain campaign](https://www.tenable.com/blog/mini-shai-hulud-frequently-asked-questions)
998+
- [What the Miasma campaign reveals about the new supply chain threat model and the underground market for developer credentials](https://www.tenable.com/blog/what-the-miasma-campaign-reveals-about-the-new-supply-chain-threat-model-and-the-underground)
961999
- [Events that trigger workflows - GitHub Docs](https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows)
9621000
- [Trusted publishing for npm packages | npm Docs](https://docs.npmjs.com/trusted-publishers/)
1001+
- [Staged publishing for npm packages | npm Docs](https://docs.npmjs.com/staged-publishing/)
9631002
- [Generating provenance statements | npm Docs](https://docs.npmjs.com/generating-provenance-statements/)
1003+
- [npm orgs | npm Docs](https://docs.npmjs.com/using-npm/orgs.html)
1004+
- [node-gyp README](https://github.com/nodejs/node-gyp)
9641005

9651006
{{#include ../../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)