
Hunting DPRK's EtherHiding:
When Nation-States Weaponize the Blockchain
North Korean threat actors have adopted EtherHiding, a sophisticated technique that transforms public blockchains into resilient command-and-control infrastructure. The Google Threat Intelligence Group identified UNC5342 leveraging smart contracts on BNB Smart Chain and Ethereum to distribute JADESNOW and INVISIBLEFERRET malware, marking the first observed nation-state adoption of this decentralized payload delivery method.
Think of this like hiding secret messages in a library that no one can shut down. Traditional malware campaigns rely on servers that security teams can block or take offline, much like unplugging a suspicious vending machine. EtherHiding instead stores malicious code on blockchains - those permanent, decentralized ledgers designed to resist censorship. Once deployed, these digital instructions remain accessible to anyone who knows where to look, and there is no central off switch that defenders can flip.
This evolution represents a fundamental shift in the cybersecurity landscape with significant implications for organizations across financial and technology sectors. The immutable nature of blockchain storage means traditional containment strategies of domain takedowns, IP blocking, server seizures will be less effective against this threat vector. For security leadership, this threat demands investment in behavioral analytics capabilities, enhanced endpoint detection, and proactive threat hunting programs capable of identifying novel attack atterns before widespread compromise occurs.
Hunting Controls & Observations
Defensive teams should focus on identifying behavioral patterns associated with blockchain-based payload retrieval and multi-stage malware execution:
- Endpoint (EDR/AV)
JavaScript-based downloaders executing from user directories, Node.js or npm package installations outside corporate repositories, portable Python interpreter deployments, ZIP archive creation in temporary directories, and processes making unexpected blockchain API calls. - Identity/IAM
Unusual account access patterns following developer onboarding processes, credential theft targeting cryptocurrency wallet applications, browser extension data exfiltration, and unauthorized access to password management tools. - Email Security & Proxy Logs
Outbound connections to blockchain explorer APIs (BscScan, Etherscan, Blockchair, Blockcypher, Ethplorer), requests containing blockchain transaction hashes in URLs, Base64-encoded data in HTTP responses from blockchain endpoints, and traffic to fake recruiting company domains. - Firewall / NetFlow
Outbound connections on TCP port 3306 (MySQL) to non-database infrastructure, communication with Telegram API endpoints for data exfiltration, and repeated queries to multiple blockchain API providers within short timeframes. - Cloud Audit Logs
Access to npm registry for suspicious package downloads, GitHub repository cloning of recruiter-provided coding challenges, and unexpected API key usage for blockchain explorer services. - Windows Security Log
Process creation events (Event ID 4688) showing JavaScript interpreters spawning child processes, file creation in AppData directories (Event ID 4663), and credential manager access attempts (Event ID 5379). - Browser and Application Logs
Extension data access from JavaScript processes, cryptocurrency wallet application activity outside normal usage patterns, and browser credential store queries from non-browser processes.
Behavioral Indicators of Attack
The EtherHiding campaign exhibits distinctive behavioral patterns that differentiate it from traditional malware delivery mechanisms.
- JavaScript code making HTTP GET requests to blockchain explorer API endpoints with specific transaction hash parameters in the query string.
- Processes decoding Base64 content followed immediately by XOR decryption operations, typically performed in-memory without writing intermediate files to disk.
- Sequential API calls to multiple blockchain services (often three or more different providers) within seconds, indicating redundancy mechanisms for payload retrieval.
- Node.js or script interpreters spawning from social engineering contexts (job interview materials, GitHub repositories shared by recruiters, technical assessment files).
- Network beacons containing system reconnaissance data (hostname, username, operating system, current directory path) transmitted to non-standard MySQL ports.
- File system enumeration followed by ZIP archive creation and upload activity targeting browser profile directories, cryptocurrency wallet paths, and password manager locations.
- Smart contract interaction patterns using read-only function calls (eth_call) that retrieve data without generating blockchain transactions, avoiding detection through transaction monitoring.
MITRE Enterprise ATT&CK Tactics and Techniques
The EtherHiding campaign aligns with multiple tactics across the MITRE ATT&CK Enterprise Matrix, demonstrating sophisticated multi-stage attack chains:
- Initial Access (T1566.001 – Phishing: Spearphishing Attachment)
Threat actors deliver malicious npm packages and GitHub repositories through fake job interview processes, compelling victims to download and execute malicious code disguised as legitimate technical assessments. - Execution (T1059.007 – Command and Scripting Interpreter: JavaScript)
The campaign relies heavily on JavaScript-based downloaders that execute in Node.js environments, fetching and evaluating subsequent payloads retrieved from blockchain transactions. - Persistence (T1547.001 – Boot or Logon Autostart Execution Registry Run Keys / Startup Folder)
INVISIBLEFERRET establishes persistence mechanisms to maintain access across system reboots, ensuring continued backdoor functionality. - Defense Evasion (T1140 – Deobfuscate/Decode Files or Information)
Malware stages employ Base64 encoding and XOR encryption to obfuscate payloads stored on-chain, decrypting content in-memory to avoid static detection. - Defense Evasion (T1027 – Obfuscated Files or Information)
JavaScript payloads are heavily obfuscated, with variable names and control flow intentionally obscured to complicate analysis and signature-based detection. - Credential Access (T1555.003 – Credentials from Password Stores: Credentials from Web Browsers)
The campaign specifically targets browser-stored credentials, session cookies, and saved payment information from Chrome, Edge, and other browsers. - Credential Access (T1552.001 – Unsecured Credentials: Credentials In Files)
Malware components scan for cryptocurrency wallet files, password manager databases, and other credential stores located in predictable file system paths. - Discovery (T1082 – System Information Discovery):
Initial beacons collect and transmit victim system details including hostname, username, operating system version, and current working directory. - Collection (T1560.001 – Archive Collected Data: Archive via Utility)
Stolen credentials and browser data are compressed into ZIP archives before exfiltration, reducing bandwidth requirements and organizing stolen information. - Command and Control (T1102.001 – Web Service: Dead Drop Resolver)
Blockchain transactions serve as dead drop resolvers, with malware querying transaction calldata to retrieve C2 server addresses and subsequent payload locations. - Command and Control (T1071.001 – Application Layer Protocol: Web Protocols)
Communication with blockchain APIs occurs over standard HTTP/HTTPS, blending with legitimate Web3 application traffic. - Exfiltration (T1041 – Exfiltration Over C2 Channel)
Compressed credential archives are uploaded to attacker-controlled servers and private Telegram channels through established backdoor connections.
Controls & Hunting Indicators
Organizations can observe EtherHiding tactics across multiple layers of their security architecture, with visibility varying based on deployed monitoring capabilities and log retention policies.
Endpoint Controls
- EDR platforms should capture process creation events showing Node.js, npm, or JavaScript interpreters spawning from unexpected parent processes, particularly those initiated through social engineering contexts like interview materials or GitHub repository downloads.
- File operation monitoring should detect Base64-encoded JavaScript files being written to user AppData directories, portable Python interpreter installations in non-standard locations, and ZIP archive creation targeting browser profile paths.
- Network connection logs from endpoint agents should reveal JavaScript processes establishing outbound connections to blockchain API providers including BscScan, Etherscan, Blockchair, Blockcypher, and Ethplorer, often with transaction hashes embedded in URLs.
- Sysmon Event ID 1 (Process Creation) captures command-line arguments showing npm install commands with suspicious package names, Node.js executing scripts with obfuscated names, and Python interpreters running credential theft modules.
- Sysmon Event ID 3 (Network Connection) identifies JavaScript interpreters or Node.js connecting to TCP port 3306 on non-database servers, indicative of INVISIBLEFERRET backdoor beaconing activity.
- PowerShell Script Block Logging (Event ID 4104) may capture decoded JavaScript payloads if PowerShell is used as an intermediate execution layer, though this campaign primarily relies on Node.js.
Network Controls
- Web proxy logs should show HTTP GET requests to blockchain explorer APIs with specific URL patterns containing transaction hashes (e.g., /api?module=proxy&action=eth_call&data=0x...), particularly when sourced from desktop endpoints rather than server infrastructure.
- DNS query logs reveal lookups for blockchain explorer domains (bscscan.com, etherscan.io, blockchair.com, api.ethplorer.io) originating from user workstations, especially when occurring in rapid succession across multiple providers.
- Firewall denied connection logs may capture initial beacon attempts to C2 infrastructure on TCP port 3306 if egress filtering is enforced, providing early warning of compromise attempts.
- SSL/TLS inspection appliances can identify Base64-encoded and XOR-encrypted payloads within HTTPS responses from blockchain APIs, though payload obfuscation may require behavioral analysis rather than signature matching.
- NetFlow data from network devices shows unusual traffic patterns including high query volumes to blockchain services from individual endpoints and data exfiltration to Telegram API endpoints (api.telegram.org).
Identity & Access Controls
- Windows Event ID 4688 (Process Creation) with command-line logging enabled captures the full execution chain including npm package installations, Node.js script execution, and Python interpreter launches with specific module parameters.
- Windows Event ID 4663 (File System Access) logs access attempts to browser credential stores (Login Data, Cookies files in Chrome/Edge profiles), cryptocurrency wallet directories, and password manager databases.
- Windows Event ID 5379 (Credential Manager Access) may indicate attempts to read stored credentials from Windows Credential Manager, though this campaign primarily targets browser-based credentials.
- Windows Event ID 4624 (Logon Success) should be correlated with subsequent blockchain API activity to identify compromised accounts being used for reconnaissance and credential theft.
- Active Directory audit logs should monitor for unusual authentication patterns following new hire onboarding or contractor access provisioning, particularly in development teams with cryptocurrency exposure.
Cloud & SaaS
- GitHub audit logs reveal repository cloning activity for fake recruiter accounts or suspicious organizations (BlockNovas LLC, Angeloper Agency, SoftGlideLLC), often followed by issue or discussion interactions with target developers.
- npm registry access logs show package downloads from suspicious publisher accounts, particularly packages with recently created timestamps, minimal download counts, and obfuscated code structures.
- Cloud provider audit trails (AWS CloudTrail, Azure Activity Log) should monitor for EC2 instance launches or virtual machine deployments on port 3306 that do not correlate with legitimate database infrastructure.
- SaaS application logs for developer platforms like GitLab, Bitbucket, and package repositories should track account creation patterns, forked repository activity, and collaboration requests from newly established accounts.
- Blockchain API service provider logs (when available through enterprise agreements) can reveal excessive query patterns, free API key abuse, and smart contract read operations targeting known malicious contract addresses.
Application & Service Logs
- Web server access logs for corporate websites should monitor for injected JavaScript code patterns, particularly loader scripts referencing blockchain API endpoints or containing Base64-encoded content.
- Browser extension logs and Chrome Enterprise policy compliance reports can identify unauthorized extension installations or modifications that facilitate credential theft.
- Email gateway logs should flag recruitment-themed messages containing GitHub links, npm package references, or requests to execute coding challenges outside corporate development environments.
- Messaging platform logs (Slack, Discord, Telegram) should monitor for external communications involving job interviews, particularly those transitioning to direct file sharing or external repository links.
- Application whitelisting logs can detect unapproved Node.js, npm, or Python interpreter executions outside sanctioned development environments.
Known Indicators of Compromise
The following IOCs have been identified from the intelligence to be used for threat hunting.
- File Hashes:
YARA rules provided for JADESNOW detection targeting obfuscated JavaScript patterns - Smart Contract Addresses:
0x8eac3198dd72f3e07108c4c7cff43108ad48a71c (BNB Smart Chain - JADESNOW storage)
Multiple Ethereum addresses used as dead drop resolvers to burn address 0x00...dEaD - Transaction Hashes:
0x5c77567fcf00c317b8156df8e00838105f16fdd4fbbc6cd83d624225397d8856 (BNB Smart Chain - JADESNOW payload)
0x86d1a21fd151e344ccc0778fd018c281db9d40b6ccd4bdd3588cb40fade1a33a (Ethereum - INVISIBLEFERRET.JAVASCRIPT)
0xc2da361c40279a4f2f84448791377652f2bf41f06d18f19941a96c720228cd0f (Ethereum - Split payload component)
0xf9d432745ea15dbc00ff319417af3763f72fcf8a4debedbfceeef4246847ce41 (Ethereum - Credential stealer) - Domains:
binplorer[.]com (Blockchain API service)
bscscan[.]com (BNB Smart Chain explorer)
etherscan[.]io (Ethereum explorer)
blockchair[.]com (Multi-chain explorer API)
blockcypher[.]com (Blockchain API service)
api[.]ethplorer[.]io (Ethereum explorer API)
api[.]telegram[.]org (Exfiltration endpoint) - File Paths:
%APPDATA%/npm/ (Malicious package installations)
%LOCALAPPDATA%/Google/Chrome/User Data/Default/Login Data (Credential targets)
%LOCALAPPDATA%/Microsoft/Edge/User Data/Default/Cookies (Session theft targets)
Portable Python interpreter in temporary directories - Network Indicators:
TCP port 3306 connections to non-database infrastructure
HTTP GET requests with "eth_call" in query parameters
Multiple blockchain API queries within 5-second windows
API requests using "apiKey=freekey" parameter (Ethplorer development key) - Fake Recruiting Organizations:
BlockNovas LLC
Angeloper Agency
SoftGlideLLC
Insights and Recommendation
Organizations that fail to adapt their detection strategies to EtherHiding face sustained credential theft, cryptocurrency asset loss, and persistent network compromise that traditional blocking mechanisms cannot remediate. The technique's resilience against takedown efforts means attackers maintain payload availability indefinitely, enabling continuous campaign refinement and target re-engagement without infrastructure rebuilding costs. Financial institutions and cryptocurrency-adjacent businesses face direct revenue loss through wallet compromise, while technology firms risk intellectual property theft and supply chain contamination through developer workstation compromise.
Security teams should prioritize behavioral detection over signature-based approaches, implementing continuous monitoring for blockchain API interactions from non-Web3 systems, script execution from social engineering contexts, and credential access patterns outside browser processes. Organizations should enforce Chrome Enterprise policies restricting dangerous file downloads, automate browser updates to eliminate fake update social engineering vectors, and establish baseline network behavior for developer teams to identify anomalous blockchain service queries. Threat hunting programs should proactively search for npm package installations from untrusted repositories, Node.js execution outside sanctioned development environments, and port 3306 connections originating from workstations. Given the sophisticated social engineering employed in DPRK campaigns, security awareness training must specifically address fake recruitment processes, emphasizing verification protocols for job opportunities and technical assessment legitimacy before executing external code.
Source and Credits
This summary is based on Google Threat Intelligence Group's research article "DPRK Adopts EtherHiding: Nation-State Malware Hiding on Blockchains" published in February 2025. The analysis was authored by Blas Kojusner, Robert Wallace, and Joseph Dobson of the Google Threat Intelligence Group (GTIG).
Threat Hunting Queries
The following queries translate EtherHiding behavioral indicators into actionable detection logic, enabling security teams to proactively hunt for compromise across endpoint, network, and identity telemetry sources.
Query 1: Blockchain API Communication from Endpoints
- Behavior Targeted: JavaScript processes making HTTP requests to blockchain explorer APIs for transaction data retrieval
- MITRE ATT&CK: T1102.001 (Web Service: Dead Drop Resolver), T1071.001 (Application Layer Protocol: Web Protocols)
- Expected Results: Endpoint processes (Node.js, JavaScript interpreters, browsers) communicating with blockchain APIs, particularly when multiple providers are queried sequentially
- False Positive Likelihood: Medium – Legitimate Web3 developers and cryptocurrency applications also query blockchain APIs; focus on processes spawned from social engineering contexts and those querying multiple providers rapidly
Splunk (SPL)
// Hunt for blockchain API communication from endpoint processes
// Tune by excluding known Web3 development teams or whitelisted applications
index=proxy OR index=firewall OR index=edr
(dest_domain IN ("*bscscan.com", "*etherscan.io", "*blockchair.com",
"*blockcypher.com", "*ethplorer.io", "binplorer.com")
OR url IN ("*eth_call*", "*action=eth_getTransactionByHash*", "*tx/0x*"))
| eval blockchain_api=case(
match(dest_domain, "bscscan"), "BscScan",
match(dest_domain, "etherscan"), "Etherscan",
match(dest_domain, "blockchair"), "Blockchair",
match(dest_domain, "blockcypher"), "Blockcypher",
match(dest_domain, "ethplorer"), "Ethplorer",
match(dest_domain, "binplorer"), "Binplorer",
1=1, "Unknown")
| stats count values(blockchain_api) as apis_queried
values(url) as urls
dc(blockchain_api) as unique_apis
earliest(_time) as first_seen
latest(_time) as last_seen
by src_ip, user, process_name
| where unique_apis >= 2 // Flag if multiple blockchain APIs queried
| eval time_span=last_seen-first_seen
| where time_span < 60 // Within 60 seconds suggests automated behavior
| sort - unique_apis
Microsoft Defender/Sentinel (KQL)
// Hunt for blockchain API communication from endpoint processes
// Data Tables: DeviceNetworkEvents, DeviceProcessEvents
// Tune by excluding known developer workstations or Web3 application servers
let BlockchainAPIs = dynamic(["bscscan.com", "etherscan.io", "blockchair.com",
"blockcypher.com", "ethplorer.io", "binplorer.com"]);
let TimeWindow = 60s; // Adjust based on false positive rate
DeviceNetworkEvents
| where TimeGenerated > ago(7d)
| where RemoteUrl has_any (BlockchainAPIs)
or RemoteUrl contains "eth_call"
or RemoteUrl contains "eth_getTransactionByHash"
| extend BlockchainAPI = case(
RemoteUrl contains "bscscan", "BscScan",
RemoteUrl contains "etherscan", "Etherscan",
RemoteUrl contains "blockchair", "Blockchair",
RemoteUrl contains "blockcypher", "Blockcypher",
RemoteUrl contains "ethplorer", "Ethplorer",
RemoteUrl contains "binplorer", "Binplorer",
"Unknown")
| summarize UniqueAPIs=dcount(BlockchainAPI),
APIs=make_set(BlockchainAPI),
URLs=make_set(RemoteUrl),
FirstSeen=min(TimeGenerated),
LastSeen=max(TimeGenerated),
ConnectionCount=count()
by DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine
| extend TimeSpan = datetime_diff('second', LastSeen, FirstSeen)
| where UniqueAPIs >= 2 and TimeSpan <= 60 // Multiple APIs within time window
| project-reorder DeviceName, InitiatingProcessFileName, UniqueAPIs, ConnectionCount, TimeSpan
Query 2: Node.js or npm Execution from Social Engineering Contexts
- Behavior Targeted: Node.js, npm, or JavaScript interpreters spawning from user directories containing interview materials, GitHub clones, or temporary downloads
- MITRE ATT&CK: T1059.007 (Command and Scripting Interpreter: JavaScript), T1566.001 (Phishing: Spearphishing Attachment)
- Expected Results: JavaScript, Node.js, or Python processes reading browser credential files, particularly when followed by ZIP archive creation and network upload activity
- False Positive Likelihood: Low – Browser credential stores should only be accessed by their respective browser processes; external access is highly suspicious
Splunk (SPL)
// Detect non-browser processes accessing credential stores
// Tune by validating legitimate backup or security scanning tools
index=edr OR index=windows EventCode=4663
ObjectName IN ("*\\Google\\Chrome\\*\\Login Data*",
"*\\Google\\Chrome\\*\\Cookies*",
"*\\Microsoft\\Edge\\*\\Login Data*",
"*\\Microsoft\\Edge\\*\\Cookies*",
"*\\Mozilla\\Firefox\\*\\logins.json*",
"*\\MetaMask\\*", "*\\Phantom\\*", "*\\1Password\\*")
NOT ProcessName IN ("chrome.exe", "msedge.exe", "firefox.exe", "1Password.exe")
| rex field=ObjectName "(?Login Data|Cookies|logins\\.json|MetaMask|Phantom|1Password)"
| stats count values(ObjectName) as accessed_files
values(ProcessName) as accessing_processes
values(ProcessCommandLine) as commands
by ComputerName, SubjectUserName, credential_type
| where count > 5 // Multiple file access attempts
| sort - count
Microsoft Defender/Sentinel (KQL)
// Detect non-browser processes accessing credential stores
// Data Tables: DeviceFileEvents, DeviceProcessEvents
// Tune by excluding legitimate credential managers and backup solutions
let CredentialPaths = dynamic(["Login Data", "Cookies", "logins.json",
"MetaMask", "Phantom", "1Password", "Bitwarden"]);
let BrowserProcesses = dynamic(["chrome.exe", "msedge.exe", "firefox.exe",
"brave.exe", "opera.exe"]);
DeviceFileEvents
| where TimeGenerated > ago(7d)
| where ActionType in ("FileOpened", "FileRead", "FileModified")
| where FolderPath has_any (CredentialPaths)
| where InitiatingProcessFileName !in~ (BrowserProcesses)
| extend CredentialType = case(
FolderPath contains "Login Data", "BrowserPasswords",
FolderPath contains "Cookies", "BrowserCookies",
FolderPath contains "logins.json", "FirefoxPasswords",
FolderPath contains "MetaMask" or FolderPath contains "Phantom", "CryptoWallet",
FolderPath contains "1Password" or FolderPath contains "Bitwarden", "PasswordManager",
"Other")
| summarize AccessCount=count(),
Files=make_set(FileName),
FirstAccess=min(TimeGenerated),
LastAccess=max(TimeGenerated)
by DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, CredentialType
| where AccessCount >= 3 // Multiple access attempts indicate systematic theft
| project-reorder DeviceName, InitiatingProcessFileName, CredentialType, AccessCount
Query 4: MySQL Port (3306) Connections to Non-Database Infrastructure
- Behavior Targeted: Workstation processes establishing TCP connections on port 3306 to external or non-database servers, indicative of INVISIBLEFERRET backdoor beaconing
- MITRE ATT&CK: T1071.001 (Application Layer Protocol: Web Protocols)
- Expected Results: Unexpected port 3306 connections from JavaScript or Node.js processes to external IP addresses, especially when originating from user workstations
- False Positive Likelihood: Low to Medium – Port 3306 is reserved for MySQL database communication; workstation connections to non-database infrastructure are suspicious unless connecting to known database servers
Splunk (SPL)
// Hunt for suspicious MySQL port usage from workstations
// Tune by whitelisting known database server IP addresses and developer tools
index=firewall OR index=edr OR index=network
dest_port=3306
| where NOT (dest_ip IN ("10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16")
AND host_type="database_server") // Exclude internal DB servers
| lookup asset_inventory src_ip OUTPUT asset_type
| where asset_type IN ("workstation", "laptop", "desktop") OR isnull(asset_type)
| stats count values(dest_ip) as destinations
values(dest_port) as ports
values(process_name) as processes
earliest(_time) as first_seen
latest(_time) as last_seen
by src_ip, user, host
| eval duration=tostring(last_seen-first_seen, "duration")
| where count > 1 // Repeated connections suggest C2 beaconing
| sort - count
Microsoft Defender/Sentinel (KQL)
// Hunt for suspicious MySQL port usage from workstations
// Data Tables: DeviceNetworkEvents
// Tune by excluding known database administration tools and server management consoles
let DatabaseServers = dynamic(["10.0.1.50", "10.0.1.51"]); // Add your DB IPs
let DatabaseTools = dynamic(["mysql.exe", "mysqladmin.exe", "HeidiSQL.exe",
"SQLyog.exe", "mysqlworkbench.exe"]);
DeviceNetworkEvents
| where TimeGenerated > ago(7d)
| where RemotePort == 3306
| where RemoteIPType == "Public" or RemoteIP !in (DatabaseServers)
| where InitiatingProcessFileName !in~ (DatabaseTools)
| summarize ConnectionCount=count(),
Destinations=make_set(RemoteIP),
FirstConnection=min(TimeGenerated),
LastConnection=max(TimeGenerated),
BytesSent=sum(SentBytes),
BytesReceived=sum(ReceivedBytes)
by DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine
| extend Duration = datetime_diff('minute', LastConnection, FirstConnection)
| where ConnectionCount >= 2 // Multiple connections suggest persistent backdoor
| project-reorder DeviceName, InitiatingProcessFileName, ConnectionCount, Duration, Destinations
Query 5: Base64 Decoding Followed by XOR Decryption in Memory
- Behavior Targeted: JavaScript or PowerShell processes performing Base64 decoding operations followed by XOR or bitwise operations, characteristic of EtherHiding payload decryption
- MITRE ATT&CK: T1140 (Deobfuscate/Decode Files or Information), T1027 (Obfuscated Files or Information)
- Expected Results: Script execution containing both Base64 decode functions and XOR operations in the same command line or script block
- False Positive Likelihood: Medium – Legitimate applications may use encoding; focus on combinations of Base64 decoding with cryptographic operations and execution from suspicious contexts
Splunk (SPL)
// Detect Base64 decoding with XOR operations in scripts
// Tune based on environment; consider excluding known development scripts
index=edr OR index=windows EventCode IN (4104, 4688)
(ScriptBlockText="*" OR CommandLine="*")
| eval has_base64=if(match(ScriptBlockText, "(?i)(frombase64|base64|atob|Buffer\\.from)")
OR match(CommandLine, "(?i)(frombase64|base64|atob)"), 1, 0)
| eval has_xor=if(match(ScriptBlockText, "(?i)(xor|\\^|charCodeAt)")
OR match(CommandLine, "(?i)(xor|\\^)"), 1, 0)
| eval has_eval=if(match(ScriptBlockText, "(?i)(eval|invoke-expression|iex)")
OR match(CommandLine, "(?i)(eval|iex)"), 1, 0)
| where has_base64=1 AND has_xor=1
| stats count values(ScriptBlockText) as script_content
values(CommandLine) as commands
values(ParentProcessName) as parent_process
by ComputerName, User, ProcessName
| where count >= 1
| sort - count
Microsoft Defender/Sentinel (KQL)
// Detect Base64 decoding with XOR operations in scripts
// Data Tables: DeviceProcessEvents, DeviceEvents (for script block logging)
// Tune by excluding known legitimate automation frameworks
let Base64Pattern = dynamic(["frombase64", "base64", "atob", "Buffer.from", "btoa"]);
let XORPattern = dynamic(["xor", "^", "charCodeAt", "charCode"]);
let EvalPattern = dynamic(["eval", "invoke-expression", "iex", "invoke-command"]);
DeviceProcessEvents
| where TimeGenerated > ago(7d)
| where FileName in~ ("node.exe", "powershell.exe", "pwsh.exe", "wscript.exe", "cscript.exe")
| extend HasBase64 = iff(ProcessCommandLine has_any (Base64Pattern), 1, 0)
| extend HasXOR = iff(ProcessCommandLine has_any (XORPattern), 1, 0)
| extend HasEval = iff(ProcessCommandLine has_any (EvalPattern), 1, 0)
| where HasBase64 == 1 and HasXOR == 1 // Both encoding and crypto operations
| extend SuspicionScore = HasBase64 + HasXOR + HasEval
| project TimeGenerated, DeviceName, AccountName, FileName,
ProcessCommandLine, SuspicionScore, InitiatingProcessFileName
| order by SuspicionScore desc, TimeGenerated desc