• Objective See
  • about
  • blog
  • malware
  • products


Analyzing the Anti-Analysis Logic of an Adware Installer
02/07/2016

Recently, SANS posted a short blog post titled "Fake Adobe Flash Update OS X Malware". While the blog covers the initial infection vector, and subsequent articles provide a decent overview of the attack, here, let's briefly discuss some of the anti-analysis techniques utilized by the malware installer.

Note: if you want to follow along at home, download the malware installer (password: infect3d).


Attack Overview
In the SANS post, the author (Johannes Ullrich), described a Facebook click-bait scheme that led naive users to a "fake Flash update":


If an unsuspecting user is tricked into installing the 'update' they will unfortunately become infected with OS X adware.

While this social-engineering approach is the most common OS X infection strategy, the fact that the binary installer is signed is somewhat interesting. SANS noted this, specifically stating, "The installer is signed with a valid Apple developer certificate issued to a Maksim Noskov."
$ codesign -dvvv /Volumes/Installer/Installer.app
Executable=/Volumes/Installer/Installer.app/Contents/MacOS/tirocinium
Identifier=com.overlaunch.leachy
Format=bundle with Mach-O thin (x86_64)
CodeDirectory v=20200 size=4065 flags=0x0(none) hashes=196+3 location=embedded
Hash type=sha1 size=20
CDHash=51bd58065c669b840c3bcab2a3f618745c64b264
Signature size=8525
Authority=Developer ID Application: Maksim Noskov (SHPB74W374)
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=Jan 20, 2016, 5:41:11 AM
Info.plist entries=28
TeamIdentifier=SHPB74W374
Sealed Resources version=2 rules=12 files=50
Internal requirements count=1 size=184

Executing the (signed) installer, launches a GUI installer application. And if the user completes the installation, malware and (interestingly) a legitimate copy of adobe flash will be installed on their system.




Malware Installer; InstallCore
As previously mentioned, the malware installer is signed by Maksim Noskov. Though signing malware affords a simple Gatekeeper 'bypass', it may provide attribution and also presents a simple way to stop the malware in its tracks. How? Apple can (and did) easily revoke the signing certificate, thus preventing the malware from ever executing. This is illustrated in the following image where as of February 7th, OS X blocks the malware with CSSMERR_TP_CERT_REVOKED (-2147409652):




Ok, back to Maksim Noskov. Hopping on VirusTotal, we find about 1000 files signed with this Apple Developer ID:


Several (if not all) appear to be the slight variants of the malware installer; identified as InstallCore


InstallCore is a known component of OS X adware that's been discussed before. Here however, lets briefly discuss some of its anti-analysis features.

One of the main questions an analyst often asks when analyzing a malicious installer or downloader is what the installer persistently installs and from where. Capturing some network traffic shows the malware installer connecting to various HTTP servers (presumably to download other malicious components), as well as downloading a legitimate adobe flash installer:
# tcpdump -s0 -A host 192.168.0.7 and port 80

...

GET /adobe_flashplayer_e2c7b.dmg HTTP/1.1
Host: appsstatic2fd4se5em.s3.amazonaws.com
Accept: */*
Accept-Language: en-us
Connection: keep-alive
Accept-Encoding: gzip, deflate
User-Agent: Installer/1 CFNetwork/720.3.13 Darwin/14.3.0 (x86_64)

However, running 'strings' on the installer binary does not reveal these urls (e.g. appsstatic2fd4se5em.s3.amazonaws.com):
$ strings -a /Volumes/Installer/Installer.app/Contents/MacOS/tirocinium | grep appsstatic2fd4se5em.s3.amazonaws.com | wc
0 0 0

Clearly some string obfuscation is being performed. In reality, this isn't too surprising; most malware (especially on Windows platforms) will obfuscate sensitive strings.

Loading the malware installer's binary (tirocinium), into a disassembler such as IDA, makes it easy to spot string obfuscations (a simple add loop):
  mov [rbp+var_8], 7Ch
  mov [rbp+var_7], 80h
  mov [rbp+var_6], 7Eh
  mov [rbp+var_5], 6Dh
  mov [rbp+var_4], 6Fh
  mov [rbp+var_3], 71h
  mov [rbp+var_2], 0Ch
  mov [rbp+var_8], 70h
  mov eax, 1

loop:
  add [rbp+rax+var_8], 0F4h
  inc rax
  cmp rax, 6
  jnz short loop

  mov [rbp+var_2], 0

Though one could write an IDAPython script to decode such strings, I'm lazy and would rather let the malware simply deobfuscate the strings itself, under the watchful eye of a debugger. However, before jumping into a dynamic debugger, let's note another 'anti-analysis' feature; junk code.

Many of the malware installer's methods contain copious amounts of spurious NOPs function calls that make up what is known as 'junk code'. For example, take a look at the -[ICJavaScriptEnvironmentInfo macAddress] method, which attempts to get the MAC address of the user's system. Apple's sample code, illustrates how get a MAC address in few lines of code. However, the IDA disassembly of the -[ICJavaScriptEnvironmentInfo macAddress] method takes up over 12 thousand bytes of disassembly!





As the following images illustrate, there are many many code blocks and calls in the disassembly to functions such as lround, NSUserName, rint, sysconf, and more. All these calls are 'useless' - they're simply present to change the signature (hash) of identical samples and/or perhaps thwart simple AV emulators and/or hinder analysis. However, in terms of manual analysis, while somewhat annoying, in reality they don't stop us.

As previously mentioned, many of the malware's more interesting strings are obfuscated. It was surmised that the easiest way to uncover such strings was to simply let the malware run under a debugger, allowing it to un-obfuscate the strings for us. Unfortunately, attempting to debug the malware initially failed:
$ lldb /Volumes/Installer/Installer.app
(lldb) target create "/Volumes/Installer/Installer.app"
Current executable set to '/Volumes/Installer/Installer.app' (x86_64).


(lldb) r
Process 1530 launched: '/Volumes/Installer/Installer.app/Contents/MacOS/tirocinium'
Process 1530 exited with status = 45 (0x0000002d)

I suspected some anti-debugging logic in the malware. While such anti-debugging in Windows malware is very common, on OS X malware, it is somewhat more rare.

Skimming the disassembly, nothing appears immediately obvious that would indicate debugger detection. However, as large portions of the malware (such as strings) were obfuscated, this isn't too surprising.

Starting a debug session and setting a breakpoint on the malware installer's initial code logic (-[ICAppController applicationDidFinishLaunching:]) did work. This indicated some code was (later) manually detecting the debugger and then terminating itself. Stepping over chunks of code quickly identified such a function (sub_100035C5B):
__text:0000000100035C5B sub_100035C5B proc near
__text:0000000100035C5B
__text:0000000100035C5B var_C = dword ptr -0Ch
__text:0000000100035C5B var_8 = byte ptr -8
__text:0000000100035C5B var_7 = byte ptr -7
__text:0000000100035C5B var_6 = byte ptr -6
__text:0000000100035C5B var_5 = byte ptr -5
__text:0000000100035C5B var_4 = byte ptr -4
__text:0000000100035C5B var_3 = byte ptr -3
__text:0000000100035C5B var_2 = byte ptr -2

__text:0000000100035C5B         push rbp
__text:0000000100035C5C         mov rbp, rsp
__text:0000000100035C5F         sub rsp, 10h
__text:0000000100035C63         mov [rbp+var_8], 7Ch
__text:0000000100035C67         mov [rbp+var_7], 80h
__text:0000000100035C6B         mov [rbp+var_6], 7Eh
__text:0000000100035C6F         mov [rbp+var_5], 6Dh
__text:0000000100035C73         mov [rbp+var_4], 6Fh
__text:0000000100035C77         mov [rbp+var_3], 71h
__text:0000000100035C7B         mov [rbp+var_2], 0Ch
__text:0000000100035C7F         mov [rbp+var_8], 70h
__text:0000000100035C83         mov eax, 1
__text:0000000100035C88
__text:0000000100035C88 loop:
__text:0000000100035C88         add [rbp+rax+var_8], 0F4h
__text:0000000100035C8D         inc rax
__text:0000000100035C90         cmp rax, 6
__text:0000000100035C94         jnz short loop

__text:0000000100035C96         mov [rbp+var_2], 0
__text:0000000100035C9A         lea rsi, [rbp+var_8] ; symbol
__text:0000000100035C9E         mov rdi, 0FFFFFFFFFFFFFFFFh ; handle
__text:0000000100035CA5         call _dlsym
__text:0000000100035CAA         mov [rbp+var_C], 28h
__text:0000000100035CB1         add [rbp+var_C], 0FFFFFFF7h
__text:0000000100035CB5         mov edi, [rbp+var_C]
__text:0000000100035CB8         xor esi, esi
__text:0000000100035CBA         xor edx, edx
__text:0000000100035CBC         xor ecx, ecx
__text:0000000100035CBE         call rax
__text:0000000100035CC0         add rsp, 10h
__text:0000000100035CC4         pop rbp
__text:0000000100035CC5         retn
__text:0000000100035CC5 sub_100035C5B endp

sub_100035C5B starts by de-obfuscating some string (see the loop at 0000000100035C88). Stepping over the deobfuscation logic in a debugger, reveals the string value: "ptrace"
(lldb) x/s $rbp-0x8
0x7fff5fbfe378: "ptrace"

Once the "ptrace" string is deobfuscated, the function then calls dlsym to resolve the address of ptrace.
(lldb) reg read
General Purpose Registers:
rax = 0x00007fff96afa0ec libsystem_kernel.dylib`__ptrace
...

Finally, at address 0x0000000100035CBE the function invokes ptrace with 0x1F for the request parameter. Seasoned OS X reversers should recognize 0x1F as PT_DENY_ATTACH, a common OS X-specific anti-debugging trick. Specifically, on OS X, if a process calls ptrace(PT_DENY_ATTACH, 0, 0, 0) while being actively debugged (traced), Apple notes it "will exit with the exit status of ENOTSUP;" Also, if a process has called ptrace with PT_DENY_ATTACH, attempting to attach to it with a debugger will equally fail.

Of course this anti-debugging mechanism is trivial to bypass. For example, one can skip over call, by modifying the program counter register (RIP):
(lldb) x/2i $pc
 0x100035cbe: ff d0 callq *%rax
 0x100035cc0: 48 83 c4 10 addq $0x10, %rsp

(lldb) reg write $rip 0x0000000100035CC0

(lldb) x/2i $pc
 0x100035cc0: 48 83 c4 10 addq $0x10, %rsp
 0x100035cc4: 5d popq %rbp


Final Thoughts
The malware discussed in this blog post depends on an amateur infection mechanism, and is not particularly novel or intriguing. However, it makes use of some obfuscations and anti-debugging techniques. While such anti-analysis logic is quite common in Windows malware, they are somewhat more rare on OS X...for now!


  • © 2017 objective-see llc
  • ✉
  • 
  • 
  • donate!