Skip to content
September 2025

September 2025

www.microsoft.com September 9, 2026

Microsoft Threat Intelligence has identified yet another XCSSET variant in the wild that introduces further updates and new modules beyond those detailed in our March 2025 blog post . The XCSSET malware is designed to infect Xcode projects, typically used by software developers, and run while an Xcode project is being built. We assess that this mode of infection and propagation banks on project files being shared among developers building Apple or macOS-related applications.

This new variant of XCSSET brings key changes related to browser targeting, clipboard hijacking, and persistence mechanisms. It employs sophisticated encryption and obfuscation techniques, uses run-only compiled AppleScripts for stealthy execution, and expands its data exfiltration capabilities to include Firefox browser data. It also adds another persistence mechanism through LaunchDaemon entries.

This variant features a submodule designed to monitor the clipboard and references a downloaded configuration file containing address regex patterns associated with various digital wallets. If a pattern match is detected, XCSSET is capable of substituting the clipboard content with its own predefined set of wallet addresses.

In this blog, we will the new modules added to the XCSSET’s inventory and key changes to existing ones. While we’re only seeing this new XCSSET variant in limited attacks as of this writing, we’re publishing our comprehensive analysis to increase awareness of this evolving threat. We shared these findings with Apple and collaborated with GitHub to take down repositories affected by XCSSET. This work reflects our broader commitment to disrupting attacks and dismantling attacker operations. Alongside our findings, we are sharing actionable detections, recommendations, and best practices to help organizations defend against this threat with confidence.

The latest XCSSET variant follows a four-stage infection chain. The initial three stages are consistent with those observed in variants, as described in our blog . This analysis begins with the fourth stage, which includes the boot() function and its associated calls to download and run submodules.

boot() function of the fourth-stage script

The new variant introduces modifications to the boot function. These include additional checks for Firefox browser and modified logic for Telegram existence check. This stage also has multiple new modules that it downloads and executes.

In the following sections, we examine changes to existing submodules as well as additional modules in this variant.

vexyeqj [Older variant: seizecj] (Info-stealer)

In comparison to the variant, several commands in this script are commented out. Additionally, it downloads a module called bnk , which is executed using osascript, with the domain supplied as a parameter. It then waits for three seconds and deletes the downloaded file.

The bnk file is a run-only compiled AppleScript. Direct decompilation of run-only compiled AppleScript is generally considered challenging or not feasible; however, the AppleScript disassembler project on Github can be used to disassemble the code for analysis.

The script defines several functions for purposes such as data validation, encryption, decryption, obtaining additional data from command and control (C2), and logging. The script is executed with the domain as its parameter.

Above is a code snippet of the dec() function, which is used to decrypt the data received from C2 server. Parsing the above leads to the command:

In the referenced code, the encrypted data is stored in the variable in . The first 32 characters of this variable are extracted to serve as the initialization vector (IV). The remaining data is then Base64-decoded and provided to the AES decryption function. In this case, the decryption key is a predefined constant, 27860c1670a8d2f3de7bbc74cd754121 , which was established and computed within the main function.

The decoded blob appears to be a configuration file. Presented below is a formatted and redacted sample of the decrypted response obtained from the C2 server:

The following section examines the core logic of the downloaded bnk payload, explaining how the information is interpreted and applied.

Firstly, it calls a defined function to obtain the configuration data from the C2 server; this data is decrypted and stored in a variable. Shell commands are executed to retrieve the SerialNumber and the current user.

The clipboard content is retrieved which was determined by checking the AEVT (Apple Event Code) codes. The process then identifies the frontmost application, which is checked against a blocklist defined by the “bad” property in the response from C2. Processing proceeds only if the current clipboard data differs from both the last clipboard entry and the last replaced clipboard data, the length of the clipboard data exceeds 25 characters, and the oD() function does not return true. The oD() function returns true when the first four characters are digits. After the above checks, it then has multiple gates and conditions. The first condition checks if the clipboard length is between 50 < len(clipboard) < 300. It then checks if the clipboard matches the pattern defined in the s record in the response. If it matches, the clipboard data is formatted in a record type string and is exfiltrated to the C2 server. The transmitted data is also AES-encrypted.

In the second condition, the script verifies whether the clipboard length is between 25 and 65, whether it was executed with a single argument, and whether cD(clipboard_data) function returns a value greater than 1, which refers to the count of digits in the data passed in argument. If these conditions are met, the script iterates through the sub collection in the C2 response, which includes individual entries for various wallets. Each sub collection entry contains:

a : Contains a list of addresses from which one is selected; the corresponding clipboard data is subsequently replaced.

t : Refers to the wallet identifier.

r : Specifies the regex pattern used for matching addresses associated with this wallet.

ir (optional): Represents a negative regex pattern; addresses matching this pattern should be excluded.

p : Appears to function as a counter or record index.

For each record, it matches pattern for r and ir . If the variable r is true and ir is false, then the program checks whether the clipboard content matches any of the attacker’s addresses. If it does not, it selects an address from the list and replaces the clipboard’s content accordingly. The system subsequently sends information—including the original clipboard data, the replaced data, the wallet name, frontmost application, and other relevant details—to the C2 server. , it assigns the value of the clipboard data to the xcP variable, which tracks the most recently replaced clipboard entry. Finally, it updates the xP variable to reflect the current clipboard text, waits for two seconds, and repeats the loop.

neq_cdyd_ilvcmwx (File-stealer)

This module retrieves an additional script from the C2 server, which is saved in the /tmp/ directory. The script is subsequently executed with the domain and moduleName provided as parameters. After execution, the downloaded file is deleted. The module operates as a compiled, run-only AppleScript. The script bears similarity to the txzx_vostfdi module, previously identified as a digital wallet data stealer targeting browsers. During analysis, the C2 server did not supply a folder list; however, it is capable of exfiltrating files back to the C2 server.

xmyyeqjx ( LaunchDaemon -based persistence)

This submodule sets up LaunchDaemon persistence for the ~/.root file, which is created in this module. Here’s a summary of the script:

The process begins by creating several paths and a ~/.root file in the user’s directory, which will contain the payload. The payload performs the following actions:

Changes the directory to /Users/Shared

Checks the network connection

Retrieves the local signed-in user

Sleeps for 30 seconds

Executes the ~/.zshrc file in the context of the signed-in user ( .zshrc file was appended with malicious payload in submodules)

Sleeps for 30 seconds

Modifies two configurations to execute system commands that disable macOS automatic configuration updates and Rapid Security Response mechanisms.

These commands modify macOS Software Update preferences to disable various critical Apple Updates, including Rapid Security Responses (RSR), Security Configuration updates, and others.

It then calls the doMainFunc() function.

This function first checks the existence of a LaunchDaemon entry with the presence of .root file in its contents. If it’s not found, it downloads another script from the C2 server, which is again a run-only compiled AppleScript. It then creates a fake application named S ystem Settings.app in the /tmp directory, which basically executes this downloaded AppleScript with two parameters. These parameters appear to be the Label/Plist Name and the file to be persisted ( ~/.root file). After creating the fake app, it calls another function where it waits for the legitimate System Settings application to get started, upon which it executes the fake application. This behavior is done to masquerade itself as legitimate.

The downloaded script first gets the device’s serial number and the current username by executing shell commands. It then forms path to the LaunchDaemon plist file and constructs its content. It uses the echo command to paste this constructed content to the LaunchDaemon file. The file name is the name that was passed in the argument. Below is an example of the created plist file:

It masquerades with prefix com.google . in plist name and executes the ~/.root file using bash. The echo command is run using “do shell script …. with administrator privileges” which can be implied by the badm AEVT code. It then executes chown command to change owner to root:wheel and sets 644 permissions to the plist file. Lastly, it executes the launchctl load -w command with sudo to start the daemon.

jey [Older Variant: jez] (Git-based persistence)

The command in the older variant executes a direct concatenation of encrypted payload along with the repeated decryption command directly through the shell. In the new variant, the decryption logic is encapsulated within a shell function, which is defined inline and then used to decrypt the encrypted string before passing it to the shell for execution. This change primarily enhances the obfuscation method used by malware.

iewmilh_cdyd (Info-stealer targeting Firefox)

This new variant has added an info-stealer module to exfiltrate data stored by Firefox. The runMe() function is invoked at first to download a Mach-O FAT binary, which is responsible for all info stealing operations, from the C2 server.

This downloaded binary appears to be a modified version of a GitHub project HackBrowserData , which is capable of decrypting and exporting browser data stored by browsers. Passwords, history, credit card information, and cookies are some of the key information it can extract from almost all popular browsers.

Upon downloading, the binary is given executable file permissions, is ad-hoc signed on the victim’s machine, and executed with – b firefox -f json –dir ” & resDir & ” –zip as arguments:

-f : format of the output data

–dir : Export directory where the output is stored

–zip : This flag stores the output in compressed ZIP

Once all the data is retrieved, it uploads the compressed ZIP and log file to C2 server with its old method of exfiltrating data in chunks.

Mitigation and protection guidance

Defenders can take the following mitigation steps to defend against this threat:

Run the latest version of your operating systems and applications. Deploy the latest security updates as soon as they become available.

Always inspect and verify Xcode projects downloaded or cloned from repositories, as the malware usually spreads through infected projects.

Exercise caution when copying and pasting sensitive data from the clipboard. Always verify that the pasted content matches the intended source to avoid falling victim to clipboard hijacking or data tampering attacks.

Encourage users to use web browsers that support Microsoft Defender SmartScreen like Microsoft Edge —available on macOS and various platforms—which identifies and blocks malicious websites, including phishing sites, scam sites, and sites that contain exploits and host malware.

Use Microsoft Defender for Endpoint on Mac , which detects, stops, and quarantines the malware discussed in this blog

Microsoft Defender for Endpoint customers can also apply the following mitigations to reduce the environmental attack surface and mitigate the impact of this threat and its payloads:

Turn on cloud-delivered protection and automatic sample submission on Microsoft Defender Antivirus. These capabilities use artificial intelligence and machine learning to quickly identify and stop new and unknown threats.

Enable potentially unwanted application (PUA) protectio n in block mode to automatically quarantine PUAs like adware. PUA blocking takes effect on endpoint clients after the signature update or computer restart. PUA blocking takes effect on endpoint clients after the signature update or computer restart.

Turn on network protection to block connections to malicious domains and IP addresses.

Microsoft Defender XDR detections

Microsoft Defender XDR customers can refer to the list of applicable detections below. Microsoft Defender XDR coordinates detection, prevention, investigation, and response across endpoints, identities, email, apps to provide integrated protection against attacks like the threat discussed in this blog.

Note: For detections associated with older variants of XCSSET, refer to our March 2025 blog post .

Threat intelligence reports

Microsoft customers can use the following reports in Microsoft products to get the most up-to-date information the threat actor, malicious activity, and techniques discussed in this blog. These reports provide the intelligence, protection information, and recommended actions to prevent, mitigate, or respond to associated threats found in customer environments.

Microsoft Defender XDR threat analytics

Microsoft Defender XDR

Microsoft Defender XDR customers can run the following query to find related activity in their networks:

Suspicious commands while building an Xcode project

for suspicious commands related to this XCSSET when an Xcode project is being built.

Suspicious commands executed by XCSSET info-stealer module

for suspicious commands related to decryption logic of data received from C2.

Suspicious application creation

for suspicious applications created in Temp folder by this XCSSET.

Microsoft Sentinel customers can use the TI Mapping analytics (a series of analytics all prefixed with ‘TI map’) to automatically match the malicious domain indicators mentioned in this blog post with data in their workspace. If the TI Map analytics are not currently deployed, customers can install the Threat Intelligence solution from the Microsoft Sentinel Content Hub to have the analytics rule deployed in their Sentinel workspace.

Below are the queries using Sentinel Advanced Security Information Model (ASIM) functions to hunt threats across both Microsoft first-party and third-party data sources. ASIM also supports deploying parsers to specific workspaces from GitHub , using an ARM template or manually.

Detect network IP and domain indicators of compromise using ASIM

The following query checks IP addresses and domain IOCs across data sources supported by ASIM network session parser:

Detect domain and URL indicators of compromise using ASIM

The following query checks domain and URL IOCs across data sources supported by ASIM web session parser.

For the latest security research from the Microsoft Threat Intelligence community, check out the Microsoft Threat Intelligence Blog .

To hear stories and insights from the Microsoft Threat Intelligence community the ever-evolving threat landscape, listen to the Microsoft Threat Intelligence podcast .

September 4 6 min read How to secure edge AI in customer-owned environments As AI moves into customer-owned environments, organizations need new ways to verify the systems, software, and AI assets they trust before releasing sensitive data, credentials, and models.

How to secure edge AI in customer-owned environments

September 2 16 min read Impersonating IT support: how threat actors turn a remote session into enterprise-wide access Microsoft Threat Intelligence observed a human-operated intrusion campaign that abuses Microsoft Teams external collaboration to impersonate IT support, gain remote access, and deploy a Node.

Impersonating IT support: how threat actors turn a remote session into enterprise-wide access