Contagious Interview ends at npm install
How DPRK actors turn LinkedIn job offers into code execution via npm postinstall hooks, what BeaverTail steals, and why developer endpoints stay blind.
DPRK operators are running a recruitment pipeline that ends in code execution. The vector is a LinkedIn message. The payload is a coding assignment. The execution primitive is npm install. Palo Alto Unit 42 tracks the active campaign as Contagious Interview. Google and Mandiant track the older variant as Operation Dream Job. Both sit inside the Lazarus cluster - TA444 and UNC4736, the financially-motivated and intelligence-driven arms of one state program. No CVE. No CVSS vector. No patch boundary. The vulnerable component is the trust a developer extends to an unsolicited recruiter.
That is the part that matters. This is not a software flaw. It is a trust boundary violation executed at human speed and registry scale.
The front end is a constructed identity. The actor stands up a recruiter persona - an aged LinkedIn profile, a plausible company page, sometimes a compromised legitimate account borrowed for its connection graph. T1585.001, establish social media accounts. T1583, acquire infrastructure for the fake employer site. Target selection is deliberate: T1591, reconnaissance against engineers at firms holding crypto, cloud access, or source worth taking. The outreach is tailored - a role, a salary band, a referral that reads as real. By the time a repository link arrives, the candidate has had several normal exchanges. The conversation is the social-engineering payload. The code is just delivery.
The code-execution primitive is mundane. Node package manager lifecycle scripts. A package.json declares preinstall, install, and postinstall hooks, and those hooks run arbitrary shell commands automatically when the package is installed. No prompt. No confirmation. CWE-829 - inclusion of functionality from an untrusted control sphere. The behaviour is by design. The dependency model assumes the developer trusts what they install. The campaign attacks that assumption directly.
The repository looks like a legitimate take-home assessment. A React frontend, a Node backend, a database connector, a README with setup steps. Buried in a transitive dependency or a config file is an obfuscated loader - minified, base64-encoded, or split across string concatenations that survive a casual read. When the candidate runs npm install to set up the project, the first instruction in any onboarding, the postinstall hook fires and pulls the next stage from attacker infrastructure. The developer never sees it execute.
The first stage is BeaverTail. A JavaScript infostealer and loader, cross-platform, with a later macOS build wrapped in the Qt framework to pass as a normal application. BeaverTail enumerates browser profiles. It reads Chromium Login Data, decrypts the Local State master key through DPAPI on Windows, targets crypto-wallet extensions by extension ID - MetaMask among them - and exfiltrates the contents. T1555.003, credentials from web browsers. T1539, steal web session cookie. The session cookies matter more than the passwords. A live cookie replays straight into Okta, Google Workspace, or a cloud console and skips both the password and the MFA prompt that issued it.
BeaverTail then stages the second payload. InvisibleFerret. A Python backdoor. It fingerprints the host, establishes C2, and pulls further modules on demand - a dedicated browser stealer, a keylogger, and frequently a download of AnyDesk configured for unattended access. T1219, remote access software. T1059.006 and T1059.007 - Python and JavaScript as the execution layers. Persistence and hands-on-keyboard control on a developer workstation. That is the foothold.
The workstation is the objective only in the narrow, crypto-theft case. In the broader case it is the entry point. A software engineer holds cloud credentials, source repository tokens, signing material in some roles, and CI/CD secrets cached in environment files and credential helpers on disk. An .npmrc automation token, an AWS key in a dotfile, a kubeconfig - all readable by the same process that just ran the postinstall hook. T1078, valid accounts. Once the host is owned, every system that trusts that engineer’s identity is in scope. The job offer becomes a supply chain compromise - T1195.001, compromise of development tools and dependencies - aimed not at the victim’s product directly but at the human who ships it.
The second-order move closes the loop. If the compromised engineer holds commit rights to a production repository or publish access to a package registry, the actor inherits both. A poisoned commit or a malicious version published under a trusted maintainer’s identity propagates to every downstream consumer of that package. One social-engineered candidate becomes a distribution channel into the employer’s entire install base. That is the mechanism behind the maintainer-account takeovers that have repeatedly moved malware through the public npm registry.
This is documented, not theoretical. Operation Dream Job, disclosed by ClearSky in 2020 and tracked by Google TAG, used fake recruiter personas on LinkedIn against defence and aerospace staff, moved the conversation to WhatsApp or email, and delivered weaponised documents. Contagious Interview, named by Unit 42 in late 2023, shifted the lure to developers and the payload to npm. Hundreds of malicious packages tied to the same actor have since reached the public registry as typosquats and lookalikes, seeded so the assignment pulls them as ordinary dependencies.
The supply chain endpoint is not hypothetical either. The 3CX compromise in March 2023 - VEILEDSIGNAL, attributed by Mandiant to UNC4736 - began when an employee installed trojanised trading software on a personal device. A DPRK-nexus actor reached one individual, owned the host, and pivoted into a vendor whose softphone ships to hundreds of thousands of organisations. The first known software supply chain attack to lead directly into another. Initial access was a person, not a perimeter.
The pattern is not exclusive to DPRK. Lapsus$ ran the same logic from the other direction - social-engineering help desks and paying insiders, then abusing third-party support access. The Okta exposure in early 2022 traced to a support engineer’s compromised laptop at a subprocessor. Different actor, same structural weakness. The trusted external relationship is the path of least resistance, and it carries no exploit signature.
Telemetry is the uncomfortable part. Initial access generates nothing an EDR will see. The LinkedIn message, the recruiter call, the repository clone - none of it touches a monitored control. The decision to trust is made by a human before any sensor sits in the path. The first observable event is npm install.
After that the signal exists if anyone collects it. Sysmon Event ID 1 shows node.exe or npm spawning a child it has no reason to spawn - python, curl, powershell, a shell one-liner with an encoded argument. Parent-child anomaly. Sysmon Event ID 3 and Event ID 22 show the interpreter opening connections and resolving fresh or low-reputation domains. Sysmon Event ID 11 shows staged payloads written under AppData, Temp, or a hidden project directory. A later AnyDesk install surfaces as a new service and a new binary. EDR classifies the chain as script-interpreter-spawning-network-connection and credential-store-access. A read against the Chromium Login Data SQLite file by a process that is not the browser is high-fidelity. On macOS, security invocation and Keychain access by a Qt-wrapped binary is the equivalent.
The detection gap is structural. Developer endpoints are the worst-instrumented machines in most environments. Engineers run interpreters that spawn children and open sockets all day - that is the work. The malicious npm install hides inside the same behaviour as a thousand legitimate ones. Baseline noise is the cover. The signal is present, and the analyst drowns it. The credential and cookie theft completes in seconds, well inside dwell time, often before the second-stage C2 registers anywhere.
There is no patch. There is no affected version range. The exposure is the workflow - unsolicited contact, an attractive role, a repository the candidate is asked to run on a machine that also holds production credentials. Mixing recruitment-sourced code and privileged access on one host is the enabling condition. Project setup run inside a disposable VM or container, with no credentials present and egress filtered, removes the primitive. The npm install flag that disables lifecycle scripts removes it at the package layer. Neither requires a new product.
The detection content is concrete and already buildable: interpreter processes spawned by package managers, non-browser reads of browser credential stores, first-seen outbound connections from node and python on developer endpoints, and unattended remote-access tooling appearing on an engineering workstation. What it requires is telemetry collected from the endpoints most often left out.
For anyone who already ran the assignment, this is an incident, not a curiosity. Cached cloud tokens, browser sessions, and signing material on that host are presumed compromised. The correct response is escalation to the security team, credential and session rotation from a clean device, and preservation of the host for analysis. Australian operators carrying privileged access into critical infrastructure inherit obligations under the SOCI Act and the Privacy Act the moment that access is exposed - the reporting clock starts at discovery, not at confirmation.
The job offer was the payload. The candidate ran it. That is why it works.
Keep Reading
supply-chain-securityThe integration is the attack surface
Pentagon raised Israeli collection risk to top tier. The technical exposure is supply chain privilege inherited from vendor software, not espionage.
grapheneosSpanish police flagged GrapheneOS as suspicion
Authorities treating GrapheneOS as a targeting signal inverts threat intel logic and exposes the wrong population to scrutiny. The mechanism breakdown.
aws-govcloudCISA contractor leaked GovCloud keys to GitHub
Technical analysis of a CISA contractor's leaked AWS GovCloud admin keys on GitHub - blast radius, IAM persistence paths, CloudTrail detections, supply-chain tail.
Stay in the loop
New writing delivered when it's ready. No schedule, no spam.