[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.

Next
Next

[Op Report] PackClient: Hands-on-Keyboard with a new C2 Framework