[Op Report] Hands-on-Keyboard Activity from the DPRK "PolinRider" Supply Chain Attack
How a fake luxury travel product manager became a front row seat to a live DPRK supply chain intrusion.
Executive Summary
For one week at the end of August 2026, a Fortune 500 enterprise CTI team stood up a decoy corporate workstation and waited. It took a live threat actor roughly three hours to find it, engage it, and run a full intrusion. What we captured was not a signature match or a vendor rehash. It was an operator typing in real time inside an environment we fully instrumented and controlled.
The activity is consistent with PolinRider, the North Korea linked open source supply chain campaign publicly reported by Socket in mid 2026 and attributed to the Contagious Interview and Famous Chollima cluster, a subset of the DPRK Lazarus group with overlap to APT37. The operator lured our persona into running a trojanized package, stood up a JavaScript command and control implant, staged a Python information stealer and clipboard monitor, and buried three layers of persistence disguised as a Microsoft .NET optimization service.
This post walks through what we saw, from first beacon to data staging, and shares defanged indicators so defenders can hunt for the same tradecraft in their own developer and build environments.
Environment at a Glance
Replica Role: Product Manager
Replica Organization: Global Travel Company
Industry: Travel and Tourism
Topology: Microsoft Active Directory environment with 2,500+ endpoints and 2000+ users.
Replica Location: United States
Observed duration: ~167 hours (Aug 27 through Sept 3, 2026)
Sensor Stack: LimaCharlie EDR, Zeek, Suricata with ETPRO
Infection Vector: Supply Chain Attack
Primary Threat Families: OtterCandy, PolinRider
Note: Replica personas, organizations, and documents are AI-generated and randomized for believability. Any resemblance to real-world entities is purely coincidental.
Figure 1: Additional malicious repositories observed in the PolinRider campaign. Source: socket.dev
Timeline of Operation Activity
Day one: initial access and first stage (27 August)
14:33 A Node.js loader in a malicious pybitjs repo is executed and beacons to the operator C2 at 23.27.13[.]135. Our YARA rules flag it as WinosStager.
14:33 cmd.exe plus curl pulls two payloads from the anonymous file host files.catbox[.]moe and runs them immediately, writing them under TEMP as SvcHostUpdate.py and SvcHostUpdate.js.
14:33 The loader chains through a gitlab[.]com raw README used as a second stage delivery channel.
14:33 The operator issues a reboot (shutdown /r /t 0) to settle persistence and clear state.
15:02 Access to lsass is observed, and a second YARA rule fires for an XFiles and OmniStealer style information stealer.
17:21 A password protected archive, [REDACTED_DIGITS].zip, is staged in the replica’s Downloads folder.
Day four: hands on keyboard as SYSTEM (30 August)
14:05 The operator returns and resumes hands on keyboard activity as SYSTEM, driving non interactive PowerShell.
14:09 PowerShell silently downloads and installs Python 3.14 machine wide.
14:11 SvcHostUpdate.py --deploy runs as SYSTEM. pip installs requests, pyperclip, mss, and Pillow, the toolkit for clipboard theft, screen capture, and HTTP exfiltration.
14:12 Three redundant persistence mechanisms are planted, all masquerading as MicrosoftCLROptimization under the SYSTEM profile.
14:12 The stealer begins POSTing host data to 150.251.113[.]223:8443 using rotating browser user agents.
Total observed duration: ~ 167 hours
Assessment
The tradecraft, tooling, and infrastructure line up cleanly with the PolinRider campaign and the wider Contagious Interview operation. Our read of the engagement:
Attribution. Consistent with a North Korea linked developer targeting operation (Contagious Interview and Famous Chollima, a Lazarus subset, with APT37 overlap). We assess this with moderate confidence based on the lure model, the WinosStager loader, the XFiles and OmniStealer stealer, and the reuse of infrastructure documented for PolinRider.
Initial access by supply chain lure. The persona was steered toward a trojanized package and a fake coding assignment. The malicious PyPI package pybitjs and a temporary codesubmit repository are the delivery artifacts, matching the fake interview and coding test model this actor is known for.
Motivation. Credential and source code theft, developer environment compromise, and cryptocurrency targeting. We captured DNS and TLS to Ethereum RPC endpoints alongside clipboard and wallet theft tooling and lsass access.
Persistence tradecraft. The operator hid in plain sight, naming its scheduled task, Run key, and Startup launcher after a real Microsoft .NET runtime component and planting them under the SYSTEM profile so they survive user logoff. Genuine ngen never lives under the systemprofile CLR optimization path, which makes this a high fidelity hunt target.
Single operator, full kill chain. Fingerprinting the exfil host tied the delivery lure, the tasking desktop, and the collector to a single box, confirming one operator drove the whole intrusion.
Defender Takeaways
If you consume open source at scale, your developer and build environments are the target. Here is where to focus:
Block and hunt the indicators. Ingest the network and host indicators below, with priority on the two C2 addresses and the catbox[.]moe and gitlab raw fetch patterns.
Hunt the persistence masquerade. Any MicrosoftCLROptimization scheduled task, Run key, or Startup VBS running from a systemprofile path is malicious. Legitimate ngen does not live there.
Watch loader behavior. Alert on node.exe or cmd.exe invoking curl to anonymous file hosts, PowerShell silently installing interpreters machine wide, and pip pulling pyperclip or mss on non developer endpoints.
Enforce dependency scanning. Scan npm, PyPI, Packagist, and Go dependencies, and treat any host that installed an affected package as suspect until reviewed from a clean machine.
Harden egress. Flag HTTP to raw public IP addresses on non standard ports such as 8443, and browser user agent rotation coming from a single source.
About Deception Pro
Deception.Pro runs instrumented Active Directory honeynets that lure real threat actors into fully monitored decoy environments and capture their tradecraft end to end: endpoint telemetry, Suricata network detections, full packet capture, and TLS decrypted command and control.
Everything in this post came from an adversary acting live inside one of our decoys, not from a signature feed and not from after the fact guesswork. While the rest of the industry was reading about PolinRider, our sensors were watching the operator type. That is the difference between reading threat intelligence and generating it.
See what your feeds are missing at Deception.Pro.
Indicators of Compromise
Network
Loader C2 (RATatouille / OtterCandy): 23.27.13[.]135
Stealer exfil (port 8443, ClipboardMonitor): 150.251.113[.]223
Payload staging: files.catbox[.]moe (97icr5.py, s5w2f0.js)
Second stage loader: gitlab[.]com/test26330331/test (raw README eval)
Malicious PyPI package: files.pythonhosted[.]org/.../pybitjs-0.1.0-py3-none-any.whl
Ethereum RPC (wallet targeting): 1rpc[.]io, ethereum-rpc.publicnode[.]com, eth.drpc[.]org
Suricata
ETPRO MALWARE Nodster CnC Activity POST
ET MALWARE RATatouille rand-user-agent Supply Chain Compromise CnC Activity (WebSocket)
ET HUNTING Suspicious POST With Reference to WINDOWS Folder Possible Malware Infection
Suspicious TLSv1.2 connection from WinHttpOpen C++ function to FQDN
ET INFO PE EXE or DLL Windows file download over HTTP
Possible Windows Installer / Bitsadmin / Desktopimgdownldr TLSv1.2 connection to FQDN, T1105
ET USER_AGENTS Node XMLHTTP User-Agent
ET INFO Rust HTTP Client User-agent Observed
ETPRO INFO HTTP Request with Lowercase user-agent / host / accept Header Observed
ET INFO Windows PowerShell User-Agent Usage / WindowsPowerShell/5.1
HTTP Connection to Internet from PowerShell, and from macOS and Linux [the rotating exfil user agents]
catbox[.]moe: DNS request, TLS SNI, and download-domain hits
files.pythonhosted[.]org: DNS lookup and TLS SNI
ETPRO HUNTING Request for config.json
HTTP direct request to public IP address
Suspicious HTTP traffic on unusual HTTP port
Observed Smart Chain Domain in TLS SNI / DNS (1rpc[.]io)
Observed Ethereum RPC Endpoint Domain (ethereum-rpc.publicnode[.]com) TLS SNI / DNS
SamrEnumerateDomainsInSamServer, SamrLookupDomainInSamServer, SamrQuerySecurityObject, SamrGetGroupsForUser
SamrLookupNamesInDomain, SamrOpenUser, SamrQueryInformationUser, SamrGetAliasMembership
ET INFO NTLM Session Setup Request/Response (Negotiate, Challenge, Auth)
Host
Downloaded payloads: %TEMP%\SvcHostUpdate.py, %TEMP%\SvcHostUpdate.js
Dropped fake ngen (Python): systemprofile\...\CLR_v4.0\Optimization\ngen.exe
Persistence launchers: ...\Startup\MicrosoftCLROptimization.vbs, clr_init.vbs
Persistence, scheduled task: MicrosoftCLROptimization
Persistence, Run key: MicrosoftCLROptimization
Password protected archive: [REDACTED_DIGITS].zip (Downloads)
File hashes (SHA-256)
97icr5.py: 75ad8365fce771294258a792fcd6b92be499714626aba0960aa1c1746e8672fd
s5w2f0.js: 7c4029b7f1383e25fb1b1ed10292e0bbe024952df2772c1d14f3bfee6ab29984
README.md (gitlab): d4688428d0e99fd4f0320d14fdd6ed46445e775b25779cdea8790e6804426ac6
ngen.exe (dropped): c197268f7e7cf2848b8c1ae59bbd0e0c14defe668a2d365302137ea929b47769
schtasks child (loader): bc866cfcdda37e24dc2634dc282c7a0e6f55209da17a8fa105b07414c0e7c527
Note: hashes for the reconstructed, in memory Node loader payload were not resolvable on disk, so the on disk staging artifacts are listed instead.