Recently, a Firefox 0day exploit was used to target employees at various cryptocurrency exchanges. In part one and part two of this blog post series, we discussed the attack, and analyzed a piece of persistent Mac malware (OSX.Netwire.A
) dropped by the exploit. Specifically, we detailed the malware’s methods of persistence, and fully reversed the sample to uncover its remotely taskable capabilities.
A security researcher at Coinbase, Philip Martin, recently noted a second sample of Mac malware utilized in the (same) attack:
This second sample (sha1: b639bca429778d24bda4f4a40c1bbc64de46fa79
) was initially undetected by every engine on VirusTotal
As such, I’ve decided to triage it and share my findings!
It should be noted that for any particular AV engine (on VirusTotal), said engine may only be one (small?) piece of a more complete security product.
That is to say, a company’s comprehensive security product may also include a behavior-based engine (not included on VirusTotal) that perhaps could generically detect this new threat.
Named mac
the sample we’re analyzing today was submitted to VirusTotal on 2019-06-20:
MD5: AF10AAD603FE227CA27077B83B26543B
SHA1: B639BCA429778D24BDA4F4A40C1BBC64DE46FA79
SHA256: 97200B2B005E60A1C6077EEA56FC4BB3E08196F14ED692B9422C96686FBFC3AD
Currently it’s unnamed by the anti-virus community, although Vitali Kremez notes that it appears to be related to OSX.Mokes
(more on this later).
Let’s begin by statically analyzing the binary.
As shown by the file
utility, the malware is a 64-bit mach-O binary, albeit a rather large one (13M
!):
$ file ~/Downloads/mac ~/Downloads/mac: Mach-O 64-bit executable x86_64 $ du -h ~/Downloads/mac 13M ~/Downloads/mac
Via my open-source “WhatsYourSign” utility we can quickly see the malware is unsigned:
We can also note from the MachOView’s output, it’s linked against a variety of “interesting” libraries/frameworks:
Prefer the terminal?
Use macOS’s built-in otool utility (with the -L flag) to view linked libraries/frameworks
Such “interesting” libraries/frameworks, that may shed some insight into the malware’s capabilities include:
IOKit.framework
AVFoundation.framework
CoreWLAN.framework
OpenGL.framework
CoreVideo.framework
Next, let’s extract embedded (ascii) strings via the built-in strings
utility (with the -a
flag):
$ strings -a ~/Downloads/mac storeaccountd com.apple.spotlight Spotlightd Skype soagent Dropbox quicklookd Google Chrome accountd Firefox Profiles trustd User-Agent Connection Close screenshots/ desktop_ jpeg *.doc *.docx *.xls *.xlsx transport.museum nishinomiya.hyogo.jp is-into-cars.com ...
There are also many strings related to statically linked libraries (such as OpenSSL).
This (likely) explains the massive size of the binary!
As noted, a limitation of the strings
utility is that is only extracts ascii strings. To extract unicode (or “wide”) strings, I used a modified version of the following python script: strings.py.
1def unicode_strings(buf, n=4):
2 reg = b"((?:[%s]\x00){%d,})" % (ASCII_BYTE, n)
3 uni_re = re.compile(reg)
4 for match in uni_re.finditer(buf):
5 try:
6 yield String(match.group().decode("utf-16"), match.start())
7 except UnicodeDecodeError:
8 pass
Turns out there are some interesting unicode (wide) strings embedded in the binary:
$ python ~/Downloads/strings.py ~/Downloads/mac 0x8f0018: :/keys/bot 0x8f01a8: %1/Library/LaunchAgents/%2.plist 0x8f0210: powershell.exe 0x8f0248: dd*.ddt 0x8f0270: kk*.kkt 0x8f0298: aa*.aat 0x8f02c0: ss*.sst 0x8f02e8: application/octet-stream 0x8f0338: Content-Type 0x8f0378: JPEG 0x8f03c0: auto-file-search 0x8f0400: :/file-search 0x8f0478: search%1 0x8f0910: s:// 0x8f0957: keys 0x8f0963: dbot
Embedded in the binary are also 5000+ urls! A few are included here:
mizunami.gifu.jp saitama.jp kimino.wakayama.jp int.bo cambridge.museum andasuolo.no lardal.no transport.museum nishinomiya.hyogo.jp is-into-cars.com karlsoy.no bungoono.oita.jp int.ci chikujo.fukuoka.jp franziskaner.museum cc.nj.us genkai.saga.jp tysfjord.no ra.it air-traffic-control.aero ina.ibaraki.jp in-the-band.net ainan.ehime.jp oita.oita.jp national-library-scotland.uk …
Moving on, via class-dump
utility we can reconstruct embedded Objective-C class information. Thought it’s mostly QT
related classes there are some interesting AVFoundation
protocols that are generally associated with recording off the webcam:
$ class-dump ~/Downloads/mac // // Generated by class-dump 3.5 (64 bit). // // File: ~/Downloads/mac // // Arch: x86_64 // Minimum Mac OS X version: 10.7.0 // SDK version: 10.9.0 @protocol AVCaptureFileOutputRecordingDelegate- (void)captureOutput:(AVCaptureFileOutput *)arg1 didFinishRecordingToOutputFileAtURL:(NSURL *)arg2 fromConnections:(NSArray *)arg3 error:(NSError *)arg4; @optional - (void)captureOutput:(AVCaptureFileOutput *)arg1 willFinishRecordingToOutputFileAtURL:(NSURL *)arg2 fromConnections:(NSArray *)arg3 error:(NSError *)arg4; - (void)captureOutput:(AVCaptureFileOutput *)arg1 didResumeRecordingToOutputFileAtURL:(NSURL *)arg2 fromConnections:(NSArray *)arg3; - (void)captureOutput:(AVCaptureFileOutput *)arg1 didPauseRecordingToOutputFileAtURL:(NSURL *)arg2 fromConnections:(NSArray *)arg3; - (void)captureOutput:(AVCaptureFileOutput *)arg1 didStartRecordingToOutputFileAtURL:(NSURL *)arg2 fromConnections:(NSArray *)arg3; @end
Ok, time to hop in to Virtual Machine (VM) to execute the malware and see what it does! Generally when dynamically analyzing malware, I’m looking for things such as:
To passively observe file events related to the malware, we can use macOS’s built-in file monitor utility: fs_usage
:
# fs_usage -w -f filesystem | grep mac mkdir /Users/user/Library/Dropbox mac.14997 open /Users/user/Desktop/mac RdData[A] /Users/user/Desktop/mac mac.14997 open /Users/user/Library/Dropbox/quicklookd WrData[A] /Users/user/Library/Dropbox/quicklookd mac.14997 execve /Users/user/Library/Dropbox/quicklookd
The fs_usage
will capture file events for the entire system, which quickly can become overwhelming.
As such, it’s recommended to filter the output, for example by piping it into grep and matching on the malware (i.e. ‘mac’).
From the fs_usage
output, it’s fairly clear to see that the malware is installing itself to the ~/Library/Dropbox/
directory as quicklookd
A quick check (of the hashes) confirms that the “new” binary quicklookd
is indeed simply a copy of the malware:
$ shasum -a 1 ~/Desktop/mac ~/Library/Dropbox/quicklookd b639bca429778d24bda4f4a40c1bbc64de46fa79 /Users/user/Desktop/mac b639bca429778d24bda4f4a40c1bbc64de46fa79 /Users/user/Library/Dropbox/quicklookd
We can also see in the file monitor output that after making a copy of itself, the malware executes (via execve
) this copy. Our process monitor, ProcInfo, also captures this event:
procInfo[730:14509] process start: pid: 733 path: /Users/user/Library/Dropbox/quicklookd user: 501 args: ( "/Users/user/Library/Dropbox/quicklookd ) signing info: { signatureStatus = "errSecCSUnsigned (-67062)"; }
In terms of networking, LuLu, (our free, open-source firewall) detects a connection attempt to what is likely the malware’s command & control server, 185.49.69.210
:
The built-in command lsof
utility also shows this connection attempt:
lsof -i TCP COMMAND PID USER TYPE NAME quicklookd 733 user IPv4 TCP 192.168.0.128:49291->185.49.69.210:http (SYN_SENT)
After a few seconds BlockBlock alerts on a persistence attempt:
Apparently the (installed copy of the) malware persists itself as a launch agent. Let’s dump it’s launch agent plist (quicklookd.plist
):
$ defaults read ~/Library/LaunchAgents/quicklookd.plist { KeepAlive = 1; Label = quicklookd; ProgramArguments = ( "/Users/user/Library/Dropbox/quicklookd" ); RunAtLoad = 1; }
As the launch agent (quicklookd.plist
) has the RunAtLoad
key set (to 1
), the OS will automatically launch the specified binary, /Users/user/Library/Dropbox/quicklookd
each time the user logs in. This provides the malware persistence.
At this point, our dynamic analysis as provided valuable insight into the malware including its:
Let’s dig a little deeper into the installation logic, as (as we’ll see) the malware implements some “variability” to perhaps complicate detection.
Recall that when extracting embedded strings, we saw strings such as quicklookd
and Dropbox
that the malware used during the installation and persistence process (that is to say the malware installed itself as quicklookd
into a directory named Dropbox
).
In the malware binary, in close proximity, there are other embedded strings:
Rather interestingly, restoring the VM to a pristine state and (re)running the malware, results in the malware selecting one of the other strings pairs (e.g. App Store
/ storeaccountd
) for installation and persistence purposes. For example, here’s BlockBlock alerting on a persistence attempt (note the malware installed itself this time, as storeaccountd
):
With a general understanding of the malware’s installation and persistence, and recovering an address of (the likely) command & control server, let’s talk about the malware’s capabilities.
However, first we need to talk about OSX.Mokes
…as this will, in actuality, reveal the malware’s capabilities!
OSX.Mokes
ConnectionA day or two ago, Vitali Kremez tweeted the following, stating that this malware is “is likely linked to…Backdoor.OSX.Mokes
“:
…as we’ll see, I believe he’s 100% correct.
OSX.Mokes
is cross-platform, fully-featured backdoor that was discovered by Kaspersky in 2016. In an excellent writeup, “The Missing Piece – Sophisticated OS X Backdoor Discovered”, they detailed OSX.Mokes
installation, persistence, network comms and rather impressive capabilities (screen capture, audio capture, document discovery & exfiltration, and more).
I’ve blogged about OSX.Mokes
before and even mentioned it several conference talks:
Stop me if this sounds familiar but in a previous blog, from 2017, I stated:
…the malware [
OSX.Mokes
] may install itself into multiple locations.Besides the standard
storeuserd
name, the malware may install itself to:
~/Library/com.apple.spotlight/SpotlightHelper
~/Library/Dock/com.apple.dock.cache
~/Library/Skype/SkypeHelper
~/Library/Dropbox/DropboxCache
~/Library/Google/Chrome/nacld
~/Library/Firefox/Profiles/profiled
And take a look at a side-by-side comparison of OSX.Mokes
(from 2016) and the sample from today:
Though names (in some cases) been slightly changed, clearly there is a ton of overlap.
Many other commonalities between the two samples are present, for example when we start comparing the malware’s capabilities. In Kaspersky’s original writeup on OSX.Mokes
they state:
This malware…is able to steal various types of data from the victim’s machine (Screenshots, Audio-/Video-Captures, Office-Documents, Keystrokes).”
Looking at the original OSX.Mokes
sample, we find several hard-coded file search constants:
10x0000001C unicode :/file-search
20x0000000E unicode *.xlsx
30x0000000C unicode *.xls
40x0000000E unicode *.docx
50x0000000C unicode *.doc
In the malware we’re looking at today, as noted by Vitali Kremez, we find the exact same file search constants (albeit in a slightly different order):
10x00000001008f0400 unicode :/file-search
20x00000001008c0fed unicode *.doc
30x00000001008c0ff3 unicode *.docx
40x00000001008c0ffa unicode *.xls
50x00000001008c1000 unicode *.xlsx
Kaspersky also noted in their writeup from 2016 that:
“Just like on other platforms, the malware creates several temporary files containing the collected data if the C&C server is not available.
$TMPDIR/ss0-DDMMyy-HHmmss-nnn.sst
(Screenshots)$TMPDIR/aa0-DDMMyy-HHmmss-nnn.aat
(Audiocaptures)$TMPDIR/kk0-DDMMyy-HHmmss-nnn.kkt
(Keylogs)$TMPDIR/dd0-DDMMyy-HHmmss-nnn.ddt
(Arbitrary Data)”
Again, in the malware we’re looking at today we see a clear overlap; specifically in the file extensions used to store collected data:
Many other commonalities (such as unique strings, cross-platform static compiled libraries, capabilities, and even size (approximately 13M
)) IMHO confirm that the malware we analyzed today is new variant of OSX.Mokes
.
I’m calling it OSX.Mokes.B
Via a Firefox 0day, attackers targeted employees of various cryptocurrency exchange(s) in order to persistently deploy two macOS backdoors.
In part one and part two of this blog post series, we discussed the attack and analyzed the first backdoor (OSX.Netwire.A
).
In today’s post, we analyzed the second specimen (SHA1: B639BCA429778D24BDA4F4A40C1BBC64DE46FA79
) and discussed its:
Most interestingly we confirmed that (as noted by others) the second persistent backdoor is undoubtedly a new variant of OSX.Mokes
To conclude, recall that although this sample, OSX.Mokes.B
is closely related to the original OSX.Mokes
sample (from 2016) not a single anti-virus engine on VirusTotal detected it as malicious! 😭
This is (yet another) example of why it’s far better to detect malicious behaviors versus static signatures. Which is what Objective-See’s tools are all about. Specifically they are able to generically detect and thus thwart (with no a priori knowledge!) even this advanced (“new”) threat:
KnockKnock: can reveal the infection (after the fact), by detecting the malware’s launch agent persistence, regardless of it’s name.
BlockBlock: will detect the malware’s persistence attempt, again regardless of it’s name.
LuLu: will detect the malware’s attempt to communicate with it’s remote command & control server
OverSight: if the malware began collecting audio or video, this would been (generically) detected
…and the best part of all these tools? They are all 100% free 🥳