Malicious npm and PyPI Packages Impersonate Aerodrome Finance and Ethereum Vault Connector to Steal Developer Credentials
8 npm and PyPI packages impersonate Aerodrome Finance and Euler's Ethereum Vault Connector, then steal .npmrc and SSH keys via webhook.site.

- Eight packages across npm (6) and PyPI (2) namesquat real, established DeFi protocols: Aerodrome Finance (the principal DEX on Base, capturing over 60% of the network's DEX volume), Euler Finance's Ethereum Vault Connector, Camelot AMM v2, and a generic 'boring-vault' name. All were published at version 1.0.0 with an identical install-time credential harvester.
- Every package shares the exact same C2 endpoint: webhook.site/326b0891-2093-4800-a4c1-686ce3e07b09, plus TCP callbacks to 178.63.67.106:443 and 178.63.67.153:443. An identical C2 across eight unrelated-sounding package names is strong evidence of a single actor running one campaign, not eight coincidences.
- The payload doesn't stop at .npmrc. It reads .npmrc, .gitconfig, environment variables, and enumerates SSH, Foundry, Hardhat, and gcloud directories, a target list built specifically for Web3 developers, not generic credential theft.
- A separate, unrelated package, @telekom-ods/react-ui-kit 2.6.9, namesquats Deutsche Telekom's real @telekom npm scope and reads /etc/passwd and /etc/shadow, exfiltrating via an out-of-band application security testing (OAST) callback instead of webhook.site. Different C2, different payload, different cluster.
- O3 Security filed both clusters to the OSSF malicious-packages database on August 11, 2026 (github.com/ossf/malicious-packages/pull/1437). No other vendor report on these exact package names was found as of publication.
Say you're building a lending app on Base and you need a vault primitive. You search npm for 'ethereum vault connector,' the exact name of a real, audited piece of DeFi infrastructure from Euler Finance. A package called ethereum-vault-connector shows up. It's MIT licensed. Its description reads like real docs. The name is exactly what you typed. You install it. In the background, before your code ever runs, it reads your .npmrc, your .gitconfig, your SSH keys, and your Foundry and Hardhat config folders. Then it sends all of it to a webhook.site URL.
That's the attack ChainRadar caught on August 11, 2026. Eight packages across npm and PyPI, each named after a real DeFi protocol or a plausible-sounding crypto infra term, all running an identical credential-stealing install hook. This isn't spray-and-pray malware naming. It's targeted brand impersonation, aimed at developers who are already integrating with the protocols being spoofed. That's exactly the audience least likely to question the package name.
This report covers two separate, unrelated clusters. Cluster 1 (8 packages, npm + PyPI) namesquats DeFi protocols and steals developer credentials via a shared webhook.site endpoint. Cluster 2 (1 npm package, @telekom-ods/react-ui-kit) reads /etc/shadow and exfiltrates via a different mechanism entirely. We are not claiming they're the same actor. Treat them as two incidents.
Why these specific names were chosen
Aerodrome Finance is not obscure. It's the top DEX on Base, built by the Velodrome team. It handles over 60% of all DEX trading volume on that network. It's also a proven attack target already. In November 2025, attackers hijacked Aerodrome and Velodrome's DNS. An insider at their domain registrar helped them do it. Users got redirected to a fake copy of the real site. Aerodrome and Velodrome's own report puts the damage at about $700,000, the amount users signed away on the phishing pages before the attack was stopped. That incident had nothing to do with npm. But it shows attackers already see Aerodrome as worth faking. Developers who build on it are a known, valuable target.
Ethereum Vault Connector (EVC) is the other anchor name. It's a real, open-source tool built by Euler Finance. It lets ERC-4626 and other vaults on Ethereum use each other as collateral. Lending protocols, stablecoins, and margin trading apps are all built on top of it. Its own site says it has been through two security reviews, four audits, and formal verification, with named partners including yAudit, Certora, and Trail of Bits. A developer building vault infrastructure who searches 'ethereum vault connector' would expect to find the real thing. They'd find the malicious package instead.
| Malicious package | What it impersonates | Why the name is credible |
|---|---|---|
| ethereum-vault-connector | Euler Finance's Ethereum Vault Connector (evc.wtf) | Exact name match for an audited, widely-referenced DeFi primitive |
| @aerodrome-finance/contracts | Aerodrome Finance, the principal DEX on Base | Scoped exactly like a real protocol would publish its own contracts package |
| @aerodrome-finance/slipstream | Aerodrome's Slipstream concentrated-liquidity AMM | Matches Aerodrome's actual product naming |
| camelot-ammv2-core | Camelot, an established Arbitrum AMM | Generic-sounding core/periphery split matches real AMM package conventions |
| camelot-ammv2-periphery | Camelot AMM v2 periphery (router/library) | Same pattern as above |
| boring-vault | Generic vault-primitive naming used across multiple real DeFi projects | Plausible enough to pass a casual name check |
| dlmm (PyPI) | Dynamic liquidity market maker tooling, a real DeFi mechanism | Common shorthand developers search for directly |
| dlmm-sdk (PyPI) | SDK naming convention matching real DLMM tooling packages | Looks like an official SDK counterpart to the above |
“Static SCA sees a freshly published package whose name matches a protocol the developer is already integrating with. Name-based reputation heuristics have nothing to flag: the name isn't a typo, it's a direct match to something real.”
One template, eight packages, one C2
All six npm packages were published at version 1.0.0. All are MIT licensed. Each has a description written to sound like real docs, things like 'Aerodrome Slipstream AMM contracts and ABIs' or 'Boring Vault contracts.' Every one carries the same preinstall and postinstall script: node index.js || true. That isn't six independent authors landing on the same idea. That's one build template, stamped onto eight package.json files, published in a single burst.
"scripts": {
"preinstall": "node index.js || true",
"postinstall": "node index.js || true"
}The strongest clue isn't the naming pattern. It's the command-and-control endpoint. O3 Security's disclosure to the OSSF malicious-packages database confirms all eight packages send stolen data to the exact same webhook.site URL, plus the same pair of callback IPs. Identical infrastructure across eight unrelated-sounding names, on two different package registries, doesn't happen by accident.
| Type | Indicator | Notes |
|---|---|---|
| C2 (HTTPS) | webhook.site/326b0891-2093-4800-a4c1-686ce3e07b09 | Identical across all 8 packages; webhook.site is a legitimate service, so this domain is allowlisted almost everywhere |
| TCP callback | 178.63.67.106:443 | Shared across the cluster |
| TCP callback | 178.63.67.153:443 | Shared across the cluster |
| File read | ~/.npmrc | Can contain registry auth tokens for private/scoped packages |
| File read | ~/.gitconfig | Can expose linked credential helpers and identity data |
| Directory enumeration | ~/.ssh, Foundry config, Hardhat config, gcloud config | A target list built specifically for blockchain and cloud-infra developers |
| Env access | Full process environment | Standard first step for harvesting API keys and tokens left in shell env |
.npmrc can hold registry auth tokens with publish rights to your org's private packages. If a token like that leaves your machine, the blast radius isn't just this one project, it's every package that token can push to.
| Package | Ecosystem | Malicious version | Exfil target | C2 |
|---|---|---|---|---|
| ethereum-vault-connector | npm | 1.0.0 | .npmrc, .gitconfig, env, SSH/Foundry/Hardhat/gcloud dirs | webhook.site/326b0891-...e07b09 |
| @aerodrome-finance/contracts | npm | 1.0.0 | Same as above | Same C2 |
| @aerodrome-finance/slipstream | npm | 1.0.0 | Same as above | Same C2 |
| boring-vault | npm | 1.0.0 | Same as above | Same C2 |
| camelot-ammv2-core | npm | 1.0.0 | Same as above | Same C2 |
| camelot-ammv2-periphery | npm | 1.0.0 | Same as above | Same C2 |
| dlmm | PyPI | 1.0.0 | Same pattern, same C2 | Same C2 |
| dlmm-sdk | PyPI | 1.0.0 | Same pattern, same C2 | Same C2 |
Why webhook.site as C2 is the smart part
webhook.site is a real service. Developers use it every day to inspect HTTP requests while debugging. That's exactly why it works as C2. A domain-reputation or allowlist tool has no reason to block it. It isn't a bulletproof host or a fresh lookalike domain. It's a well-known SaaS tool with a long, clean history. The malicious traffic doesn't look like malware traffic. It looks like a developer testing a webhook.
- Domain-reputation filters see a trusted, long-established domain and let the request through.
- SIEM rules that allowlist common developer SaaS tools (webhook testers, logging endpoints, CI callback URLs) miss it by design.
- The unique path (the UUID after webhook.site/) is what actually routes stolen data to the attacker, and that part is invisible to anything that only inspects the domain.
A separate cluster: @telekom-ods/react-ui-kit
The same sweep also caught @telekom-ods/react-ui-kit at version 2.6.9. The name is a near-match for Deutsche Telekom's real npm scope, @telekom, home of the company's Scale design system. But the behavior is different in every way that matters. This package doesn't read .npmrc or post to webhook.site. It reads /etc/passwd and /etc/shadow instead: the local user list and, on a misconfigured or root-running system, the hashed password file. It then sends the results out through an OAST (out-of-band application security testing) callback domain.
| Package | Ecosystem | Malicious version | Files read | C2 |
|---|---|---|---|---|
| @telekom-ods/react-ui-kit | npm | 2.6.9 | /etc/passwd, /etc/hosts, /etc/shadow | d9t83osijf9n1gb62e4gxfioysijywqww.oast.me |
We are treating this as a distinct incident, not a third data point for the DeFi cluster's narrative. Different C2 infrastructure, different exfil mechanism (OAST callback vs. direct webhook POST), different target files, and no naming overlap with the DeFi packages. The only thing the two clusters share is being caught the same day.
Here's how an OAST domain works: it encodes a unique subdomain per victim. Any DNS lookup or HTTP hit against that subdomain confirms the code ran, even with no direct network access allowed. DNS resolution alone can leak the confirmation. Reading /etc/shadow needs elevated privileges to actually pull hashes on a properly locked-down system. That suggests one of two things. Either this payload is opportunistic, aimed at misconfigured CI runners and containers that run as root, or it just tries the read regardless, to see what comes back.
Attribution: unattributed
We checked this against known campaign families: Shai-Hulud, Miasma, TeamPCP, and others. No match. The install-hook mechanism here is a plain preinstall/postinstall npm script, not a .pth injection or a worm-style spreading step. The shared webhook.site C2 and the DeFi-brand namesquat pattern don't line up with any campaign we could verify against a primary source. So we're not naming this cluster. If you've seen IOC or infrastructure overlap with a tracked campaign, we'd want to know.
Detection and response
If any of the listed packages appear in a lockfile, package.json, or requirements.txt, treat the machine as compromised. The preinstall/postinstall hook runs automatically on npm install, before you'd ever import or run the package's code.
# npm projects: search lockfiles and node_modules for the malicious names
grep -RE '"(ethereum-vault-connector|@aerodrome-finance/contracts|@aerodrome-finance/slipstream|boring-vault|camelot-ammv2-core|camelot-ammv2-periphery|@telekom-ods/react-ui-kit)"' package.json package-lock.json yarn.lock pnpm-lock.yaml 2>/dev/null
# PyPI projects: check installed packages and requirements files
pip freeze | grep -E '^(dlmm|dlmm-sdk)=='
grep -E '^(dlmm|dlmm-sdk)' requirements*.txt 2>/dev/null
# Confirm exact malicious version if a match is found
npm ls ethereum-vault-connector boring-vault camelot-ammv2-core camelot-ammv2-periphery 2>/dev/null
npm ls @aerodrome-finance/contracts @aerodrome-finance/slipstream @telekom-ods/react-ui-kit 2>/dev/null- Run the grep/pip commands above across every repo and CI cache on machines used for DeFi/Web3 or Telekom-adjacent frontend development.
- If a match is found, rotate everything readable from .npmrc: npm/registry auth tokens, and any org-scoped publish tokens tied to that machine's identity.
- Rotate git-linked credentials referenced in .gitconfig, including any stored credential helper tokens.
- Rotate SSH keys that were present in ~/.ssh at the time of install, and revoke the corresponding public keys from GitHub, GitLab, and any servers that trusted them.
- Rotate Foundry, Hardhat, and gcloud credentials/config if those directories exist on the affected machine, since the payload specifically enumerates them.
- For @telekom-ods/react-ui-kit, audit whether the process had root or elevated privileges (CI runner, container running as root) and, if so, treat any credentials or hashes in /etc/shadow as potentially exposed and rotate local account passwords.
- Remove the malicious package version, pin dependencies going forward, and add the package names above to an internal denylist or private registry block.
- Add an egress monitoring rule for outbound traffic to webhook.site immediately following an npm/pip install step in CI, since legitimate build steps rarely need it.
Why this evades most scanning stacks
None of the individual techniques here are exotic. What makes this cluster effective is that each layer of a typical AppSec stack has a specific, predictable reason to let it through.
| Layer | What it checks | Why this attack passes |
|---|---|---|
| Typosquat / name-similarity detection | Edit-distance or fuzzy match against popular package names | These aren't typos of existing packages, they're exact-match impersonations of protocol names that have no prior npm package to squat against |
| Static SCA / dependency scanning | Known-vulnerability and known-malware databases | Freshly published packages with no CVE and no prior malware history; the payload is a plain, undisguised preinstall script, not an obfuscated binary, so there's nothing novel for a signature to catch, only unfamiliarity |
| Network allowlisting / domain reputation | Blocklists of known-bad or newly registered domains | webhook.site is a legitimate, long-standing developer tool. It has no reason to be on a blocklist |
| Developer sniff-test | Does the package name and description look legitimate? | The names match real, audited DeFi infrastructure the developer is actually trying to integrate with. This is the layer the attacker specifically engineered around |
The one control this attack has no answer for is runtime behavioral analysis: a sandbox that actually installs the package and watches what the preinstall/postinstall hook does. Every layer above it can be satisfied by a plausible name and a clean-looking manifest. None of them execute the code.
This maps to MITRE ATT&CK T1195.002 (Compromise Software Supply Chain) for the distribution vector and T1552.001 (Unsecured Credentials: Credentials In Files) for the .npmrc/.gitconfig theft. If you're building detection rules off this report, alert on preinstall/postinstall scripts making outbound HTTP requests during CI dependency installs, not just on known-bad package names, since name-based rules will always trail the next namesquat by however long it takes someone to notice.