This is some text inside of a div block.
Glitch effect

LightSpy Malware Variant Targeting macOS


Download Your

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Glitch effectGlitch effectGlitch effectGlitch effectGlitch effect

LightSpy Malware Variant Targeting macOS

Glitch effectGlitch effectGlitch effect
Glitch banner

On April 11, 2024, BlackBerry released a new blog detailing a new VirusTotal upload of the LightSpy mobile spyware framework. BlackBerry stated that this malware was an iOS implant, yet Huntress researchers discovered that, although the uploaded samples appear novel, they aren’t actually targeting iOS at all. Instead, what was observed is a macOS variant of the LightSpy malware, which hasn’t been previously reported. This new capability demonstrates that in addition to the iOS and Android, macOS users could’ve been targeted.

Based on BlackBerry’s report, several large publications including Forbes, HackerNews, and Mashable, reported that the sample uploaded is an active and dangerous iOS threat. This is incorrect, as the sample BlackBerry analyzed will only run on Intel macOS devices, or Apple Silicon devices with Rosetta 2 enabled.

The publications also stated that this was a likely catalyst for Apple sending out “spyware attack alerts.” We’ve assessed that, due to Apple’s most recent support article, About Apple threat notifications and protecting against mercenary spyware, Apple is referring to the more recent and sophisticated Pegasus spyware from NSO Group. 

It’s also important to note that while we were able to find the Android version of this malware on the same C2 as the macOS version, it doesn't appear the iOS version is also present. In this article, we'll only be focusing on the macOS implant. For more information of the Android version (also known as WyrmSpy), please see this report by the ThreatFabric team.

In addition to our analysis, we’re providing YARA and Sigma rules which can be used freely to detect potential usage of the macOS LightSpy variant. The text in all images or terminal screenshots are also available in the GitHub repository.

Thanks to researchers at TrendMicro, Kaspersky, and ThreatFabric for their prior work on the LightSpy framework, their contributions were incredibly helpful in our research.

Technical Analysis

Confirming macOS Targeting

While there is a variant of LightSpy that affects Apple’s mobile devices like iPhone, this sample notably only targets the macOS platform. There are a number of factors which support this, but the largest is that these binaries are all compiled for the x86_64 architecture, ruling out iPhones based on the ARM architecture. This can be confirmed by running the [.highlight]file[.highlight] command against the macOS and iOS samples.

Figure 1: File types of macOS and iOS Macho binaries

In both cases, the structure of the implant is the same. A dropper, which loads a series of dynamically loaded modules (dylibs), similar to DLLs on Windows, that contain most of the malicious capabilities.

Differences from iOS Version

What made LightSpy famous was an iOS version discovered in 2020, covered by both Kaspersky and TrendMicro. While there are a large number of similarities between the two, there are a few interesting differences that provide some new insight into the organization behind the framework as well as their targeting.

Generally, the macOS version seems to be more refined than the iOS version. The operational security (opsec) is significantly improved, the development practices seem more mature, and things are generally more organized. A quick example is that iOS version stores its C2 information in plain text:

Figure 2: iOS LightSpy Downloading Plugins

The macOS version solves this problem by using a plugin manifest, which provides more flexibility for updating plugins down the road in addition to lower static detections. Despite the various improvements, LightSpy still leaves plenty on the table when it comes to anti-analysis.

All of the binaries for both macOS and iOS contain plenty of developer artifacts. Looking specifically for file paths, we can extract a decent picture of how this malware was organized. 

There are two hosts that seem to have been involved in development of LightSpy: [.highlight]mac[.highlight] and [.highlight]air[.highlight]. Obviously, there's no way to confirm that there weren’t multiple development hosts with the same username, but this still helps in understanding the organization of the framework.

Stage 1: Dropper

The first stage of this malware is a dropper (SHA256: [.highlight]afd03337d1500d6af9bc447bd900df26786ea4a4[.highlight]) which downloads and runs the core implant dylib. 

Checking PID File:
The macOS version of this malware makes use of a process identification number (PID) file located at [.highlight]/Users/Shared/[.highlight] to verify that the implant isn’t already running. A PID file is just a file containing the PID of a running process—it’s used to verify a specific running process in order to reference it at a later time.

Configuration Extraction:
The configuration for this malware is appended to the end of the binary (in this case the last [.highlight]0x1d0[.highlight] bytes) and is encrypted with AES with a static key of [.highlight]3e2717e8b3873b29[.highlight]

Download Stage 2 and Plugins:
Before downloading the plugins from the C2 server, the dropper requests [.highlight]macmanifest.json[.highlight] which contains lots of information about the plugins. The MD5s correspond to the encrypted versions.

Figure 3: manifest.json file

Payload Verification:
After downloading the core dylib responsible, another call is made to the following address:

Which returns a JSON blob used to verify the integrity of the second stage. The other interesting aspect to note is the date, which shows this being at least three years old. This timeframe lines up with the original discovery of the LightSpy malware in 2020.

Payload Decryption:
The plugins and core dylib are encrypted with a rolling-type XOR located in the [.highlight]_XorDecodeFile[.highlight] function.

Figure 4: Screenshot of decryption function decompilation

Luckily, reimplementing the routine is quite simple and allows for easy analysis of the downloaded plugins.

Stage 2: Implant

The second stage (SHA256: [.highlight]0f66a4daba647486d2c9d838592cba298df2dbf38f2008b6571af8a562bc306c[.highlight]) is responsible for loading, maintaining, and using the plugins. During this stage, the implant queries the device for system information using the [.highlight]DeviceInformation[.highlight] class. It collects a standard set of device information:

Figure 5: Diff of DeviceInformation function, iOS on left and macOS on right

When you diff the methods within that class, the macOS version doesn't collect information that would be found on a phone such as the International Mobile Subscriber Identity (IMSI) or International Mobile Equipment Identity (IMEI) numbers. Additionally, when analyzing functions like [.highlight]getScreenSizeInches[.highlight], the iOS version will return dimensions of iOS devices, whereas the macOS version only returns a single string, [.highlight]13.3 inches[.highlight].

Figure 6: macOS version of getScreenSizeInches
Figure 7: iOS version of getScreenSizeInches

Communication with the C2 is still performed over WebSockets using the open source library SocketRocket with all the standard functionality you’d expect: sending heartbeats, receiving commands, updating command status, etc.

Stage 3: Plugins

This particular implant downloads 10 additional payloads, each to accomplish a particular task. Since they’ve been covered pretty extensively, we noted below, in the IOCs, the different plugins (dylibs) that are associated with the macOS variant.

iOS Implant[2] macOS Implant
AudioRecorder (Plugin ID: 18000)
Browser (Plugin ID: 14000) BrowserHistory (Plugin ID: 14000)
CameraShot (Plugin ID: 19000)
FileManage (Plugin ID: 15000) FileManage (Plugin ID: 15000)
KeyChain (Plugin ID: 31000) KeyChains (Plugin ID: 31000)
LanDevices (Plugin ID: 33000)
ProcessAndApp (Plugin ID: 16000)
ScreenRecorder (Plugin ID: 34000)
ShellCommandaaa (Plugin ID: 20000) ShellCommand (Plugin ID: 20000)
WifiList (Plugin ID: 17000) WifiList (Plugin ID: 17000)
BasicInfo (Plugin ID: 11000)
SoftInfoaaa (Plugin ID: 16000)
Screenaaa (Plugin ID: 33000)
Locationaaa (Plugin ID: 13000)
iOS WeChat (Plugin ID: 12000)
iOS QQ (Plugin ID: 25000)
iOS Telegram (Plugin ID: 26000)


Even though we’ve historically seen LightSpy target iOS, this variant very clearly is targeting macOS. As the macOS landscape constantly evolves, and attacks that specifically target the Apple ecosystem become more prevalent, we wanted to include some detection opportunities here as well.

It's also worth noting that while this sample was uploaded to VirusTotal recently from India, this isn't a particularly strong indicator of an active campaign, nor targeting within the region. It's a contributing factor, but without more concrete evidence or visibility into delivery mechanisms, it should be taken with a heavy grain of salt. 

While we haven’t made any attribution claims in this post, most prior research has associated this malware to APT 41. We're confident that this sample is indeed part of the LightSpy framework, and have no reason to disagree with that attribution.

Apple, in an attempt to thwart threat actors, has introduced new features to their *OS such as Lockdown Mode, additional TCC restrictions, and constantly evolving XProtect/XProtectRemediator modules designed to protect the end user. It's also a great opportunity to remember to keep devices updated, regardless of platform.

Appendix A

We created YARA rules that will detect the implant, loader, and the dylibs. We included a private rule that will assist in paring down detections to only Macho binaries. It's important to note that without that private rule, the rules will not run, as they all check for a Macho in their condition. The rules are available below and on GitHub.

YARA Rules

Sigma Rule

Appendix B


Filename SHA1 Description
loader afd03337d1500d6af9bc447bd900df26786ea4a4
C40F0D27 fd49866245721acc6e7431ec61b066696b72a1e1 core implant
soundrecord 0563225dcc2767357748d9f1f6ac2db9825d3cf9 Plugin ID: 18000
browser 476c726b58409a8e3e6cf8fb6bb7d46596917e24 Plugin ID: 14000
cameramodule 33c39728a0393d4271f27cc1d85cf3c1610be333 Plugin ID: 19000
FileManage 9a00f6ca0d9140316f9ae03f79c7511cec32849f Plugin ID: 15000
keychain 8f390335b571297a9eb605576745876666ee7f6a Plugin ID: 31000
LanDevices 7aceb8db03b8b8c7899982b5befcaf455a86fe0b Plugin ID: 33000
softlist c65817a55b003462d48189875f18fa8bdb57b402 Plugin ID: 16000
ScreenRecorder e9ba5d2dd449678628834cf5a11cffe042a4f6d6 Plugin ID: 34000
ShellCommand 30e33f1188ca4cffc997260c9929738594e7488c Plugin ID: 20000
wifi 8e7e8d896ed61bea7a49271e2e6ffc982942e5c7 Plugin ID: 17000


IP Description
103[.]27[.]109[.]217 Primary C2






Blurry glitch effect

Sign Up for Blog Updates

Subscribe today and you’ll be the first to know when new content hits the blog.

Huntress at work