Skip to main content

Nov 12, 2026

PolinRider: How Malicious Coding Assignments Steal Developer Secrets and Backdoor Their Tools

See how PolinRider uses fake coding assignments, Ethereum-based C2, and tampered developer tools to establish persistent access.

Ryan Devendorf

On October 29, 2026, attackers exploited access to the internal wallet-signing service of global cryptocurrency exchange Binance in an incident affecting approximately $6.34 billion in digital assets. The theft followed a months-long campaign that included a malicious coding assignment delivered to a software engineer through a fraudulent recruitment process.

According to Binance’s November 3 incident report, the assignment compromised the engineer's workstation, giving attackers access to the developer environment. They subsequently used an internal AI tool to compromise two additional engineers' machines, discovered a container deployment permission token, and later used stolen credentials to deploy a container and trigger a malicious script that launched the wallet attack. Binance reported that its endpoint protection failed to detect the malware involved in the September compromise.

In an independent investigation, Abnormal analyzed a live variant of PolinRider, malware whose tradecraft is consistent with DPRK-linked Contagious Interview activity. Our samples represent a cross-platform variant that targets AI coding tools and other development software. 

Both investigations describe the same broader playbook: targeting developers through fraudulent recruitment and malicious coding assignments to establish a foothold. The FBI attributes the Binance theft to DPRK's TraderTraitor activity, while Abnormal assesses that its PolinRider samples are associated with DPRK-linked Contagious Interview activity. We did not establish that our specific repositories were used against Binance, but we assess a DPRK/Contagious Interview nexus with moderate confidence.

Our analysis revealed how a concealed loader retrieves command-and-control (C2) server addresses from Ethereum transactions and downloads an encrypted second-stage payload. That payload is designed to modify commonly used development tools to establish persistent access. These techniques allow the malware to extend its presence beyond the initial coding assignment by embedding itself in applications developers routinely use.

Abnormal's investigation offers a detailed look at a malware variant associated with the same broader fake interview attack methodology.

How a Coding Assignment Becomes an Initial Access Vector

The PolinRider campaign uses a familiar recruitment scenario: a purported recruiter contacts a developer and shares a GitHub repository containing a take-home coding assignment. Completing the exercise involves downloading and executing code from an unfamiliar source.

In the two trojanized repositories Abnormal analyzed, malicious code was concealed in files that could easily escape notice during a routine project review. One version used an extensionless file named `init`, while another embedded obfuscated JavaScript in files presented as fonts, including `fa-solid-400.woff2` and `.orc` files. The retained init file is 32,822 bytes, with a benign-looking initialization stub followed by 776 spaces and a 31,302-character obfuscated suffix.

The repositories also incorporated execution mechanisms into standard development workflows. Running `npm run dev` could trigger the loader through the project's scripts, while a VS Code task configuration could initiate execution when the developer opened the project folder—provided the workspace was trusted and automatic tasks were permitted.

Binance's incident report describes a similar recruitment process: a purported recruiter arranged interviews with a software engineer during which he was directed to download a malicious coding assignment. Binance reported that the malware replaced a legitimate `pyenv` component, while Abnormal's investigation identified execution mechanisms involving project startup scripts and VS Code tasks.

A Concealed Loader Delivers the Second-Stage Payload

Once executed, the PolinRider loader retrieves an encrypted second-stage Node.js payload. Abnormal’s analysis identified XOR-encrypted code executed through `eval` and a detached process. Obfuscation concealed the logic responsible for retrieving and launching the additional malware.

The second stage examines the development environment to identify installed developer applications and locate components it can modify to establish persistence. It searches for Cursor, VS Code, and Antigravity, inspecting editor startup modules and stored device identifiers. It also checks for GitHub Desktop and uses `npm root -g` to locate the global npm installation.

These checks tell the malware which development tools are available and which files it can modify to establish recurring execution. The backdoor subsequently reports which tools were modified to the operator through a `/verify-human` endpoint.

By targeting applications developers routinely launch, the malware creates opportunities to execute attacker-controlled code long after the original coding assignment has been opened.

Ethereum Transactions Allow the Malware to Locate Changing C2 Servers

One of the more distinctive capabilities observed in the PolinRider campaign is its use of Ethereum transactions to locate C2 infrastructure.

Rather than relying exclusively on a hardcoded server address, the loader contains an Ethereum address controlled by the operator. It searches Ethereum transactions through public RPC endpoints, using the Blockscout indexer as a fallback. The malware then extracts information encoded in the transaction’s recipient field and decodes it to recover its C2 server's IP address.

This technique, known as EtherHiding, allows the operator to update the malware’s C2 destination by publishing another Ethereum transaction. The loader continues referencing the same on-chain address, even as the infrastructure it contacts changes.

The recovered loaders resolved backend addresses including `95[.]135[.]181[.]151` and `103[.]179[.]142[.]155`; the latter was unavailable during downstream analysis. Further infrastructure analysis identified a Windows VPS accessed directly through its IP address, with RDP exposed and no associated domain identified for that server.

This architecture complicates infrastructure-based blocking. Although defenders can block a known malicious IP address, the malware can retrieve an updated destination from publicly accessible blockchain data without requiring changes to the loader itself.

The use of Ethereum in this campaign serves a different purpose than the EIP-7702 authorizations described in Binance’s incident report. In PolinRider, Ethereum provides a mechanism for C2 discovery. Binance reported that attackers abused EIP-7702 authorizations during the subsequent movement of wallet assets. The available evidence does not establish a connection between these mechanisms.

Malware Modifies Developer Tools to Establish Persistent Access

After identifying the development environment, the second-stage payload attempts to modify components of applications the developer is likely to use regularly. Abnormal researchers observed code designed to tamper with editor startup components, including the `@vscode/deviceid` module and npm’s `lib/cli.js` file. The injected material contained the marker `/*M260630A*/` and references to companion `.inz.cjs` files. Once these modifications are applied, launching a compromised editor or invoking npm can execute attacker-controlled code again.

The malicious repository provides the initial opportunity for execution, while modifications to established development tools allow the malware to run again during subsequent workflows. Researchers also identified watchdog-related artifacts under `~/.node_modules/.npm-ws*`, providing further evidence of the malware's persistence mechanisms.

The captured watcher retrieves the orchestrator at startup. Its empty 60-second interval keeps the process alive; it does not repeat the fetch. Operator tasking arrives separately through `Socket[.]IO`, while `/verify-human/<version>` reports host and injection status.

Binance's incident report illustrates how a compromised developer workstation contributed to an intrusion that ultimately reached the exchange's wallet-signing infrastructure. On October 20, attackers used Engineer B's compromised computer and an internal AI tool to gain control of two other engineers' machines. On Engineer A's computer, they discovered a container deployment permission token. Nine days later, on October 29, the attackers accessed Engineer C's computer, used credentials stolen from Engineer A, deployed a container, and triggered a malicious script to launch the wallet attack.

That sequence comes from Binance's reporting, not Abnormal's malware analysis. It demonstrates the potential consequences of developer workstation compromise when attackers can use that access to interact with internal tools, obtain credentials, and move toward sensitive systems.

An Additional Python Stage Collects Developer Secrets Automatically

Further analysis recovered a boot stage and a dedicated Python information stealer, expanding the chain beyond persistent remote access. The boot code can export process environment variables to `/snv`, start developer-tool injection in parallel, and retrieve a Python payload from `/$/1`. Its default mode starts collection automatically, without waiting for an operator command.

The Python stage targets browser data, cryptocurrency wallets, password manager files, and developer secrets. Its Chromium routines implement password, cookie, and payment card export. Firefox collection includes credential databases, cookies, and extension files; copying those files does not establish that every stored secret was decrypted. Other routines enumerate Windows credentials, access Linux secret stores, and copy the macOS login keychain database. Developer-focused targets include environment files, `.git-credentials`, and selected VS Code and GitHub Desktop artifacts.

Collected data can be packaged into password-protected archives and uploaded through `/u/f`, with host and collection information reported through `/u/e`. Cleanup can remove staging directories after packaging, before upload is attempted, and remove archives according to local upload flags. Deleted files therefore do not prove that the data reached the operator. The boot and Python responses were captured on November 5, 2026, and deobfuscated without executing either payload. These establish the capabilities of the captured responses, not successful theft from a victim.

The Node backdoor provides a separate interactive channel through `Socket[.]IO`. Recovered handlers accept command events and can read the clipboard, upload selected files or directories, evaluate supplied JavaScript, and execute system commands. The `/verify-human/<version>` HTTP request reports host and injection status; its response is discarded. Automatic Python collection and interactive Node tasking give the operator complementary ways to obtain data.

The Telegram Fallback Reuses Previously Reported Infrastructure

The recovered upload configuration also identifies a Telegram fallback: File Bot, `@file_1018_bot`, with numeric bot ID `7870147428`. The configured destination is recipient ID `7699029999`, which Telegram metadata resolves to a private account named Magic Meta, `@magicmeta`. These results identify the bot and configured recipient for the captured configuration. 

JFrog’s June 2026 research reports the same bot ID and exact recipient ID in a chain involving hijacked npm packages, concealed font files, VS Code tasks, a `Socket[.]IO` backdoor, and a Python stealer. OpenSourceMalware separately reports the same bot identity in older PolinRider-related packages, but a different destination chat. This overlap supports reuse of exfiltration infrastructure. The recipient’s public profile uses a cityscape avatar. Reverse-image research did not establish its location, and the image supplies no reliable geographic or actor-attribution evidence.

For defenders, confirmed execution should trigger investigation of credential exposure as well as persistence. Review Node-to-Python process chains containing `urllib.request` and `exec`, correlate stage requests such as `/$/boot` and `/$/1` with uploads to `/snv`, `/u/e`, and `/u/f`, and restore modified developer tools from trusted sources. A process match or upload request is an investigative lead, not proof of completed collection. Keep unfamiliar repositories isolated from developer credentials, and require workspace trust and automatic-task review before running folder-open tasks.

Detection Opportunities for Security Teams

Abnormal’s analysis identified several artifacts and behaviors that can help security teams investigate potential PolinRider infections. At the repository level, suspicious indicators include extensionless `init` files referenced by npm scripts, JavaScript embedded in files presented as fonts, and `.vscode/tasks.json` configurations capable of triggering execution when a trusted project folder opens and automatic tasks are permitted. These artifacts warrant closer scrutiny when found in repositories provided by unfamiliar external contacts, including individuals claiming to represent prospective employers.

On developer workstations, security teams can look for unauthorized modifications to editor and npm components, along with associated artifacts and network activity. Relevant indicators include:

  • The `/*M260630A*/` and `/*RS260605*/` markers.

  • Unexpected references to `inz.cjs` files within editor or npm modules.

  • Files matching the `~/.node_modules/.npm-ws*` pattern.

  • Network activity involving the observed `/verify-human` reporting path.

  • Connections to C2 infrastructure identified in the campaign, including addresses recovered through its Ethereum-based discovery mechanism.

These indicators provide investigative leads, but their significance depends on the surrounding activity and system context. Their presence alone does not establish that a workstation has been compromised.

The Binance incident also highlights the importance of looking beyond the initial infection. Monitoring and correlating suspicious activity across developer workstations, internal AI tools, credentials, deployment infrastructure, and sensitive systems could help investigators identify suspicious sequences that individual security controls might not detect in isolation.

Why the Initial Compromise Is Only Part of the Risk

The Binance incident illustrates the broader risks of compromised developer environments. Attackers used access to an engineer's workstation to reach additional machines, use stolen credentials, and ultimately abuse Binance's wallet-signing service.

Abnormal's PolinRider investigation reveals how a malicious coding assignment can establish persistent access to a developer environment. In the samples we analyzed, concealed malware used Ethereum transactions to locate changing C2 servers and contained code designed to modify commonly used development tools to enable recurring execution.

For security teams, these findings underscore the importance of investigating suspicious repository activity, unauthorized modifications to development tools, and subsequent activity involving credentials, internal AI tools, and sensitive infrastructure. The initial execution of a malicious coding assignment may be only one stage of a much larger intrusion, making continued visibility into developer environments and the systems they can access critical to identifying potential compromise.

For additional insight into the attack landscape and analyses of other cyber threats, visit Abnormal Intelligence, our threat intelligence data and research hub.

Protect Against Evolving Email Threats

See how behavioral AI detects attacks that legacy defenses miss.