Article Banner

UNK_DeadDrop: North Korean Phishing Turns VS Code Against Developers

While most phishing campaigns chase office workers, UNK_DeadDrop targets the people who build software. Proofpoint linked this campaign to North Korean operators who pose as recruiters and hiring managers. They lure developers into opening what looks like a normal coding project, then quietly turn the developer's own code editor into an attack tool.

Think of it like a gift box that springs open the moment it is unwrapped. Simply opening the booby-trapped project can run hidden commands without a single click. Because the trap hides inside trusted developer tools, traditional security software often misses it.

The goal is theft. The campaign steals saved passwords, cryptocurrency wallets, and login keys directly from the developer's machine. A single compromised developer can expose company code, cloud accounts, and customer funds. Proofpoint tracked attacks against roughly 100 organizations across finance, technology, education, and cryptocurrency, with the United States as the main target. Recovery forces teams to rotate credentials and move any exposed funds.

Hunting Controls & Observations

UNK_DeadDrop hides inside legitimate developer workflows, so detection depends on watching how trusted tools behave rather than matching known files. Organizations can detect this campaign through multiple telemetry sources:

  • Endpoint Controls: EDR/XDR, Sysmon (Events 1, 3, 11), process creation with parent-process logging, and file monitoring on integrated development environment (IDE) configuration files and browser credential stores
  • Network Controls: Firewall and proxy logs, DNS query logs, and TLS inspection for outbound WebSocket and HTTP sessions to rare external hosts
  • Identity & Access Controls: Operating system credential store and keychain access logs, and privilege elevation events tied to interactive prompts
  • Cloud & SaaS Controls: Source-control (GitHub, GitLab) audit and clone activity, and email gateway logs for recruitment-themed lures with repository links

Behavioral Indicators of Attack

The following behaviors distinguish this campaign from normal development activity:

  • A code editor launching a shell or script interpreter (cmd.exe, wscript.exe, bash) within moments of opening a freshly cloned repository, driven by an auto-run task on folder open
  • The editor process running as a script engine, transforming the IDE into a general-purpose interpreter to execute attacker code
  • Installation of unfamiliar IDE extensions that masquerade as update or support tooling
  • Scripting or editor processes reading saved browser logins and password store files across multiple browser profiles
  • Fake system password prompts appearing shortly after a project is opened, followed by privilege elevation attempts
  • Backup or shadow-copy access used to read locked credential databases when direct file reads fail
  • Outbound connections from developer machines to an uncommon external address on a high port
  • Rapid self-cleanup that deletes working directories and task files after execution completes

MITRE Enterprise ATT&CK Tactics and Techniques

UNK_DeadDrop spans the kill chain from initial access through exfiltration:

Controls' Observables

Endpoint Controls

Endpoint detection platforms can identify the campaign by correlating IDE behavior with credential access:

  • IDE spawning a command shell after repository open: A code editor parent process launching cmd.exe, wscript.exe, or a Unix shell.
    • Related MITRE Techniques: T1204.002, T1059.004, T1059.005
    • Detection Difficulty: MEDIUM
  • Editor running as a script interpreter: The editor binary executing a JavaScript bootstrap or launching with a Node.js execution flag.
    • Related MITRE Techniques: T1059.007
    • Detection Difficulty: MEDIUM
  • Rogue IDE extension install: A VSIX extension with update or support naming installed outside the marketplace workflow.
    • Related MITRE Techniques: T1176.002
    • Detection Difficulty: MEDIUM
  • Credential store access by developer tooling: Python, Node.js, or editor processes reading browser login databases or shadow copies.
    • Related MITRE Techniques: T1555.003, T1070.004
    • Detection Difficulty: HIGH

Network Controls

Network telemetry exposes the command-and-control channel and delivery:

  • Outbound session to a rare host on a high port: WebSocket or HTTP traffic from a developer endpoint to an uncommon external address.
    • Related MITRE Techniques: T1041
    • Detection Difficulty: MEDIUM
  • Repository clones from newly registered domains: Source-control fetches that precede script execution.
    • Related MITRE Techniques: T1195.002
    • Detection Difficulty: MEDIUM

Identity & Access Controls

Identity telemetry reveals credential capture and elevation:

  • Interactive password prompt followed by elevation: A GUI credential prompt spawned by an editor or script process, then a privilege elevation attempt.
    • Related MITRE Techniques: T1056.002, T1548.002
    • Detection Difficulty: HIGH
  • Keychain or credential-manager access changes: Modification of access controls on the login keychain or credential vault.
    • Related MITRE Techniques: T1555.003
    • Detection Difficulty: MEDIUM

Cloud & SaaS Controls

Email and source-control telemetry catch the lure stage:

  • Recruitment or code-review lures with repository links: Inbound mail referencing job offers or code reviews and linking to unfamiliar code-hosting accounts.
    • Related MITRE Techniques: T1566.002
    • Detection Difficulty: LOW

Insights and Recommendation

Organizations that fall victim to UNK_DeadDrop face theft of developer credentials, cryptocurrency wallet drainage, and access to source code and cloud environments. Because developers commonly hold tokens for repositories, build systems, and production infrastructure, a single compromised workstation can become a pivot into the software supply chain and customer-facing services. Recovery requires credential and token rotation, wallet migration, and review of any code or dependencies the developer touched during the exposure window.

Security teams should treat developer endpoints as high-value assets and tune detections to IDE behavior. Alert when a code editor spawns a shell or script interpreter immediately after a repository is opened, and monitor for editor processes launching as a Node.js interpreter. Inventory and restrict IDE extension installation, and watch for access to browser credential stores or shadow copies by scripting and editor processes. Flag outbound connections from developer subnets to newly observed external hosts and high ports. Finally, instruct developers to treat unsolicited job-offer and code-review repositories as suspicious and to open untrusted projects only in sandboxed or restricted-mode environments.

Source and Credits

This summary is based on Proofpoint's research article "Don't Fear the Repo: UNK_DeadDrop Phishing Campaign Targets Developers to Steal Cryptocurrency" by Saher Naumaan, Carlos Rubio, and the Proofpoint Threat Research Team, published on June 8, 2026.

Threat Hunting IOCs & Queries

The indicators below are a representative subset drawn from the Proofpoint report. Threat actors rotate infrastructure frequently, so prioritize the behavioral queries that follow over static matching.

Known Indicators of Compromise

  • Command-and-Control IP: 23.137.105[.]75 (port 5173, WebSocket/HTTP)
  • Sender IP Addresses: 170.205.29[.]83, 170.205.30[.]227
  • Domains: pulsynk[.]org, trixauvex[.]org, onoplanoai[.]ink, predicttocareer[.]space, empowerpharmacy[.]space, nxlog[.]tech, ondofinance[.]tech, deep-ai-guard[.]store, recruitvex[.]us, nemesis[.]work
  • Malicious Repositories: github[.]com/Pulsynk/pulsynk, github[.]com/Trixauvex-org/trixauvex, gitlab[.]com/pulsynk-org/rekt-db
  • File Hashes (SHA256): c935808147f0236c81483d7bbeda4b9d602f3595d5d4057f8115d39e222d1c4b (tasks.json), 734699773e53d995f20d485eb61261033d9d00b4332b39ca26071bcd60cd352f (run-update.sh), 52886aab179f26421678ff23af1b0fabf0a17ffbb534369cdbbac8008cbed8e7 (google-update-support.vsix), a2b9a769df84d9d3a4694bb0252a2c6a5e5f5d1a85a04565362737092bbb3a86 (google-update-support-linux-amd64)
  • Host Artifacts: .vscode/tasks.json with a run-on-folder-open task; vendor/run-update.sh, vendor/run-update.cmd, vendor/run-update-hidden-launch.vbs; Overlord open-source Go command-and-control agent

Code Editor Spawning a Shell or Script Interpreter

Behavior Targeted: Detects a code editor launching a command shell or script interpreter shortly after a repository is opened, the signature of a run-on-folder-open task.
MITRE ATT&CK: T1204.002, T1059.003, T1059.004, T1059.005
Expected Results: Editor processes (Code.exe, Cursor.exe) as the parent of cmd.exe, wscript.exe, powershell.exe, or a Unix shell, often on hosts that recently cloned a new repository.
False Positive Likelihood: MEDIUM. Developers legitimately use integrated terminals and task runners.
Tuning Guidance: Allowlist known build commands (npm, node, tsc) per developer baseline and prioritize executions within minutes of a first-seen repository.

Splunk SPL Query

index=sysmon sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1
    earliest=-30d
    (ParentImage="*\\Code.exe" OR ParentImage="*\\Cursor.exe")
    (Image="*\\cmd.exe" OR Image="*\\wscript.exe" OR Image="*\\cscript.exe"
        OR Image="*\\powershell.exe" OR Image="*\\bash.exe")
| stats count min(_time) AS firstSeen max(_time) AS lastSeen values(CommandLine) AS cmds
    by Computer, User, ParentImage, Image
| sort - lastSeen

// TUNING: Allowlist legitimate build/task commands (npm, node, tsc) per developer baseline
// FALSE POSITIVES: Integrated-terminal use; correlate with newly cloned repositories
// TELEMETRY: Requires Sysmon Event ID 1 (process creation) with parent-process logging

Microsoft KQL Query (Defender/Sentinel)

DeviceProcessEvents
| where Timestamp > ago(30d)
| where InitiatingProcessFileName in~ ("Code.exe","Cursor.exe","code","cursor")
| where FileName in~ ("cmd.exe","wscript.exe","cscript.exe","powershell.exe","pwsh.exe","bash","sh","zsh")
| summarize Count=count(), FirstSeen=min(Timestamp), LastSeen=max(Timestamp),
    Commands=make_set(ProcessCommandLine, 10)
    by DeviceName, AccountName, InitiatingProcessFileName, FileName
| order by LastSeen desc

// TUNING: Allowlist known task-runner commands per developer baseline
// FALSE POSITIVES: Legitimate integrated-terminal usage; weight executions near repo-open events
// TELEMETRY: Microsoft Defender for Endpoint (DeviceProcessEvents)

Note: These queries were generated with AI assistance. Test thoroughly in your environment before production use.

Editor Running as a Node.js Interpreter

Behavior Targeted: Detects the code editor being repurposed as a JavaScript runtime to execute a bootstrap script and decrypt staged payloads.
MITRE ATT&CK: T1059.007, T1140
Expected Results: Editor processes invoked with a JavaScript file argument or a Node.js execution flag, frequently followed by Python or wallet-stealer activity.
False Positive Likelihood: MEDIUM. Some extensions legitimately use the editor's Node runtime.
Tuning Guidance: Baseline normal extension behavior and focus on bootstrap script names and execution from user repository directories.

Splunk SPL Query

index=sysmon sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1
    earliest=-30d
    Image="*\\Code.exe"
    (CommandLine="*ELECTRON_RUN_AS_NODE*" OR CommandLine="*gus-node-bootstrap*"
        OR CommandLine="*.js*")
| stats count min(_time) AS firstSeen max(_time) AS lastSeen values(CommandLine) AS cmds
    by Computer, User, ParentImage
| sort - lastSeen

// TUNING: Baseline legitimate extension-driven Node usage; alert on bootstrap script names
// FALSE POSITIVES: Editor extensions using the embedded Node runtime
// TELEMETRY: Requires Sysmon Event ID 1 with full command-line logging

Microsoft KQL Query (Defender/Sentinel)

DeviceProcessEvents
| where Timestamp > ago(30d)
| where FileName in~ ("Code.exe","Cursor.exe")
| where ProcessCommandLine has_any ("ELECTRON_RUN_AS_NODE","gus-node-bootstrap",".js")
| summarize Count=count(), FirstSeen=min(Timestamp), LastSeen=max(Timestamp)
    by DeviceName, AccountName, ProcessCommandLine, InitiatingProcessFileName
| order by LastSeen desc

// TUNING: Allowlist known extension bootstrap scripts; focus on user repo paths
// FALSE POSITIVES: Legitimate extensions invoking the Node runtime
// TELEMETRY: Microsoft Defender for Endpoint (DeviceProcessEvents)

Note: These queries were generated with AI assistance. Test thoroughly in your environment before production use.

Browser Credential Store Access by Developer Tooling

Behavior Targeted: Detects scripting or editor processes reading saved browser logins and credential databases, including shadow-copy fallbacks for locked files.
MITRE ATT&CK: T1555.003, T1548.002
Expected Results: Python, Node.js, or editor processes accessing Login Data, key4.db, logins.json, or Local State across multiple browser profiles.
False Positive Likelihood: MEDIUM. Password managers and browser sync tools touch these files.
Tuning Guidance: Allowlist sanctioned credential-management software and alert when access originates from developer tooling or recently created processes.

Splunk SPL Query

index=sysmon sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1
    earliest=-30d
    (CommandLine="*Login Data*" OR CommandLine="*key4.db*" OR CommandLine="*logins.json*"
        OR CommandLine="*Local State*")
    (Image="*\\python.exe" OR Image="*\\node.exe" OR Image="*\\Code.exe"
        OR Image="*\\wscript.exe" OR Image="*\\powershell.exe")
| stats count values(CommandLine) AS cmds by Computer, User, Image
| sort - count

// TUNING: Allowlist sanctioned password managers and browser sync utilities
// FALSE POSITIVES: Legitimate credential-management tooling
// TELEMETRY: Requires Sysmon Event ID 1 with command-line logging

Microsoft KQL Query (Defender/Sentinel)

DeviceFileEvents
| where Timestamp > ago(30d)
| where FileName in~ ("Login Data","key4.db","logins.json","Local State","Cookies")
| where InitiatingProcessFileName in~ ("python.exe","node.exe","Code.exe","Cursor.exe",
    "wscript.exe","cscript.exe","powershell.exe","pwsh.exe")
| summarize Count=count(), FirstSeen=min(Timestamp), LastSeen=max(Timestamp),
    Paths=make_set(FolderPath, 10)
    by DeviceName, AccountName, InitiatingProcessFileName
| order by LastSeen desc

// TUNING: Allowlist sanctioned credential-management software
// FALSE POSITIVES: Browser sync and password-manager processes
// TELEMETRY: Microsoft Defender for Endpoint (DeviceFileEvents)

Note: These queries were generated with AI assistance. Test thoroughly in your environment before production use.

Command-and-Control Connection to Known Infrastructure

Behavior Targeted: Detects outbound connections to the campaign's command-and-control server and to high-port WebSocket or HTTP listeners from developer endpoints.
MITRE ATT&CK: T1041
Expected Results: Sessions to 23.137.105.75 or to remote port 5173 originating from developer workstations.
False Positive Likelihood: LOW for the specific IP; MEDIUM for the high port alone.
Tuning Guidance: Treat the IP match as high fidelity. For the port-only logic, allowlist known internal services and focus on developer subnets.

Splunk SPL Query

index=sysmon sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=3
    earliest=-30d
    (DestinationIp="23.137.105.75" OR DestinationPort=5173)
| stats count min(_time) AS firstSeen max(_time) AS lastSeen
    by Computer, User, Image, DestinationIp, DestinationPort
| sort - count

// TUNING: IP match is high fidelity; for port-only logic allowlist internal services
// FALSE POSITIVES: Legitimate apps using port 5173 (dev servers); scope to non-loopback destinations
// TELEMETRY: Requires Sysmon Event ID 3 (network connection); enrich with firewall/proxy logs

Microsoft KQL Query (Defender/Sentinel)

DeviceNetworkEvents
| where Timestamp > ago(30d)
| where RemoteIP == "23.137.105.75" or RemotePort == 5173
| where RemoteIP !startswith "127." and RemoteIP != "::1"
| summarize Count=count(), FirstSeen=min(Timestamp), LastSeen=max(Timestamp),
    Ports=make_set(RemotePort, 10)
    by DeviceName, InitiatingProcessFileName, RemoteIP
| order by LastSeen desc

// TUNING: IP match is high fidelity; port 5173 also used by local dev servers, scope to remote hosts
// FALSE POSITIVES: Internal development servers on the same port
// TELEMETRY: Microsoft Defender for Endpoint (DeviceNetworkEvents)

Note: These queries were generated with AI assistance. Test thoroughly in your environment before production use.

Back to Hunting off the Red