macOS NotLockBit | Evolving Ransomware Samples Suggest a Threat Actor Sharpening Its Tools

Last week, researchers at Trend Micro published a report on a macOS malware sample that had credible file locking and data exfiltration capabilities and masqueraded as LockBit ransomware on successful encryption of a user’s files. Until now, ransomware threats for Mac computers had been at best ‘proof of concept’ and at worst entirely incapable of succeeding at their apparent aim. Interestingly, despite one of the more credible previous attempts being from LockBit itself, this latest discovery appears to be an entirely different threat actor appropriating the name of a more notorious one. Since earlier researchers did not give a specific threat name for the sample they reported, we have dubbed the malware ‘macOS.NotLockBit’.

SentinelOne has discovered a set of related Mach-O samples in addition to the one reported on by previous researchers. In this post, we provide indicators of compromise for this set of samples and discuss how they have changed across versions.

All known samples of macOS.NotLockBit are blocked by SentinelOne Singularity.

Overview of macOS.NotLockBit

The technical details have been described by researchers at Trend Micro, so we will simply summarize the main points here for context. As previously reported, the ransomware is written in Go and is distributed as an x86_64 binary, meaning it will only run on Intel Macs or Apple silicon Macs with the Rosetta emulation software installed.

On execution, the ransomware gathers system information from the host. On Mac targets, it is able to read the property list file at /System/Library/CoreServices/SystemVersion.plist to gather the product name, version and build and to query sysctl hw.machine to gather the architecture and sysctl kern.boottime for the time since last boot. This functionality is provided via Host in Elastic’s Go sysinfo module.

A search across the binary for Magic headers reveals an embedded public key. This allows for the possibility of asymmetric encryption, making decryption impossible without access to the private key held by the attacker.

NotLockBit embedded public key
NotLockBit’s embedded public key

The malware uses this embedded public key to encrypt a randomly generated master key. This in turn is used in the subsequent file encryption process and written to a README.txt file deposited in each folder containing encrypted files, recognizable by their .abcd file extension.

The README.txt is dropped in each folder with encrypted files
The README.txt is dropped in each folder with encrypted files

Once the encryption process is complete, the malware attempts to use osascript to change the Desktop wallpaper and display a LockBit 2.0 banner.

LockBit's wallpaper is co-opted by NotLockBit
LockBit’s wallpaper is co-opted by NotLockBit

As pointed out by other researchers, LockBit v2.0 has been superseded by version 3.0 for some time now and key actors behind its development have been arrested, meaning that whoever is responsible for developing this malware is, with high probability, not LockBit.

In the first version of the ransomware, (Sample_1, described below), the wallpaper functionality is missing, but it is included in all subsequent versions via the sym._mkgo_lock_wallp.SetWp function.

NotLockBit sets the wallpaper using System Events.app via a call to osascript
NotLockBit sets the wallpaper using System Events.app via a call to osascript

Prior to the file locking operation, the malware attempts to exfiltrate the user’s data to a remote server. The threat actor abuses AWS S3 cloud storage for this purpose using credentials hardcoded into the binary. The malware creates new repositories (‘buckets’) on the attacker’s Amazon S3 instance (now defunct).

Trend Micro did not describe how or where they discovered the Mach-O sample they reported, and at present there is no known distribution method for NotLockBit. We did discover both the single Mach-O sample mentioned by Trend’s researchers and several more from our own research on VirusTotal, and our findings below are based on these newly-discovered samples.

Testing and Evolution of macOS Ransomware Samples

We discovered five Mach-O samples, including the one mentioned by previous researchers, which indicate the malware’s development over a short period of time. The samples can be split into three groups.

SHA1 Name Size First Seen
367362b4ab6384833752b6936c296f3746859b82 Sample_1 3MB 03-Jan
23f3b070aad47f72ddf2d148f455cce2266901fd Sample_2a 8.8MB 15-Jan
2e8cadad5ab90651ae36fb09fb386ffd91bd0d41 Sample_2b 8.8MB 15-Jan
6c19a41d033ccc39bd42bc2f2e830e1f5808ca15 Sample_3a 9.3MB 24-May
c9611cba90349e78b6051c299dc8d012048a91a4 Sample_3b 9.3MB 24-May

Sample_1 appeared on VirusTotal on 3rd January, some 12 days before the next pair of samples and 5MB lighter, weighing in at 3MB rather than 8.8MB. It is linked to the CoreFoundation and Security frameworks and the System.B dylib. It uses the latter for various file and symbolic link manipulation operations including opening, closing, reading, writing, and unlinking. The minimum OS for Sample_1 is macOS Ventura and the binary was developed with the Ventura 13.3 SDK. The executable has no code signature and, as with all the other samples seen to date, is x86_64 only.

This sample does not contain any of the code for exfiltrating the data, strings related to AWS nor the code for setting the wallpaper as seen in later samples. Sample_1 seems likely to be a test of the code’s ability to perform its encryption tasks and to see how that code fared against VirusTotal’s public AV detection engines.

Attacker symbols and functions in the Sample_1
Attacker symbols and functions in the Sample_1

Sample_2a (analysed by previous researchers) and Sample_2b are each 8.8MB in size, fully functional and functionally identical. Like the earlier sample, they are built against the Ventura SDK and require macOS 13 as the minimum OS version. They were both uploaded to VirusTotal on 15th January, a few minutes apart. However, Sample_2b, while not stripped of symbolic information, shows some attempt to obfuscate some function names which appear unobfuscated in Sample_2a. This suggests that the developers may have been further testing static detection and anti-analysis techniques.

Sample_2a is fully functional and unobfuscated
Sample_2a is fully functional and unobfuscated
Sample_2b shows some attempt at obfuscating function names
Sample_2b shows some attempt at obfuscating function names

Both samples leave a slew of interesting functions unobfuscated that analysts and detection engineers may wish to peruse.

sym._mkgo_lock_del.Plmxowkqg
sym._mkgo_lock_filemanager.InitWithCredentials
sym._mkgo_lock_filemanager.InitWithCredentials.WithCredentialsProvider.func6
sym._mkgo_lock_filemanager.InitWithCredentials.WithRegion.func5
sym._mkgo_lock_filemanager._Uploader_.CreateBucket
sym._mkgo_lock_filemanager._Uploader_.UploadFile
sym._mkgo_lock_filemanager._Uploader_.UploadFile.Printf.func2
sym._mkgo_lock_filemanager._Uploader_.UploadFile.func3
sym._mkgo_lock_filemanager.InitWithCredentials.func1
sym._mkgo_lock_filemanager.InitWithCredentials.func2
sym._mkgo_lock_filemanager.InitWithCredentials.func3
sym._mkgo_lock_filemanager.InitWithCredentials.func4
sym._mkgo_lock_filemanager._Uploader_.UploadFile.func1
sym._mkgo_lock_sysinfo._C2func_gethostuuid.abi0
sym._mkgo_lock_sysinfo._C2func_uuid_unparse_upper.abi0
sym._mkgo_lock_sysinfo.getHostUUID
sym._mkgo_lock_wallp.SetWp
sym._mkgo_lock_sysinfo._cgo_412d459cdd96_C2func_gethostuuid
sym._mkgo_lock_sysinfo._cgo_412d459cdd96_C2func_uuid_unparse_upper

The third set of samples appeared on VirusTotal a little under five months later and a little less  than two hours apart on 24th May, 2024. Weighing in at 9.3MB, Sample_3a and Sample_3b are entirely stripped of symbolic information. However, a variety of useful artifacts remain for threat hunters and those restricted to static detection signatures.

Stripped function at 0x1003e80e0 in Sample_3a reveals malicious intent
Stripped function at 0x1003e80e0 in Sample_3a reveals malicious intent

This includes strings related to both AWS accounts and to manipulating System Events to set the wallpaper. Unlike the earlier samples, these now require macOS Sonoma as the minimum OS and are built against the macOS 14.4 SDK.

In all versions of this malware, the attacker’s are hindered somewhat by Apple’s TCC protections. Multiple alerts require consent as the malware attempts to traverse certain directories and control processes such as System Events. Given that bypassing TCC is reasonably trivial, we would expect to see development in this area in future versions.

SentinelOne Detects macOS.NotLockBit

SentinelOne customers are protected from all known variants of macOS.NotLockBit through a multi-engine platform that combines static and dynamic AI, ensuring that the latest threats are stopped pre-execution and on-execution.

Conclusion

Ransomware on macOS remains a small and still unlikely threat, but it is apparent that threat actors have understood that the double extortion method that works so well on other platforms—essentially, infostealers combining with file lockers—is equally viable on Apple’s desktop platform. Regardless of whether the file encryption succeeds or not, or whether users have adequate backups, bad actors seek to profit from stolen victim data.

The NotLockBit malware appears to be very much in development. For now, the threat actor’s AWS accounts have been removed and there are no known victims or distribution methods in the wild. Given the amount of development that has gone into this threat so far, we would be surprised not to see more from this actor in the short to medium term.

Indicators of Compromise

Files SHA1 | Mach-O x86_64
23f3b070aad47f72ddf2d148f455cce2266901fd
2e8cadad5ab90651ae36fb09fb386ffd91bd0d41
367362b4ab6384833752b6936c296f3746859b82
6c19a41d033ccc39bd42bc2f2e830e1f5808ca15
c9611cba90349e78b6051c299dc8d012048a91a4