MacSync under the microscope: new delivery methods and a new payloadMacSync 深度解析:全新交付方式与全新有效载荷
We look at a new version of the MacSync macOS stealer with a backdoor module that targets crypto enthusiasts and developers.

Malware descriptions
Loader, Calendar, and Two Simple Droppers
A couple more scripts
Indicators of compromise
MacSync is a relatively young, rapidly evolving family of crypto/info stealers. First advertised on the dark web in 2025 as Mac.c, the stealer was later renamed to MacSync by its creators. The initial versions were implemented as AppleScripts and closely resembled the AMOS stealer family, but over time, MacSync developed distinctive features of its own, including a backdoor module. In this report, we discuss a new infection chain that differs significantly from previous variants. We first spotted it in the wild in September 2026.
The developers of this family have overhauled their approach to payload delivery by replacing script-based droppers with binary ones.
The main malicious payload now consists of modules written in Objective-C and Swift.
At one stage of infection, the attackers use iCloud to deliver the next
Kaspersky solutions detect the threats described below under the following verdicts:
HEUR:Trojan.OSX.MacSync.*
HEUR:Trojan-PSW.OSX.MacSync.*
HEUR:Trojan-Dropper.OSX.MacSync.*
HEUR:Trojan-Downloader.OSX.MacSync.*
MacSync is an infostealer distributed under the malware-as-a-service (MaaS) model, so the specific delivery method for the first stage of the infection chain is up to the operators. Recent public reports on MacSync have mostly focused on modules delivered through social engineering and ClickFix-style attacks. However, both then and now, the malware has also spread disguised as free or cracked versions of popular applications, as well as under the guise of new software. For example, we found MacSync masquerading as a nonexistent crypto wallet app called Toria; the attackers not only created a dedicated web page for it but also promoted it on X and Telegram:
The latest version of the infostealer we discovered starts the infection chain with malicious DMG images. Even within a single campaign built around one fake application, we found two different ways the infostealer and backdoor modules were delivered to the victim’s device. In one, the payload inside the DMG was a compiled JXA script that, once launched, decoded a shell script and passed it directly to the interpreter without writing it to disk. In the other version of the application, the same script appeared at a later stage of infection, after a chain of droppers and loaders had run. We’ll take a look at the second infection chain in detail, since it is more complex and technically interesting. The infection scheme is shown below:
It’s worth noting right away that MacSync shows shared traits at almost every stage:
All temporary files are placed in the /tmp directory. The same directory is where *.lock files are created to prevent the malware from running again.
Once its task is complete, the module removes traces of its activity: temporary files, its own logs, and so on.
All binary files are in the FAT Mach-O format and target devices with both Apple and Intel processors.
In this infection chain, the payload on the disk image is an .APP application. When started, it first checks whether the whole bundle has the com.apple.quarantine extended quarantine attribute, and if it finds one, it runs the xattr -cr <app_name> command to remove all attributes. Next, it extracts an XOR-encrypted URL from its overlay and decrypts it with the key 73 6f 6e 6f 6d 61 62 6c 64 07 . After the encrypted data, there are 8 bytes indicating the length of the ciphertext, followed by the magic word SONOMAC1 . It’s worth noting that the malware reads the overlay backwards: it first locates the magic word, then reads the data size, and then uses the size to determine the boundaries of the data block containing the ciphertext.
The resulting URL is a link to the next-stage downloader script. In some cases, this link pointed directly to a file hosted on an attacker-controlled server; however, in at least one sample, the link pointed to a public iCloud calendar:
Contents of the downloaded calendar
After retrieving the calendar file from the server, the downloader creates an anonymous pipe, launches the interpreter to read commands from standard input ( zsh -s ), sets the pipe as standard input, and redirects the contents of the calendar into it line by line. Since a calendar is normally not a command, the interpreter treats the lines as invalid commands until it reaches the malicious payload after the DESCRIPTION : line. These commands ultimately download a .TAR.GZ archive from iCloud that contains an .APP bundle. The downloader removes the quarantine attribute from it, signs it with an ad-hoc signature, and executes it.
We don’t know the contents of the scripts distributed from the attacker’s server, but they are very likely the same script found in the calendar event description.
The downloaded application is a dropper. The malicious payload it extracts is a zlib-compressed executable encrypted with AES in CBC mode, using the following key and initialization vector:
The dropper decrypts and unpacks it, then places it at /tmp/.sys-<16-digit random value>.
Inside is another dropper, but unlike the previous stages, this one includes anti-debugging protection. In particular, it checks whether it’s running on a virtual machine by making sysctl queries with the kern.hv_vmm_present and machdep.cpu.brand_string parameters. It also sets the PT_DENY_ATTACH flag with ptrace to prevent a debugger from attaching to the process. The payload is a shell script encrypted with AES in CBC mode, using the following key and initialization vector:
Payload of the second dropper
As shown in the screenshot above, the second dropper delivers a downloader script that retrieves the next-stage payload from the command-and-control server, decrypts it with AES in CBC mode using the following key and initialization vector, and then executes it in memory:
Inside the retrieved script, we can immediately spot several familiar indicators associated with the MacSync malware family:
The main function in the script is named daemon_function .
The stolen data is uploaded to the command-and-control server via PUT requests. The data in the requests is sent in 90-megabyte chunks. In earlier versions, the chunk sizes differed.
One way to establish persistence on a system it uses is to inject a malicious command into the .ZSHRC, the configuration file for the ZSH interpreter, which contains commands that run each time the interpreter starts.
The URL path where the backdoor executable is stored on the command-and-control server begins with the /loader/ directory.
The script performs the following tasks:
Downloading and decrypting additional malicious modules: an infostealer, a backdoor, and a special utility for generating encryption keys and decrypting downloaded executable files
Gaining persistence on the system
Uploading data received from the infostealer module to the command-and-control server
One detail stands out: instead of the usual encryption algorithms (XOR, AES, and so on), the attackers took a different approach to delivering malicious modules at this stage. It involves a selfmade utility called pkgunpack that implements two commands: genkey and decrypt . The malicious payload is decrypted as follows:
The malware generates a public and private encryption key pair using genkey command from pkgunpack, whose generation function relies on an open implementation of the elliptic-curve Diffie-Hellman protocol on Curve25519: curve25519_donna .
The public key is encoded in base64 and sent to the command-and-control server together with a one-time code generated by the command $(date +%s)-${RANDOM}-$$ .
The server responds with the following JSON: { "ok": true, "dek_wrap_b64": <base64_encoded_encrypted_key> , "build_pub_b64": "pFSxn/Uwg9bS45aVKCzA+8exSMfDHXpbpHC/f7G472w=", "crypto": "v2.5" } 1 2 3 4 5 6 { "ok" : true , "dek_wrap_b64" : < base64_encoded_encrypted_key > , "build_pub_b64" : "pFSxn/Uwg9bS45aVKCzA+8exSMfDHXpbpHC/f7G472w=" , "crypto" : "v2.5" } Here, build_pub_b64 is the server’s public key, which is also predefined in the script itself, and dek_wrap_b64 is a base64-encoded string that contains the payload encryption key. This key is encrypted on the server side with a shared secret computed from the public key generated with pkgunpack on the victim’s device.
Then decrypt command from pkgunpack utility decrypts the key: A shared secret is computed from the server’s known public key and the private key for the current session, using the same ECDH Curve25519 key exchange scheme that was used to generate the keys. The resulting shared secret is concatenated with the string sn-dek-wrap-v1 , and a SHA-256 hash is computed from the result. Next, the dek_wrap_b64 block received from the server is decoded. It has the following structure: The first 5 bytes: additional authenticated data (AAD) The next 12 bytes: the initialization vector (IV) The rest: the ciphertext The ciphertext is decrypted with AES in GCM mode using the previously obtained key, IV, and AAD. Decoded dek_wrap_b64
A shared secret is computed from the server’s known public key and the private key for the current session, using the same ECDH Curve25519 key exchange scheme that was used to generate the keys.
The resulting shared secret is concatenated with the string sn-dek-wrap-v1 , and a SHA-256 hash is computed from the result.
Next, the dek_wrap_b64 block received from the server is decoded. It has the following structure: The first 5 bytes: additional authenticated data (AAD) The next 12 bytes: the initialization vector (IV) The rest: the ciphertext
The first 5 bytes: additional authenticated data (AAD)
The next 12 bytes: the initialization vector (IV)
The rest: the ciphertext
The ciphertext is decrypted with AES in GCM mode using the previously obtained key, IV, and AAD. Decoded dek_wrap_b64
Decoded dek_wrap_b64
The result is the key for decrypting the downloaded malicious payload. The payload, in turn, also contains an AAD and an IV in its header and is encrypted with AES GCM. The utility decrypts it and terminates.
Note that at each individual stage, the utility zeros out buffers after using encryption keys and data, apparently to impede forensic data collection and dynamic analysis of samples.
As mentioned earlier, at this stage, the script downloads only two modules: an infostealer and a backdoor. Once decrypted, both are .TAR.GZ archives; their contents are extracted, stripped of all extended attributes (such as com.apple.quarantine ), and signed with an ad-hoc signature. The infostealer module runs first: it collects the data it needs, places it in a temporary folder, and compresses it into a .TAR.GZ archive, which the script then sends to the attackers’ server. Next, before launching the backdoor, the script sets up persistence for it and creates a backup copy. The backup copy, along with the other files it needs to operate, is placed in $HOME/Library/Application Support/System. This directory doesn’t exist in macOS by default; the script creates it. The backdoor disguises itself as the Finder application and achieves persistence in the system through the following methods:
A LaunchAgent named com.apple.finder.agent
Injection of a command that runs the .repair-run script when the ZSH interpreter starts from the .ZSHRC
Injection of a similar command, which also runs the .repair-run script, into the global GIT pre-commit and post-checkout hooks
The .repair-run script checks whether the backdoor files exist, restores them from a backup if they are missing, and re-creates and reloads the LaunchAgent. At the same time, it kills the BTMNotificationAgent , NotificationCenter , and BackgroundTaskManagementAgent system processes to prevent the system from notifying the user about the new LaunchAgent.
One last thing worth noting about the script at this stage is its use of a custom HTTP header, X-Upload-Token , without which the C2 server responds to requests with errors. During our research, we observed the use of the following tokens: b8b4b88205a8f594b95a841bc37342898f34cad8a5a9e4a22ce69a31a1208650 and ff3ab9ef841630364818396f62e696b72aed162cf0b895b6643ef25dad79b51d . The backdoor later uses these same tokens to communicate with the C2 server.
The infostealer module ships as an .APP application, with its main executable written in Swift. As with previous AppleScript-based versions, the malware first asks the user for the administrator password. It adapts the window it displays to match the application it is impersonating. After the password is entered, the user sees a window that imitates a system notification about a corrupted application, offering to move it to the trash.
Fake stealer pop-up windows
Interestingly, instead of the method most macOS malware families use to verify a password, the dscl utility, the attackers used the Pluggable Authentication Modules (PAM) API. This is a fairly new technique for macOS malware, first observed in the wild in July 2026 in the Pam Stealer family. It apparently caught the attention of malware authors, and we may see it used more often going forward.
Password verification with PAM
Many strings in the stealer (file names, directory names, team IDs, and so on) are XOR-encrypted and stored in static arrays. The encryption keys differ between samples and are generated based on the ciphertext length.
The set of data the stealer collects has expanded slightly compared to previous versions. The generalized list is as follows:
Browser data: browsing history, cookies, crypto wallet extension data, saved logins and passwords, and Local State files
Crypto wallet application data
Device login and password
System information: list of installed applications and running processes, device model, hardware, UUID, and so on
Configuration files for SSH, ZSH, AWS, Kubernetes, GIT, and other services/programs
ZSH and Bash command history
Current user profile picture
The collected data is saved to a hidden directory in /tmp/.
The stealer module also has one interesting feature, disabled in all samples discovered so far and apparently still in development. Its purpose is to check whether the malicious application’s resources contain a file called KcHelper at <app_path>/Contents/Resources/Helpers, and, if the file is present, launch it with certain parameters. If this file is missing, a fallback function, _kc_grab_storage_item , is executed instead. Since KcHelper was not present among the application’s resources at the time of our research, we can only speculate about its purpose based on our analysis of this function. It first runs a command that modifies the partition_id of the keychain entry for a specific service so that three categories of applications can access it without user confirmation and without the keychain password:
teamid: the application is signed with a certificate that has a specific teamID (in this case, the target application’s developer)
apple: the application is an Apple service
apple-tool: the application is an Apple command-line utility
The stealer then uses the Security.framework API to try and retrieve the secret’s contents on its own, which still ends up triggering a confirmation request for the operation. It appears the threat actors plan to refine this feature in the future to gain unimpeded access to secrets even if the keychain password changes, but at this point, they haven’t managed to do so, which is why the feature is disabled. In the stealer’s encrypted strings, we saw examples of arguments for the command that modifies partition_id , which indicate that the attackers are after browser secrets. Example:
Code section responsible for changing access to keychain services
The backdoor is a Fat Mach-O executable written in Objective-C. It has two launch modes: a regular one and one with the --persist-status flag. In the second mode, it only checks how it was added to the persistence objects: as a Login Item or as a LaunchAgent. In standard mode, before proceeding to its main functionality, the backdoor also checks whether it has been added to autorun in any way. If not, it uses the same persistence mechanism as the parent script. However, for macOS versions older than 13.0, a separate helper executable stored inside the backdoor’s body is used regardless of whether autorun objects are present. The helper performs a single task: it uses the CoreServices.framework API to add the executable file passed to it as an argument to the Login Items.
As with the droppers from the early stages of the infection chain, the configuration for communicating with the C2 is stored in the executable’s overlay and encrypted with XOR using the same key. It consists of several strings separated by null bytes:
AGNT1 : a magic constant confirming that the configuration was decrypted correctly
Access token: the same one used in the parent script
BLD-150 : the backdoor build number
The malware also writes logs to $HOME/Library/Logs/.sysnotif-agent.log and supports extended logging when launched with the LAUNCHER_DEBUG environment variable. Communication with the C2 takes place over HTTP. The server’s response should be a JSON file.
tag : the victim’s unique ID combined with the backdoor build number
build : backdoor build number
old_token : previous token
upload_id : an identifier for the object being uploaded, generated randomly based on a timestamp, the process ID, and a random four-byte number
command_status : a status unique to the commands the agent executes
upload_id : the ID of the file uploaded to the server (if any)
phase : information about the command being executed or its stage
active : command in-progress flag ( true = still running; false = finished)
Although the backdoor offers several different commands, they all boil down to the same action: extract the base64-encoded AppleScript script from the script_b64 field in the server’s response and execute it. Individual command handlers then act as wrappers around the scripts, correctly populating telemetry and sending requests to the C2 server. Based on the command names and the messages sent to the server during their execution, we can reconstruct their purpose without having the scripts on hand. The backdoor supports the following commands:
deploy_ext : deploy an extension downloaded from the server into the victim’s browser.
deploy_ledger : replace the installed Ledger wallet with the version from the server.
regrab : collect system information and/or specific files again. This time, the collected data is packaged into an archive typical for the MacSync family, at /tmp/osalogging.zip, unless a different path is specified in the archive_path field sent along with the command.
live_browser : the only command executed without an AppleScript script. The backdoor checks for the presence of the sn_relay file among its resources, and if it’s not found, downloads and executes it. Its content and purpose remain a mystery to us, but based on the command name and the messages sent to the server, we can assume that the attackers somehow implement a MitM attack on traffic originating from the victim’s browser.
The section of the regrab command where the archive’s integrity is verified and its hash is calculated before it is sent
The new version of the MacSync infostealer differs quite significantly from its previously observed variants. The attackers have substantially overhauled their approach to executing the stealer’s and backdoor’s main malicious payload, moving from AppleScripts to full-fledged executable files written in Swift and Objective-C. It’s also worth noting the more complex infection chain: instead of obfuscated shell scripts delivered through ClickFix attacks, this version used binary droppers and loaders, some of which leveraged Apple’s infrastructure as one of the intermediate stages for delivering the malicious payload.
The nature of the data attackers seek to collect from a victim’s device, as well as the categories of applications the stealer disguises itself as, clearly indicates that this malware family primarily targets developers, crypto enthusiasts, and other users associated in some way with IT and the crypto space. MacSync’s compromise of software developers’ devices poses particular security risks for both end users and corporate systems, opening up expanded opportunities for attackers to further their intrusion.
Stage one loader 26a0f7cdb9f7dc5ace9a40af825b1538 2d69812584269699fade26622e6490c5 7df1049cbd56c0bfa4a3364a379b4c2c 9f15fe9c4415cd668334339f705b94d8 fb90887592655a8c989e443c640167aa 6791dad263cac6d63ebba6a4b57e7d71
Malicious calendar (stage two) 3ded1d71a822b53b12c3b67bcaf633f5
Stage three dropper 781ce50001d4b449600afa347c9b0208 8e84b01d5ac9624f0b181ade0e737193 980e2134679bc0c609f7659882883d77 4203ec932bfcc0907f91732440d6d997 eb760d5c88f13f7ee0f8f86ba3407123 f9f70096aabb4d22a6657014f4853a53
Stage four dropper 3deeed48fd38f22e369f5c3092bd68a1
Stage five script f97d24212fa6a21be0c4d211e10f044c
Stage six script 00d12d842596bf5ee1805effb4571d30 9a0043d900a9ac78c886c59c9a328fd0
Auxiliary .repair-run script 7212229c85852c3bffaf9740002b2f39
Infostealer c53d0ea45dbc622afb7f16ea3eec78bc
Backdoor fc3ba5ed282d77127efd0b0f2403531b
Auxiliary autorun tool 8dc8561349d144d4661bc66f2ec49f9f
URL hxxps://toria[.]app/ hxxps://warpcast[.]asia/Toria.dmg hxxps://streamyard.appstore.com[.]mx/installer.sh hxxps://slack.apple03cloudstore[.]com/installer.sh hxxps://toria.apple03cloudstore[.]com/ hxxps://waaako.appstore.com[.]mx/installer.sh hxxps://toria.apple03cloudstore[.]com/e3c1a6b00bc31e14/stage2.enc hxxps://docsend.appstore.com[.]mx/dcc737d157ef4271/stage2.enc hxxps://docsend.appstore.com[.]mx/dcc737d157ef4271/CoreUpdate.pkg.enc hxxps://docsend.appstore.com[.]mx/dcc737d157ef4271/Helper.pkg.enc hxxps://caldav.icloud[.]com/published/2/MTk1NDMwMDMzNTUxOTU0M1aHCZ-nMxiyGzBTzPiodOf44DtKJ6PpjftAG28_ui2NCYMpL_vu4pF4ddsJ8ysg0QI7pR0VEIEbZYdilVZRw08 hxxps://gateway.icloud[.]com/caldav/1_MTk1NDMwMDMzNTUxOTU0M0pybtJB186GzhogprwCQUjY3oZNiDFHH8WVo6bmgUtI/attach/4GE4TKNBTGAYDGMZVGUYTSNJUGOAALDAFMDOJBGWNUCYJLZRNDCLCO2YMQ3I64RLGMNXVG3KYBPWQOGYIEI7MPBDDYHECFDYVENTXIYFNDCPOVRMCTYI236RCYZAE63V5U3RTUYGUMO2CO7PKCLWMCXE73M7OPTHSGRWH5DXQ4PCUQU4ELZTLW54JSTK2H7VQ6PD26WOA2R7PPIQ6RTJWDEWP34U3HB4YWMXXC6EJ6PKWILSPYRSDEVY6QGMWSIUN6PR5W35KO3D4QZE7CFPUVBAEKI/Loader.app.tar.gz/YXR0YWNoYXR0YWNoYXR0YRhrE8mQ0E-b_dTUSGStQgTQ0ULFxCanei3Ke-EuEyQL
C2 hxxps://docsend.appstore[.]com[.]mx hxxps://toria.apple03cloudstore[.]com
Malware Technologies
MacSync under the microscope: new delivery methods and a new payload
This site uses Akismet to reduce spam. Learn how your comment data is processed.
GReAT Ideas. Balalaika Edition
GReAT Ideas. Green Tea Edition
GReAT Ideas. Powered by SAS: malware attribution and next-gen IoT honeypots
GReAT Ideas. Powered by SAS: threat actors advance on new fronts
GReAT Ideas. Powered by SAS: threat hunting and new techniques
From the same authors
FakeWallet crypto stealer spreading through iOS apps in the App Store
SparkKitty, SparkCat’s little brother: A new Trojan spy found in the App Store and Google Play
HZ Rat backdoor for macOS attacks users of China’s DingTalk and WeChat
What’s in your notepad? Infected text editors target Chinese users
Cracked software beats gold: new macOS backdoor stealing cryptowallets
In the same category
The Odyssey and Trojans again: MovieReaper attacks users in multiple countries through compromised torrents
Angry Birds: Toy Ghouls’ new toys
ValleyRAT masquerading as adware
The invisible passenger in your car
Project CAV3RN continues: Google Apps Script as C2 relay and DNS-based C2 channel selection
恶意软件描述
加载器、日历和两个简单的滴管
再写几个脚本
妥协的迹象
MacSync 是一个相对年轻且快速发展的加密/信息窃取程序家族。该窃取程序最初于 2025 年以 Mac.c 的名称在暗网上出现,后被其开发者更名为 MacSync。最初的版本以 AppleScript 的形式实现,与 AMOS 窃取程序家族非常相似,但随着时间的推移,MacSync 发展出了自身独特的特性,包括一个后门模块。在本报告中,我们将讨论一种与以往变种显著不同的新型感染链。我们于 2026 年 9 月首次在实际环境中发现了它。
该系列产品的开发者彻底改变了有效载荷投放方式,用二进制投放器取代了基于脚本的投放器。
现在主要的恶意载荷由用 Objective-C 和 Swift 编写的模块组成。
在感染的某个阶段,攻击者利用 iCloud 来传播下一个目标。
卡巴斯基解决方案能够检测到以下所述的威胁,并给出相应的判定结果:
HEUR:Trojan.OSX.MacSync.*
HEUR:Trojan-PSW.OSX.MacSync.*
HEUR:Trojan-Dropper.OSX.MacSync.*
HEUR:Trojan-Downloader.OSX.MacSync.*
MacSync 是一款以恶意软件即服务 (MaaS) 模式分发的窃取信息程序,因此感染链第一阶段的具体传播方式由攻击者自行决定。近期关于 MacSync 的公开报告主要集中在通过社会工程和 ClickFix 式攻击传播的模块上。然而,无论过去还是现在,该恶意软件也伪装成热门应用程序的免费版或破解版,甚至伪装成新软件进行传播。例如,我们发现 MacSync 伪装成一个名为 Toria 的并不存在的加密钱包应用程序;攻击者不仅为其创建了专门的网页,还在 X 和 Telegram 上对其进行推广。
我们发现的最新版信息窃取程序以恶意 DMG 镜像启动感染链。即使在围绕单个虚假应用程序构建的攻击活动中,我们也发现了两种不同的信息窃取程序和后门模块被传播到受害者设备的方式。其中一种方式是,DMG 镜像中的有效载荷是一个编译后的 JXA 脚本,该脚本一旦运行,就会解码一个 shell 脚本并将其直接传递给解释器,而无需写入磁盘。在另一种版本的应用程序中,相同的脚本出现在感染的后期阶段,即一系列投放器和加载器运行之后。我们将详细分析第二种感染链,因为它更为复杂且技术上更有趣。感染方案如下所示:
值得注意的是,MacSync几乎在每个阶段都表现出一些共同特征:
所有临时文件都放置在 /tmp 目录中。*.lock 文件也创建在该目录中,以防止恶意软件再次运行。
任务完成后,该模块会清除其活动痕迹:临时文件、自身日志等等。
所有二进制文件均为 FAT Mach-O 格式,目标设备包括 Apple 和 Intel 处理器。
在这个感染链中,磁盘映像上的有效载荷是一个 .APP 应用程序。启动时,它首先检查整个程序包是否具有 com.apple.quarantine 扩展隔离属性,如果找到,则运行 xattr -cr 命令。<app_name>首先,它执行移除所有属性的命令。接下来,它从覆盖层中提取一个经过 XOR 加密的 URL,并使用密钥 73 6f 6e 6f 6d 61 62 6c 64 07 对其进行解密。加密数据之后是 8 个字节,表示密文的长度,然后是魔数 SONOMAC1。值得注意的是,该恶意软件反向读取覆盖层:它首先找到魔数,然后读取数据大小,最后使用该大小来确定包含密文的数据块的边界。
生成的 URL 是指向下一阶段下载脚本的链接。在某些情况下,该链接直接指向攻击者控制的服务器上托管的文件;但是,至少在一个样本中,该链接指向一个公开的 iCloud 日历:
下载的日历内容
从服务器获取日历文件后,下载器创建一个匿名管道,启动解释器从标准输入读取命令(`zsh -s`),将该管道设置为标准输入,并将日历文件的内容逐行重定向到管道中。由于日历文件通常不是命令,因此解释器会将这些行视为无效命令,直到遇到 `DESCRIPTION:` 行之后的恶意载荷。这些命令最终会从 iCloud 下载一个包含 `.APP` 程序包的 `.TAR.GZ` 归档文件。下载器会移除该程序包的隔离属性,使用临时签名对其进行签名,然后执行它。
我们不知道攻击者服务器分发的脚本内容,但它们很可能与日历事件描述中发现的脚本相同。
下载的应用程序是一个投放器。它提取的恶意载荷是一个使用 zlib 压缩的可执行文件,并使用以下密钥和初始化向量以 CBC 模式的 AES 加密:
投放器对其进行解密和解包,然后将其放置在 /tmp/.sys-<16 位随机值> 处。
内部还有一个投放器,但与之前的阶段不同,这个投放器包含了反调试保护。具体来说,它会使用 kern.hv_vmm_present 和 machdep.cpu.brand_string 参数执行 sysctl 查询,以检查自身是否运行在虚拟机上。它还会使用 ptrace 设置 PT_DENY_ATTACH 标志,以防止调试器附加到该进程。有效载荷是一个使用 AES CBC 模式加密的 shell 脚本,使用的密钥和初始化向量如下:
第二个投放器的有效载荷
如上图所示,第二个投放器会投放一个下载器脚本,该脚本从命令与控制服务器检索下一阶段的有效载荷,使用以下密钥和初始化向量以 CBC 模式的 AES 对其进行解密,然后在内存中执行它:
在检索到的脚本中,我们可以立即发现几个与 MacSync 恶意软件家族相关的熟悉特征:
脚本中的主要函数名为 daemon_function。
被盗数据通过 PUT 请求上传到命令与控制服务器。请求中的数据以 90 兆字节为单位发送。在早期版本中,数据块大小有所不同。
建立对所用系统的持久性的一种方法是将恶意命令注入到 ZSH 解释器的配置文件 .ZSHRC 中,该文件包含每次解释器启动时运行的命令。
后门可执行文件在命令与控制服务器上的 URL 路径以 /loader/ 目录开头。
该脚本执行以下任务:
下载并解密其他恶意模块:信息窃取程序、后门程序以及用于生成加密密钥和解密已下载可执行文件的特殊实用程序
在系统上获得持久性
将从信息窃取模块接收的数据上传到命令与控制服务器
一个细节值得注意:攻击者并没有使用常见的加密算法(例如 XOR、AES 等),而是采用了不同的方法来传递恶意模块。他们使用了一个名为 pkgunpack 的自制工具,该工具实现了两个命令:genkey 和 decrypt。恶意载荷的解密过程如下:
该恶意软件使用 pkgunpack 中的 genkey 命令生成公钥和私钥加密密钥对,其生成功能依赖于 Curve25519 上的椭圆曲线 Diffie-Hellman 协议的开源实现:curve25519_donna。
公钥以 base64 编码,并与由命令 $(date +%s)-${RANDOM}-$$ 生成的一次性代码一起发送到命令与控制服务器。
服务器返回以下 JSON:{ "ok": true, "dek_wrap_b64":<base64_encoded_encrypted_key> , "build_pub_b64": "pFSxn/Uwg9bS45aVKCzA+8exSMfDHXpbpHC/f7G472w=", "crypto": "v2.5" } 1 2 3 4 5 6 { "ok" : true , "dek_wrap_b64" : < base64_encoded_encrypted_key > , "build_pub_b64" : "pFSxn/Uwg9bS45aVKCzA+8exSMfDHXpbpHC/f7G472w=" , "crypto" : "v2.5" } 这里,build_pub_b64 是服务器的公钥,它也在脚本本身中预定义,而 dek_wrap_b64 是包含有效负载加密密钥的 base64 编码字符串。该密钥在服务器端使用由受害者设备上的 pkgunpack 生成的公钥计算出的共享密钥进行加密。
然后,pkgunpack 工具的解密命令会解密密钥:使用与生成密钥时相同的 ECDH Curve25519 密钥交换方案,根据服务器已知的公钥和当前会话的私钥计算共享密钥。将生成的共享密钥与字符串 sn-dek-wrap-v1 连接,并根据结果计算 SHA-256 哈希值。接下来,解码从服务器收到的 dek_wrap_b64 数据块。它的结构如下:前 5 个字节:附加认证数据 (AAD);接下来的 12 个字节:初始化向量 (IV);其余部分:密文。使用先前获得的密钥、IV 和 AAD,以 GCM 模式的 AES 算法解密密文。解码后的 dek_wrap_b64
使用与生成密钥时相同的 ECDH Curve25519 密钥交换方案,根据服务器已知的公钥和当前会话的私钥计算出一个共享密钥。
将得到的共享密钥与字符串 sn-dek-wrap-v1 连接起来,并根据结果计算 SHA-256 哈希值。
接下来,对从服务器接收到的 dek_wrap_b64 数据块进行解码。其结构如下:前 5 个字节:附加认证数据 (AAD);接下来的 12 个字节:初始化向量 (IV);其余部分:密文。
前 5 个字节:附加认证数据 (AAD)
接下来的 12 个字节:初始化向量 (IV)
其余部分:密文
使用先前获得的密钥、初始化向量 (IV) 和自动分配算法 (AAD),在 GCM 模式下使用 AES 算法解密密文。解码后的 dek_wrap_b64
解码 dek_wrap_b64
结果即为解密已下载恶意载荷的密钥。该载荷的头部包含一个 AAD 和一个 IV,并使用 AES GCM 加密。该实用程序解密后终止。
请注意,在每个单独的阶段,该实用程序在使用加密密钥和数据后会将缓冲区清零,这显然是为了阻止取证数据收集和样本的动态分析。
如前所述,在此阶段,脚本仅下载两个模块:一个信息窃取程序和一个后门程序。解密后,这两个模块均为 .TAR.GZ 压缩文件;其内容会被提取,所有扩展属性(例如 com.apple.quarantine)都会被移除,并使用临时签名进行签名。信息窃取程序模块首先运行:它收集所需数据,将其放置在临时文件夹中,并压缩成 .TAR.GZ 压缩文件,然后脚本会将该压缩文件发送到攻击者的服务器。接下来,在启动后门程序之前,脚本会为其设置持久化机制并创建备份副本。备份副本及其运行所需的其他文件会被放置在 $HOME/Library/Application Support/System 目录下。该目录在 macOS 中默认不存在;脚本会创建它。后门程序会将自身伪装成 Finder 应用程序,并通过以下方法实现系统持久化:
一个名为 com.apple.finder.agent 的 LaunchAgent
当 ZSH 解释器从 .ZSHRC 启动时,注入一个命令来运行 .repair-run 脚本。
将类似的命令(该命令也会运行 .repair-run 脚本)注入到全局 GIT pre-commit 和 post-checkout 钩子中。
.repair-run 脚本会检查后门文件是否存在,如果不存在则从备份中恢复,并重新创建和加载 LaunchAgent。同时,它会终止 BTMNotificationAgent、NotificationCenter 和 BackgroundTaskManagementAgent 这三个系统进程,以防止系统通知用户新的 LaunchAgent。
关于此阶段的脚本,最后一点值得注意的是它使用了自定义 HTTP 标头 X-Upload-Token。如果没有此标头,C2 服务器会响应错误请求。在我们的研究中,我们观察到使用了以下令牌:b8b4b88205a8f594b95a841bc37342898f34cad8a5a9e4a22ce69a31a1208650 和 ff3ab9ef841630364818396f62e696b72aed162cf0b895b6643ef25dad79b51d。后门程序随后使用这些相同的令牌与 C2 服务器通信。
信息窃取模块以 .APP 应用程序的形式发布,其主可执行文件用 Swift 编写。与之前的基于 AppleScript 的版本一样,该恶意软件首先会要求用户输入管理员密码。它会调整显示的窗口,使其与它所冒充的应用程序相匹配。输入密码后,用户会看到一个窗口,该窗口模仿系统通知,提示用户某个应用程序已损坏,并询问用户是否可以将其移至废纸篓。
虚假盗窃弹出窗口
有趣的是,攻击者并没有像大多数 macOS 恶意软件家族那样使用 dscl 工具来验证密码,而是使用了可插拔身份验证模块 (PAM) API。这对于 macOS 恶意软件来说是一种相当新的技术,最早于 2026 年 7 月在 Pam Stealer 家族中被发现。这项技术显然引起了恶意软件作者的注意,我们未来可能会看到它被更频繁地使用。
使用 PAM 进行密码验证
窃取程序中的许多字符串(文件名、目录名、团队 ID 等)都经过异或加密,并存储在静态数组中。加密密钥因样本而异,并根据密文长度生成。
与之前的版本相比,窃取程序收集的数据集略有扩展。概括后的数据集如下:
浏览器数据:浏览历史记录、Cookie、加密钱包扩展数据、已保存的登录名和密码以及本地状态文件
加密钱包应用程序数据
设备登录名和密码
系统信息:已安装应用程序和正在运行的进程列表、设备型号、硬件、UUID 等。
SSH、ZSH、AWS、Kubernetes、GIT 和其他服务/程序的配置文件
ZSH 和 Bash 命令历史记录
当前用户头像
收集到的数据保存在 /tmp/ 目录下的隐藏目录中。
窃取模块还有一个有趣的特性,目前所有发现的样本中都已禁用,而且显然仍在开发中。它的作用是检查恶意应用程序的资源中是否包含一个名为 KcHelper 的文件。<app_path> /Contents/Resources/Helpers 目录,如果该文件存在,则使用特定参数启动它。如果该文件不存在,则改为执行备用函数 _kc_grab_storage_item。由于在我们研究时,KcHelper 并不在应用程序的资源中,因此我们只能根据对该函数的分析来推测其用途。它首先运行一个命令,修改特定服务的钥匙串条目的 partition_id,以便三类应用程序无需用户确认和钥匙串密码即可访问该服务:
teamid:应用程序使用具有特定 teamID(在本例中为目标应用程序的开发者)的证书进行签名。
苹果:该应用程序是苹果公司的服务
apple-tool:该应用程序是 Apple 的命令行实用程序。
窃取者随后使用 Security.framework API 尝试自行检索密钥内容,但最终仍会触发操作确认请求。攻击者似乎计划在未来改进此功能,以便在密钥链密码更改后也能畅通无阻地访问密钥,但目前尚未成功,因此该功能已被禁用。在窃取者的加密字符串中,我们看到了用于修改 partition_id 的命令参数示例,这表明攻击者的目标是浏览器密钥。示例:
负责更改对钥匙串服务的访问权限的代码段
该后门程序是一个用 Objective-C 编写的 Fat Mach-O 可执行文件。它有两种启动模式:常规模式和使用 `--persist-status` 标志的模式。在第二种模式下,它仅检查自身是如何添加到持久化对象中的:作为登录项 (Login Item) 还是作为 LaunchAgent。在标准模式下,后门程序在执行其主要功能之前,还会检查自身是否以任何方式添加到自动运行列表中。如果没有,它将使用与父脚本相同的持久化机制。但是,对于 macOS 13.0 之前的版本,无论是否存在自动运行对象,都会使用存储在后门程序主体内的单独的辅助可执行文件。该辅助程序执行一项任务:它使用 CoreServices.framework API 将作为参数传递给它的可执行文件添加到登录项中。
与感染链早期阶段的投放器一样,与 C2 服务器通信的配置信息存储在可执行文件的覆盖网络中,并使用相同的密钥通过异或运算进行加密。它由几个以空字节分隔的字符串组成:
AGNT1:一个魔法常量,用于确认配置已正确解密。
访问令牌:与父脚本中使用的令牌相同。
BLD-150:后门构建编号
该恶意软件还会将日志写入 $HOME/Library/Logs/.sysnotif-agent.log 文件,并在使用 LAUNCHER_DEBUG 环境变量启动时支持扩展日志记录。与 C2 服务器的通信通过 HTTP 协议进行。服务器的响应应为 JSON 文件。
标签:受害者的唯一 ID 与后门构建编号的组合。
构建:后门构建编号
old_token:前一个标记
upload_id:用于标识正在上传的对象,根据时间戳、进程 ID 和一个随机的四字节数字随机生成。
command_status:代理执行的命令的唯一状态
upload_id:上传到服务器的文件的 ID(如果有)
阶段:有关正在执行的命令或其阶段的信息
活动:命令进行中标志(true = 仍在运行;false = 已完成)
尽管该后门提供了多种不同的命令,但它们最终都指向同一个目的:从服务器响应的 script_b64 字段中提取 base64 编码的 AppleScript 脚本并执行它。各个命令处理程序会封装这些脚本,正确地填充遥测数据并向 C2 服务器发送请求。基于命令名称和执行期间发送给服务器的消息,即使没有脚本本身,我们也能推断出它们的用途。该后门支持以下命令:
deploy_ext:将从服务器下载的扩展程序部署到受害者的浏览器中。
deploy_ledger:将已安装的 Ledger 钱包替换为服务器上的版本。
重新抓取:再次收集系统信息和/或特定文件。这次,收集到的数据将被打包成一个典型的 MacSync 系列归档文件,位于 /tmp/osalogging.zip,除非在随命令发送的 archive_path 字段中指定了不同的路径。
live_browser:这是唯一一个无需 AppleScript 脚本即可执行的命令。该后门程序会检查其资源中是否存在 sn_relay 文件,如果找不到,则会下载并执行该文件。其内容和用途目前尚不清楚,但根据命令名称和发送到服务器的消息,我们可以推测攻击者可能对来自受害者浏览器的流量实施了中间人攻击。
regrab 命令中用于验证归档文件的完整性并计算其哈希值的部分,然后再发送该文件。
新版 MacSync 信息窃取程序与其之前发现的变种存在显著差异。攻击者大幅改进了执行窃取程序和后门程序主要恶意载荷的方式,从 AppleScript 转而使用用 Swift 和 Objective-C 编写的完整可执行文件。此外,值得注意的是其更为复杂的感染链:该版本不再使用通过 ClickFix 攻击传播的混淆 shell 脚本,而是使用二进制投放器和加载器,其中一些利用了苹果的基础设施作为传播恶意载荷的中间环节。
攻击者试图从受害者设备中收集的数据性质,以及窃取数据程序伪装成的应用程序类别,都清楚地表明,该恶意软件家族主要针对开发者、加密货币爱好者以及其他与IT和加密货币领域相关的用户。MacSync对软件开发者设备的入侵,对终端用户和企业系统都构成了特殊的安全风险,并为攻击者进一步入侵提供了更多机会。
第一阶段加载器 26a0f7cdb9f7dc5ace9a40af825b1538 2d69812584269699fade26622e6490c5 7df1049cbd56c0bfa4a3364a379b4c2c 9f15fe9c4415cd668334339f705b94d8 fb90887592655a8c989e443c640167aa 6791dad263cac6d63ebba6a4b57e7d71
恶意日历(第二阶段)3ded1d71a822b53b12c3b67bcaf633f5
三级滴管 781ce50001d4b449600afa347c9b0208 8e84b01d5ac9624f0b181ade0e737193 980e2134679bc0c609f7659882883d77 4203ec932bfcc0907f91732440d6d997 eb760d5c88f13f7ee0f8f86ba3407123 f9f70096aabb4d22a6657014f4853a53
第四阶段滴管 3deeed48fd38f22e369f5c3092bd68a1
第五阶段脚本 f97d24212fa6a21be0c4d211e10f044c
第六阶段脚本 00d12d842596bf5ee1805effb4571d30 9a0043d900a9ac78c886c59c9a328fd0
辅助 .repair-run 脚本 7212229c85852c3bffaf9740002b2f39
信息窃取者 c53d0ea45dbc622afb7f16ea3eec78bc
后门 fc3ba5ed282d77127efd0b0f2403531b
辅助自动运行工具 8dc8561349d144d4661bc66f2ec49f9f
URL hxxps://toria[.]app/ hxxps://warpcast[.]asia/Toria.dmg hxxps://streamyard.appstore.com[.]mx/installer.sh hxxps://slack.apple03cloudstore[.]com/installer.sh hxxps://toria.apple03cloudstore[.]com/ hxxps://waaako.appstore.com[.]mx/installer.sh hxxps://toria.apple03cloudstore[.]com/e3c1a6b00bc31e14/stage2.enc hxxps://docsend.appstore.com[.]mx/dcc737d157ef4271/stage2.enc hxxps://docsend.appstore.com[.]mx/dcc737d157ef4271/CoreUpdate.pkg.enc hxxps://docsend.appstore.com[.]mx/dcc737d157ef4271/Helper.pkg.enc hxxps://caldav.icloud[.]com/published/2/MTk1NDMwMDMzNTUxOTU0M1aHCZ-nMxiyGzBTzPiodOf44DtKJ6PpjftAG28_ui2NCYMpL_vu4pF4ddsJ8ysg0QI7pR0VEIEbZYdilVZRw08 hxxps://gateway.icloud[.]com/caldav/1_MTk1NDMwMDMzNTUxOTU0M0pybtJB186GzhogprwCQUjY3oZNiDFHH8WVo6bmgUtI/attach/4GE4TKNBT GAYDGMZVGUYTSNJUGOAALDAFMDOJBGWNUCYJLZRNDCLCO2YMQ3I64RLGMNXVG3KYBPWQOGYIEI7MPBDDYHECFDYVENTXIYFNDCPOVRMCTYI236RCYZAE63V 5U3RTUYGUMO2CO7PKCLWMCXE73M7OPTHSGRWH5DXQ4PCUQU4ELZTLW54JSTK2H7VQ6PD26WOA2R7PPIQ6RTJWDEWP34U3HB4YWMXXC6EJ6PKWILSPYRSDEVY6QGMWSIUN6PR5W35KO3D4QZE7CFPUVBAEKI/Loader.app.tar.gz/YXR0YWNoYXR0YWNoYXR0YRhrE8mQ0E-b_dTUSGStQgTQ0ULFxCanei3Ke-EuEyQL
C2 hxxps://docsend.appstore[.]com[.]mx hxxps://toria.apple03cloudstore[.]com
恶意软件技术
MacSync 深度解析:全新交付方式与全新有效载荷
本网站使用 Akismet 来减少垃圾邮件。了解您的评论数据如何处理。
伟大的想法。巴拉莱卡版
绝妙创意。绿茶版
GReAT Ideas。由 SAS 提供支持:恶意软件归因和下一代物联网蜜罐
GReAT Ideas。由 SAS 提供支持:威胁行为者在新战线上不断扩张
GReAT Ideas。由 SAS 提供支持:威胁狩猎和新技术
出自同一作者之手
FakeWallet 加密货币窃取程序正在通过 App Store 中的 iOS 应用传播
SparkKitty,SparkCat 的弟弟:App Store 和 Google Play 中发现的新型木马间谍软件
HZ Rat 后门程序可攻击 macOS 用户,尤其是中国钉钉和微信用户。
你的记事本里有什么?受感染的文本编辑器正瞄准中国用户。
破解软件胜过黄金:macOS 新后门窃取加密钱包
同一类别
《奥德赛》和特洛伊木马再次出现:MovieReaper 通过被入侵的种子文件攻击多个国家的用户
愤怒的小鸟:玩具总动员的新玩具
ValleyRAT 伪装成广告软件
你车里的隐形乘客
CAV3RN 项目持续推进:Google Apps Script 作为 C2 中继以及基于 DNS 的 C2 信道选择