Back to Intelligence

WaterPlum DPRK Campaign: 30,000 Devices Infected, $10.7M in Crypto Stolen — Detection and Remediation Guide

SA
Security Arsenal Team
September 20, 2026
10 min read

A joint law enforcement advisory published this month confirms that WaterPlum, a North Korean state-aligned intrusion set, compromised at least 30,000 devices worldwide between December 2025 and July 2026, exfiltrating cryptocurrency assets subsequently laundered through mixers and transferred — more than $10.7 million worth — to wallets controlled by the Democratic People's Republic of Korea.

This is not a smash-and-grab operation. WaterPlum (tracked in parallel with Lazarus-cluster activity and consistent with DPRK revenue-generation operations) is part of Pyongyang's well-documented strategy of funding its weapons programs through financially motivated cyber operations against the crypto sector and retail holders. The 30,000-device figure tells us this was a broad-net, financially oriented campaign — trojanized software, fake recruiter lures, and malicious packages targeting developers and crypto users — not a surgical espionage intrusion. That breadth changes your defensive calculus: any endpoint where an employee holds, trades, or touches cryptocurrency is in scope, and that includes personal-adjacent workstations, developer machines, and finance team endpoints.

If your organization handles crypto treasury, builds Web3 tooling, or employs developers who work on-chain, treat this as an active-threat posture change, not a news item to file away.

Technical Analysis: How WaterPlum Operations Typically Execute

The advisory describes a mass-compromise campaign monetized through cryptocurrency theft. Based on the operational pattern — device infection at scale followed by wallet draining and laundering — the attack chain defenders should expect follows the DPRK playbook refined across 2024–2026 campaigns:

1. Initial access via social engineering and trojanized software. DPRK financial-motivation clusters consistently deliver payloads through fake job-recruiter lures (LinkedIn/Telegram outreach), malicious npm/PyPI packages targeting Web3 developers, and trojanized trading or meeting applications (often delivered as unsigned MSI/DMG installers). The common denominator: a human is socially engineered into executing an installer.

2. Staging and execution. Payloads are typically staged via PowerShell or bash download cradles, frequently abusing cloud-hosted CDNs and paste services for second-stage delivery. Watch for encoded command execution and short-lived staging scripts in %TEMP% or /tmp.

3. Credential and wallet theft. The payload harvests browser credential stores and, critically for this campaign, cryptocurrency wallet artifacts — browser-extension wallets (MetaMask stores data under the browser's Local Extension Settings), desktop wallet files (wallet.dat, Electrum wallets), and keystores. Access to %APPDATA%\Roaming\Ethereum\keystore, %APPDATA%\Bitcoin\wallet.dat, and Chromium Local Extension Settings directories by non-browser processes is a high-fidelity signal.

4. Clipboard hijacking. A low-noise monetization technique seen repeatedly in DPRK-linked stealers: monitoring the clipboard for cryptocurrency address patterns (e.g., ^0x[a-fA-F0-9]{40}$ for Ethereum, ^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$ for Bitcoin) and swapping the victim's destination address with an attacker-controlled one at paste time. MITRE ATT&CK T1115 — Clipboard Data.

5. Persistence and exfiltration. Run-key persistence and scheduled tasks on Windows; launch agents on macOS. Exfiltration of harvested wallet material and credentials over HTTPS to attacker infrastructure, often fronted by compromised WordPress sites or cloud storage abuse.

Exploitation status: This is confirmed, active, in-the-wild exploitation at scale — 30,000+ compromised devices with verified financial loss per the joint advisory. This is not theoretical. No specific CVE is named in the advisory; the intrusion vector is social engineering and trojanized software delivery, which means patching alone will not protect you — behavioral detection and user-awareness controls are the primary mitigations.

Detection & Response

The following detections target the core observable behaviors of this campaign: wallet-artifact access by unusual processes, clipboard hijacking, persistence establishment, and staging behavior. Tune paths and parent processes against your environment's developer tooling (npm, node, python are legitimately noisy on dev workstations).

Sigma Rules

YAML
---
title: Cryptocurrency Wallet File Access by Non-Wallet Process
id: 3b8f2c1a-7e4d-4a9f-b1c3-8d2e6f5a0b19
status: experimental
description: Detects processes outside known wallet/browser binaries accessing cryptocurrency wallet files and browser extension storage, consistent with WaterPlum-style wallet theft (DPRK financially motivated campaigns, MITRE T1555.003/T1552.001).
references:
  - https://www.bleepingcomputer.com/news/security/north-korean-waterplum-hackers-infected-30-000-devices-worldwide/
  - https://attack.mitre.org/techniques/T1555/003/
author: Security Arsenal
date: 2026/07/28
tags:
  - attack.credential_access
  - attack.t1555.003
  - attack.t1552.001
logsource:
  category: file_event
  product: windows
detection:
  selection_paths:
    TargetFilename|contains:
      - '\AppData\Roaming\Bitcoin\wallet.dat'
      - '\AppData\Roaming\Ethereum\keystore\'
      - '\AppData\Roaming\Electrum\wallets\'
      - '\AppData\Roaming\Exodus\'
      - '\Local Extension Settings\nkbihfbeogaeaoehlefnkodbefgpgknn'
  filter_browsers:
    Image|endswith:
      - '\chrome.exe'
      - '\msedge.exe'
      - '\brave.exe'
      - '\firefox.exe'
  condition: selection_paths and not 1 of filter_browsers
falsepositives:
  - Legitimate backup software archiving user profiles
  - EDR/forensic tooling
level: high
---
title: Process Reading Clipboard at High Frequency (Address Swapper Behavior)
id: 91c4e2d7-5f3a-4b8e-a2d6-1c9f7b3e5a84
status: experimental
description: Detects non-system processes making repeated OpenClipboard/GetClipboardData calls, a hallmark of clipboard-hijacking stealers that swap cryptocurrency addresses at paste time (MITRE T1115). Deploy where your telemetry exposes clipboard API usage or via ETW-based sensors.
references:
  - https://www.bleepingcomputer.com/news/security/north-korean-waterplum-hackers-infected-30-000-devices-worldwide/
  - https://attack.mitre.org/techniques/T1115/
author: Security Arsenal
date: 2026/07/28
tags:
  - attack.collection
  - attack.t1115
logsource:
  category: process_creation
  product: windows
detection:
  selection:
    Image|endswith:
      - '\powershell.exe'
      - '\pwsh.exe'
      - '\node.exe'
      - '\python.exe'
      - '\wscript.exe'
      - '\cscript.exe'
    CommandLine|contains:
      - 'OpenClipboard'
      - 'GetClipboardData'
      - 'SetClipboardData'
      - 'System.Windows.Forms.Clipboard'
      - 'Get-Clipboard'
      - 'Set-Clipboard'
falsepositives:
  - Legitimate clipboard-management utilities
  - RMM tooling with clipboard sync features
level: medium
---
title: Persistence via Run Key by Unsigned Process in User Temp Path
id: 5d7a3f1c-2e8b-4c6d-9a1f-4b7e2c8d5a63
status: experimental
description: Detects registry Run-key persistence values pointing to executables in user-writable temp/roaming locations, a common WaterPlum-style stealer persistence pattern (MITRE T1060/T1547.001).
references:
  - https://www.bleepingcomputer.com/news/security/north-korean-waterplum-hackers-infected-30-000-devices-worldwide/
  - https://attack.mitre.org/techniques/T1547/001/
author: Security Arsenal
date: 2026/07/28
tags:
  - attack.persistence
  - attack.t1547.001
logsource:
  category: registry_set
  product: windows
detection:
  selection_key:
    TargetObject|contains:
      - '\CurrentVersion\Run\'
      - '\CurrentVersion\RunOnce\'
  selection_value:
    Details|contains:
      - '\AppData\Local\Temp\'
      - '\AppData\Roaming\'
      - '\Users\Public\'
      - '\ProgramData\Microsoft\'
  condition: selection_key and selection_value
falsepositives:
  - Legitimate user-installed updaters (OneDrive, Slack, Teams) — allowlist known-good values
level: high

KQL — Microsoft Sentinel / Defender Hunt

This query hunts for wallet-file and browser-extension-storage access by non-browser processes, plus clipboard-related script execution, and joins to network egress for correlation. Run it across the full campaign window (December 2025 onward) on your retrospective hunt.

KQL — Microsoft Sentinel / Defender
let Lookback = 90d;
let WalletPaths = dynamic([
  @"\AppData\Roaming\Bitcoin\",
  @"\AppData\Roaming\Ethereum\keystore\",
  @"\AppData\Roaming\Electrum\",
  @"\AppData\Roaming\Exodus\",
  @"Local Extension Settings\nkbihfbeogaeaoehlefnkodbefgpgknn",  // MetaMask
  @"Local Extension Settings\ejbalbakoplchlghecdalmeeeajnimhm"   // MetaMask (Edge ID)
]);
let BrowserProcs = dynamic([@"chrome.exe", @"msedge.exe", @"firefox.exe", @"brave.exe", @"opera.exe"]);
let WalletAccess =
    DeviceFileEvents
    | where TimeGenerated > ago(Lookback)
    | where FolderPath has_any (WalletPaths)
    | where not(FileName has_any (BrowserProcs) or InitiatingProcessFileName has_any (BrowserProcs))
    | project WalletAccessTime=TimeGenerated, DeviceName, DeviceId, AccessingProcess=InitiatingProcessFileName,
              AccessingCmd=InitiatingProcessCommandLine, AccessingPath=InitiatingProcessFolderPath, TargetFile=FolderPath;
let ClipboardOrStaging =
    DeviceProcessEvents
    | where TimeGenerated > ago(Lookback)
    | where ProcessCommandLine has_any ("Get-Clipboard","Set-Clipboard","OpenClipboard","IEX (","Invoke-WebRequest","curl ","wget ")
    | where ProcessCommandLine has_any ("-enc","-e ","FromBase64String","http")
    | project ProcTime=TimeGenerated, DeviceName, DeviceId, ProcName=FileName, ProcCmd=ProcessCommandLine;
WalletAccess
| join kind=leftouter ClipboardOrStaging on DeviceName, $left.WalletAccessTime between ($right.ProcTime .. ($right.ProcTime + 2h))
| extend NetworkEgress = toscalar(
    DeviceNetworkEvents
    | where TimeGenerated > ago(Lookback)
    | where DeviceName == tostring(WalletAccess.DeviceName) and InitiatingProcessFileName == tostring(WalletAccess.AccessingProcess)
    | where TimeGenerated between (WalletAccess.WalletAccessTime .. (WalletAccess.WalletAccessTime + 6h))
    | summarize make_set(RemoteUrl, 25))
| project WalletAccessTime, DeviceName, AccessingProcess, AccessingPath, TargetFile, ProcCmd, NetworkEgress
| order by WalletAccessTime desc

Also run a Syslog/CEF variant for Linux/macOS developer workstations ingested into Sentinel: filter Syslog for sudo, curl, wget to non-corporate domains on hosts where npm/pip telemetry shows recent package installs — DPRK malicious-package delivery frequently lands on *nix dev boxes, not just Windows.

Velociraptor VQL — Endpoint Hunt Artifact

Deploy this as a hunt across your fleet to find wallet artifacts touched by unusual processes and Run-key persistence pointing at user-writable paths.

VQL — Velociraptor
-- WaterPlum wallet-theft hunt: Run-key persistence in user-writable paths
-- plus processes with handles/cmdlines referencing wallet artifacts
LET persistence =
  SELECT Key.FullPath AS RegKey,
         Value.Name AS ValueName,
         Value.String AS ValueData
  FROM glob(globs=[
    'HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\*',
    'HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\*'
  ], accessor='registry')
  WHERE ValueData =~ '(?i)(appdata\\\\(local\\\\temp|roaming)|users\\\\public|programdata)'

LET wallet_procs =
  SELECT Pid, Name, Exe, CommandLine, Username, CreateTime
  FROM pslist()
  WHERE CommandLine =~ '(?i)(wallet\\.dat|keystore|electrum|exodus|nkbihfbeogaeaoehlefnkodbefgpgknn|get-clipboard|openclipboard)'
     OR Exe =~ '(?i)(appdata\\\\local\\\\temp|users\\\\public)'

SELECT * FROM persistence
UNION ALL
SELECT NULL AS RegKey, Name AS ValueName, CommandLine AS ValueData FROM wallet_procs

Remediation Script — Windows Verification & Hardening

Run on endpoints suspected of exposure, or fleet-wide via your RMM/GPO tooling for posture verification.

PowerShell
# WaterPlum Post-Compromise Verification & Hardening Script
# Run elevated. Review output before acting on flagged items.

Write-Host "=== [1] Suspicious Run-Key Persistence ===" -ForegroundColor Cyan
$runKeys = @(
  'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run',
  'HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce',
  'HKLM:\Software\Microsoft\Windows\CurrentVersion\Run',
  'HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce'
)
foreach ($key in $runKeys) {
  if (Test-Path $key) {
    Get-ItemProperty $key | Get-Member -MemberType NoteProperty | ForEach-Object {
      $val = (Get-ItemProperty $key).$($_.Name)
      if ($val -match 'AppData\\Local\\Temp|Users\\Public|AppData\\Roaming') {
        Write-Host "[FLAG] $key :: $($_.Name) = $val" -ForegroundColor Red
      }
    }
  }
}

Write-Host "=== [2] Wallet Artifacts Present (scoping) ===" -ForegroundColor Cyan
$walletPaths = @(
  "$env:APPDATA\Bitcoin\wallet.dat",
  "$env:APPDATA\Ethereum\keystore",
  "$env:APPDATA\Electrum\wallets",
  "$env:APPDATA\Exodus",
  "$env:LOCALAPPDATA\Google\Chrome\User Data\Default\Local Extension Settings\nkbihfbeogaeaoehlefnkodbefgpgknn"
)
foreach ($p in $walletPaths) {
  if (Test-Path $p) { Write-Host "[FOUND] $p (last write: $((Get-Item $p).LastWriteTime))" -ForegroundColor Yellow }
}

Write-Host "=== [3] Unsigned Executables in Temp/Roaming ===" -ForegroundColor Cyan
Get-ChildItem "$env:TEMP","$env:APPDATA" -Recurse -Include *.exe,*.dll,*.msi -ErrorAction SilentlyContinue |
  ForEach-Object {
    $sig = Get-AuthenticodeSignature $_.FullName
    if ($sig.Status -ne 'Valid') { Write-Host "[FLAG] $($_.FullName) - $($sig.Status)" -ForegroundColor Red }
  }

Write-Host "=== [4] Scheduled Tasks Launching from User Paths ===" -ForegroundColor Cyan
Get-ScheduledTask | Where-Object {
  $_.Actions.Execute -match 'AppData|Temp|Users\\Public'
} | ForEach-Object { Write-Host "[FLAG] $($_.TaskName) -> $($_.Actions.Execute) $($_.Actions.Arguments)" -ForegroundColor Red }

Write-Host "=== [5] Hardening: Enable ASR rules blocking credential theft (requires Defender) ===" -ForegroundColor Cyan
# Block credential stealing from LSASS + executable content from email/archive
Set-MpPreference -AttackSurfaceReductionRules_Ids `
  '9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2','be9ba2d9-53ea-4cdc-84e5-9b1eeee46550' `
  -AttackSurfaceReductionRules_Actions Enabled,Enabled

Write-Host "=== [6] Egress check: recent connections to non-RFC1918 from script hosts ===" -ForegroundColor Cyan
Get-NetTCPConnection -State Established -ErrorAction SilentlyContinue |
  Where-Object { $_.RemoteAddress -notmatch '^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.|127\.)' } |
  ForEach-Object {
    $proc = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
    if ($proc.ProcessName -match 'powershell|pwsh|node|python|wscript|cscript') {
      Write-Host "[FLAG] $($proc.ProcessName) (PID $($_.OwningProcess)) -> $($_.RemoteAddress):$($_.RemotePort)" -ForegroundColor Red
    }
  }

Write-Host "=== Review all [FLAG] entries with IR before removal. Preserve evidence. ===" -ForegroundColor Green

Remediation: Action Plan for Affected and At-Risk Organizations

If compromise is suspected (immediate, 0–24 hours):

  1. Assume all crypto material on the host is burned. Transfer remaining funds from any wallet whose artifacts (keystore files, seed phrases, browser-extension wallets) resided on a flagged endpoint to a newly generated wallet created on a clean device. Rotating a password on a compromised keystore is insufficient — the private key is exfiltrated.
  2. Rotate every credential stored in the browser on affected hosts, prioritizing exchange accounts, email, and SSO. Force enterprise-wide session revocation (revoke refresh tokens in Entra ID/Okta) for affected users.
  3. Isolate, don't reimage immediately. Capture memory and triage images first — the persistence mechanism and exfil destination are your threat-intelligence gold. Then reimage from known-good media.
  4. Report. Cryptocurrency theft by DPRK actors should be reported to the FBI (IC3) and your local field office; OFAC exposure considerations apply if stolen funds touch sanctioned wallets — involve counsel.

Structural hardening (this quarter):

  1. Move crypto off hot wallets on general-purpose endpoints. Hardware wallets with on-device signing, and corporate treasury under multisig or MPC custody. No employee workstation should hold unencrypted wallet material.
  2. Constrain developer package risk. Enforce allowlisted private registries/proxies for npm/PyPI, enable dependency scanning, and treat unsolicited "test assignments" from recruiters as hostile by policy.
  3. Block clipboard-based attacks where feasible. Endpoint policies that alert on clipboard reads of address-shaped strings; browser policies limiting extension installation to an allowlist (MetaMask on corporate machines should be an explicit, risk-accepted decision).
  4. Egress filtering. Deny direct outbound HTTPS from script hosts (powershell, node, python) to uncategorized domains at the proxy. DPRK staging relies heavily on cloud CDN abuse — domain-category filtering plus TLS inspection materially degrades it.
  5. Tabletop this scenario. "Developer machine infected via trojanized npm package; $2M in treasury crypto moved in 40 minutes" — if your IR plan doesn't cover key-compromise fund recovery, contact-tree activation with your custodian, and exchange freeze requests, fix that now.

There is no patch for social engineering. The joint advisory's 30,000-device count is a reminder that DPRK revenue operations succeed through volume and user trust exploitation — your detections above are the safety net, but the perimeter is the human and the wallet architecture.

Related Resources

Security Arsenal Managed SOC Services AlertMonitor Platform Book a SOC Assessment soc-mdr Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.