Digita Security

Cybersecurity solutions for the

  • modern
  • mobile
  • independent
  • innovative
  • enterprising

macOS workforce

June 23, 2019

Part III: Burned by Fire(fox)

a firefox 0day drops another macOS backdoor (osx.mokes.b)
by Patrick Wardle

This is Part 3 of a 3 Part series. In Part 1, we identified the malware as OSX.Netwire.A and discussed the infection vectors of the attack. In Part 2, we detailed the malware’s methods of persistence, and fully reversed the sample to uncover its remotely taskable capabilities. In this next section we will review the second specimen which persists within the attack and creates an additional backdoor. While analyzing this second specimen we will cover topics of its installation, method of persistence, command & control server and capabilities. All of these capabilities can be detected within your enterprise provided you have a heuristic engine which is capable of understanding unwanted events providing value beyond the detection of undesired signatures. For more info on how you can defend your organization using GamePlan, checkout: “Leveraging Apple’s Game Engine for Advanced Threat Detection

If you would like to see a demo, you can request one on the homepage of our website.

Background

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.

📝 👾 Want to play along?

I’ve shared the sample (password: infect3d)

…please don’t infect yourself!

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 would presummingly include a behavior-based engine (not included on VirusTotal) that perhaps could generically detect this new threat (i.e GamePlan).

Static Analysis

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 “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

Dynamic Analysis

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:

  • files created
  • processes started
  • network connections

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, a firewall such as LuLu, 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 the malware persists:

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:

  • installation
  • persistence (launch agent)
  • address of command & control server

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 another persistence alert (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!

The OSX.Mokes Connection

A 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

Conclusion

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:

  • installation
  • method of persistence
  • command & control server
  • capabilities

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.