XCSSET

XCSSET is a modular macOS malware family delivered through infected Xcode projects and executed when the project is compiled. Active since August 2020, it has been observed installing backdoors, spoofed browsers, collecting data, and encrypting user files. It is composed of SHC-compiled shell scripts and run-only AppleScripts, often hiding in apps that mimic system tools (such as Xcode, Mail, or Notes) or use familiar icons (like Launchpad) to avoid detection.[1][2][3]

ID: S0658
Associated Software: OSX.DubRobber
Type: MALWARE
Platforms: macOS
Version: 1.3
Created: 05 October 2021
Last Modified: 04 April 2025

Associated Software Descriptions

Name Description
OSX.DubRobber

[4]

Techniques Used

Domain ID Name Use
Enterprise T1548 .006 Abuse Elevation Control Mechanism: TCC Manipulation

For several modules, XCSSET attempts to access or list the contents of user folders such as Desktop, Downloads, and Documents. If the folder does not exist or access is denied, it enters a loop where it resets the TCC database and retries access.[3]

Enterprise T1087 Account Discovery

XCSSET attempts to discover accounts from various locations such as a user's Evernote, AppleID, Telegram, Skype, and WeChat data.[1]

Enterprise T1098 .004 Account Manipulation: SSH Authorized Keys

XCSSET will create an ssh key if necessary with the ssh-keygen -t rsa -f $HOME/.ssh/id_rsa -P command. XCSSET will upload a private key file to the server to remotely access the host without a password.[1]

Enterprise T1560 Archive Collected Data

XCSSET will compress entire ~/Desktop folders excluding all .git folders, but only if the total data size is under 200MB.[1]

Enterprise T1059 .004 Command and Scripting Interpreter: Unix Shell

XCSSET uses a shell script to execute Mach-o files and osacompile commands such as, osacompile -x -o xcode.app main.applescript.[1]

Enterprise T1554 Compromise Host Software Binary

XCSSET uses a malicious browser application to replace the legitimate browser in order to continuously capture credentials, monitor web traffic, and download additional modules.[1]

Enterprise T1543 .004 Create or Modify System Process: Launch Daemon

XCSSET uses the ssh launchdaemon to elevate privileges, bypass system controls, and enable remote access to the victim.[1]

Enterprise T1486 Data Encrypted for Impact

XCSSET performs AES-CBC encryption on files under ~/Documents, ~/Downloads, and~/Desktop with a fixed key and renames files to give them a .enc extension. Only files with sizes less than 500MB are encrypted.[1]

Enterprise T1005 Data from Local System

XCSSET collects contacts and application data from files in Desktop, Documents, Downloads, Dropbox, and WeChat folders.[1]

Enterprise T1573 .001 Encrypted Channel: Symmetric Cryptography

XCSSET uses RC4 encryption over TCP to communicate with its C2 server.[1]

Enterprise T1546 Event Triggered Execution

XCSSET's dfhsebxzod module searches for .xcodeproj directories within the user’s home folder and subdirectories. For each match, it locates the corresponding project.pbxproj file and embeds an encoded payload into a build rule, target configuration, or project setting. The payload is later executed during the build process.[3][2]

.004 Unix Shell Configuration Modification

Using AppleScript, XCSSET adds it's executable to the user's ~/.zshrc_aliases file ("echo " & payload & " > ~/zshrc_aliases"), it then adds a line to the .zshrc file to source the .zshrc_aliases file ([ -f $HOME/.zshrc_aliases ] && . $HOME/.zshrc_aliases). Each time the user starts a new zsh terminal session, the .zshrc file executes the .zshrc_aliases file.[3]

Enterprise T1041 Exfiltration Over C2 Channel

XCSSET retrieves files that match the pattern defined in the INAME_QUERY variable within the user's home directory, such as *test.txt, and are below a specific size limit. It then archives the files and exfiltrates the data over its C2 channel.[1][3]

Enterprise T1068 Exploitation for Privilege Escalation

XCSSET has used a zero-day exploit in the ssh launchdaemon to elevate privileges and bypass SIP.[1]

Enterprise T1083 File and Directory Discovery

XCSSET has used mdfind to enumerate a list of apps known to grant screen sharing permissions and leverages a module to run the command ls -la ~/Desktop.[5][3]

Enterprise T1222 .002 File and Directory Permissions Modification: Linux and Mac File and Directory Permissions Modification

XCSSET uses the chmod +x command to grant executable permissions to the malicious file.[6]

Enterprise T1564 .001 Hide Artifacts: Hidden Files and Directories

XCSSET uses a hidden folder named .xcassets and .git to embed itself in Xcode.[1]

Enterprise T1574 .006 Hijack Execution Flow: Dynamic Linker Hijacking

XCSSET adds malicious file paths to the DYLD_FRAMEWORK_PATH and DYLD_LIBRARY_PATH environment variables to execute malicious code.[1]

Enterprise T1105 Ingress Tool Transfer

XCSSET downloads browser specific AppleScript modules using a constructed URL with the curl command, https://" & domain & "/agent/scripts/" & moduleName & ".applescript.[1]

Enterprise T1056 .002 Input Capture: GUI Input Capture

XCSSET prompts the user to input credentials using a native macOS dialog box leveraging the system process /Applications/Safari.app/Contents/MacOS/SafariForWebKitDevelopment.[1]

Enterprise T1036 Masquerading

XCSSET installs malicious application bundles that mimic native macOS apps, such as Safari, by using the legitimate app’s icon and customizing the Info.plist to match expected metadata.[1][3]

Enterprise T1027 .013 Obfuscated Files or Information: Encrypted/Encoded File

Older XCSSET variants use xxd to encode modules. Later versions pass an xxd or base64 encoded blob through multiple decoding stages to reconstruct the module name, AppleScript, or shell command. For example, the initial network request uses three layers of hex decoding before executing a curl command in a shell.[3]

Enterprise T1647 Plist File Modification

In older versions, XCSSET uses the plutil command to modify the LSUIElement, DFBundleDisplayName, and CFBundleIdentifier keys in the /Contents/Info.plist file to change how XCSSET is visible on the system. In later versions, XCSSET leverages a third-party notarized dockutil tool to modify the .plist file responsible for presenting applications to the user in the Dock and LaunchPad to point to a malicious application.[1][3]

Enterprise T1113 Screen Capture

XCSSET saves a screen capture of the victim's system with a numbered filename and .jpg extension. Screen captures are taken at specified intervals based on the system. [1]

Enterprise T1518 Software Discovery

XCSSET uses ps aux with the grep command to enumerate common browsers and system processes potentially impacting XCSSET's exfiltration capabilities.[1]

.001 Security Software Discovery

XCSSET searches firewall configuration files located in /Library/Preferences/ and uses csrutil status to determine if System Integrity Protection is enabled.[1]

Enterprise T1539 Steal Web Session Cookie

XCSSET uses scp to access the ~/Library/Cookies/Cookies.binarycookies file.[1]

Enterprise T1553 .001 Subvert Trust Controls: Gatekeeper Bypass

XCSSET has dropped a malicious applet into an app's .../Contents/MacOS/ folder of a previously launched app to bypass Gatekeeper's security checks on first launch apps (prior to macOS 13).[5]

Enterprise T1195 .001 Supply Chain Compromise: Compromise Software Dependencies and Development Tools

XCSSET adds malicious code to a host's Xcode projects by enumerating CocoaPods target_integrator.rb files under the /Library/Ruby/Gems folder or enumerates all .xcodeproj folders under a given directory. XCSSET then downloads a script and Mach-O file into the Xcode project folder.[1]

Enterprise T1082 System Information Discovery

XCSSET identifies the macOS version and uses ioreg to determine serial number.[1]

Enterprise T1614 .001 System Location Discovery: System Language Discovery

XCSSET uses AppleScript to check the host's language and location with the command user locale of (get system info).[1]

Enterprise T1569 .001 System Services: Launchctl

XCSSET loads a system level launchdaemon using the launchctl load -w command from /System/Librarby/LaunchDaemons/ssh.plist.[1]

Enterprise T1497 .003 Virtualization/Sandbox Evasion: Time Based Evasion

Using the machine's local time, XCSSET waits 43200 seconds (12 hours) from the initial creation timestamp of a specific file, .report. After the elapsed time, XCSSET executes additional modules.[1]

References