A second wave of the moika.tech operation surfaces twelve fresh Beacon packages targeting two more private scopes. The playbook hasn't changed.
Two days ago we documented the moika.tech dependency-confusion campaign: 318 packages, two payload families, and a Russian-nexus operator squatting the private package names of banks and payment processors. We expected more scopes to follow. They did.
This week we pulled twelve more tarballs off the public registry, published under two scopes we hadn't seen before: @ccrm/*-api-axios and @emcd-vue/*. Every one is the same postinstall beacon, re-obfuscated per build, phoning the same oob[.]moika[.]tech infrastructure. No new tricks, just new targets. Our detection engine flagged all twelve within 7 minutes of publication. This is a short follow-up to put the new indicators on the record and confirm the attribution holds.
The attack mechanics are unchanged from the first wave; see Inside the moika.tech Dependency Confusion Campaign for a full breakdown. Each package is a functional decoy with a 76-byte stub library and the real cargo in a postinstall lifecycle hook, dressed with plausible-looking metadata (platform@ccrm.io, github.ccrm.io, jira.ccrm.io) that doesn't resolve.
This wave is all Beacon
Our previous report split the campaign into the Beacon (a lightweight recon stub that pulls and runs a second stage) and the Dropper (a heavier package that sweeps ~12 categories of local credentials before exfil). Every one of these twelve is a Beacon. The tell is baked into the payload:
Stage 1 performs no credential collection itself. It fingerprints the host, fetches an OS-specific second stage from the C2, and hands off. Whatever harvesting happens, happens in stage 2, served live from oob[.]moika[.]tech and consistent with the wave-one RAT based on shared C2 infrastructure.
Inside the beacon
Below is the deobfuscated stage-1 loader (renamed and commented; the shipped file is obfuscator.io-hardened (rotated string array, base64 string decoder, arithmetic-encoded constants, and a per-build randomised index offset) so the twelve files are byte-different but semantically identical).
Two details worth calling out, both consistent with the first wave:
The
findProjectRootwalk specifically looks for a monorepo root (package.jsonwithworkspaces, oryarn.lock/pnpm-workspace.yaml). The beacon wants to know it landed in a real corporate repo, not a throwaway directory.The 3-second
sleepcarries the same intent the original payloads spelled out in Russian: "обходит sandbox." It's there to outlast single-shot install sandboxes that don't wait around.
The DEP_CONFUSION_* environment handoff is the same scheme from wave one: stage 1 is a thin, disposable loader, and the operator can swap stage 2 server-side without ever re-publishing a package.
Target identification
The scope names are the targeting. Dependency confusion only fires if the scope is one the victim already pulls privately, so the squatted names are the victim list:
@emcd-vue/*: Vue front-end packages for EMCD, the crypto-mining-pool and fintech platform. Sampled scopes:auth,loans,b2b-pay-form.@ccrm/*-api-axios: a CRM/API client surface (customer,contact,analytics,products,recommendation,file-storage,user-storage,client-voice,external-integrations). Owning organisation not yet publicly identified.
This is the same victimology as wave one (banking, payments, and now crypto-fintech) and it lines up with the Russian-nexus targeting we documented previously (@bcs → BCS Bank, @cloudplatform-single-spa, @car-loans). The operator is working through a list of private fintech scopes one organization at a time.
The package metadata carries a consistent deception pattern across both scopes: platform@ccrm.io and platform@emcd-vue.io as maintainer emails, git+https://github.ccrm.io/platform/... and git+https://github.emcd-vue.io/... as repository URLs, both simulating internal GitHub Enterprise hosts rather than github.com. This is the same spoofing technique documented in the May campaign. One meaningful difference: the @yandex.ru maintainer aliases present in several May wave packages do not appear here. Whether that reflects a different operator working from the same tooling, or the same operator cleaning up attribution artifacts, the infrastructure and payload are consistent with the campaign we reported on May 31.
Indicators of Compromise
Network
Indicator | Type | Stage |
|---|---|---|
| C2 domain | 0/1 |
| Stage-2 retrieval | 1 |
| Exfil sink ( | 2 |
| Stage-0/1 host (per wave-one report) | 0/1 |
Host artifacts
Indicator | Type |
|---|---|
| Run-once state dir |
| Dropped stage-2 |
Strings
Indicator | Type |
|---|---|
| C2 auth header |
| C2 user-agent |
| Env-handoff markers / kill switch |
| Decoy metadata lures |
Packages (12): SHA-256 of the tarball (abbreviated; full hashes in appendix)
Package | Version | SHA-256 |
|---|---|---|
| 5.0.1 |
|
| 5.0.1 |
|
| 5.0.1 |
|
| 5.0.1 |
|
| 5.0.1 |
|
| 5.0.1 |
|
| 5.0.1 |
|
| 5.0.1 |
|
| 5.0.1 |
|
| 6.4.9 |
|
| 5.7.4 |
|
| 7.1.8 |
|
(Full hashes in the appendix / 00-inventory.md.)
MITRE ATT&CK
Tactic | Technique |
|---|---|
Initial Access | T1195.001: Supply Chain Compromise: Compromise Software Dependencies and Development Tools |
Execution | T1059.007: JavaScript; T1072: Software Deployment Tools (npm lifecycle) |
Defense Evasion | T1027: Obfuscated Files or Information; T1497.003: Time-Based Sandbox Evasion |
Discovery | T1083: File and Directory Discovery (monorepo root walk) |
Command and Control | T1105: Ingress Tool Transfer; T1071.001: Web Protocols |
Response
Block
oob[.]moika[.]techat DNS/egress. Hunt forUser-Agent: ccrm-telemetry/1.0, theX-Secretvalue,~/.cache/._ccrm_init/, and<tmpdir>/._ccrm_init.js.Audit installs of any
@ccrm/*or@emcd-vue/*; check lockfiles and~/.npm/_logsfor these versions. Treat any host that installed one as compromised pending stage-2 review.Pin scope→registry in
.npmrc(@ccrm:registry=…,@emcd-vue:registry=…) so private scopes can never resolve to the public registry, the single most effective control against dependency confusion.CCRM_NO_TELEMETRY=1neutralizes stage 1, but the packages must still be removed.
Related: Inside the moika.tech Dependency Confusion Campaign · Redhat NPMJS packages hit in latest Shai-Hulud wave · The Complete TeamPCP Campaign

Real World Attacks

Redhat NPMJS packages hit in latest Shai -Hulud wave

Valentino Duval
1 Jun 2026
Real World Attacks

Inside the moika.tech Dependency Confusion Campaign

Valentino Duval
31 May 2026
Real World Attacks

Megalodon: Active GitHub Actions Supply Chain Attack Harvesting CI/CD Secrets at Scale

Ossprey Research Team
21 May 2026
