HackingTeam Reborn; A Brief Analysis of an RCS Implant Installer
02/26/2016
› note: if you want to follow along at home, download the malware installer (password: infect3d).
As I'm generally quite occupied with my day job as Director of R&D at Synack, the weekend is when I finally have some free time to blog. This weekend I wasn't sure what I'd write about until @osxreverser tweeted late Friday afternoon:
Obviously the Italians referenced here, are HackingTeam - but what about "Apple's Encrypted binaries"...that to me was the intriguing part! (well and the fact that I didn't know HackingTeam was still around, after getting totally owned).
Last summer, at Blackhat I gave a presentation entitled Writing Bad @$$ Malware for OS X. In this talk, I provided several suggestions as to how OS X malware could be improved. One thing I mentioned was leveraging Apple's native encryption scheme as simple way to 'protect' one's malicious binaries:
Moreover, I was literally just beta-testing the next version of TaskExplorer this week, which can globally enumerate and list all such encrypted binaries (see below) - precisely to detect such malware!
Now I'm sure other people have had the idea of using Apple's encryption scheme to protect their malware and, as we'll see, it's really not that good an idea (malware authors: use environmental key generation!). But until now, I'd never encountered any malware that made use of this encryption scheme - so yes, I was stoked!
After chatting with @osxreverser and @claud_xiao (mahalos guys!), I was able to get a hash of binary that turned out to an implant installer (dropper) for HackingTeam's latest(?) version of their RCS Implant. Luckily this new binary is 'available' on VirusTotal for analysis, or as a direct download here (password: infect3d).
Implant Installer (Dropper)
The implant installer binary (sha256: 58e4e4853c6cfbb43afd49e5238046596ee5b78eca439c7d76bd95a34115a273) is detected by exactly 0 (of 54) AV companies :/
Diving in, the first thing we notice is that it is encrypted with Apple's native OS X encryption scheme. How can we tell this? Well, as detailed here one can check if the binary's _TEXT segment's load command flags has the SG_PROTECTED_VERSION_1 (0x8) set:
$ otool -l install
Load command 1
cmd LC_SEGMENT
cmdsize 328
segname __TEXT
vmaddr 0x00001000
vmsize 0x00004000
fileoff 0
filesize 16384
maxprot 0x00000007
initprot 0x00000005
nsects 4
flags 0x8
IDA Pro will inform you of this fact as well:
Finaly, as previously mentioned, the soon to be released next version of TaskExplorer can also globally display all tasks and/or libraries that are protected in this manner. Obviously signed Apple binaries that are encrypted are fine - anything else (e.g. the unsigned 'install'); SUPER SHADY!
As the implant's installer is encrypted, static analysis cannot commence until it is decrypted. Luckily, as explained in my BlackHat talk (and many other places online), since the encryption scheme is symmetrical (Blowfish), and utilizes a static key, it can easily be 'undone'. In fact, even the well known Classdump tool contains an open-source implementation of such a decryptor. Compiling this decryptor code, ('deprotect') we can easily decrypt the implant's installer:
./deprotect install installDecrypted
$ otool -l installDecrypted
Load command 1
cmd LC_SEGMENT
cmdsize 328
segname __TEXT
vmaddr 0x00001000
vmsize 0x00004000
fileoff 0
filesize 16384
maxprot 0x00000007
initprot 0x00000005
nsects 4
flags 0x0
Hooray - now we can dive into the analysis, right? Unfortunately the implant installer, while now decrypted, is also packed :/ Again, how can we tell? Well either looking at the IDA disassembly (which is still f00bar'd) or, again, via the soon-to-be-release version of TaskExplorer, which can now generically detect (via entropy analysis) packed binaries!
Now, I'm not too familiar with HackingTeam's packers - though a phenomenal overview is provided here. Of course @osxreverser already had provided some insight into this:
Due to @osxreverser's tweet, specifically that HackingTeam was likely using a custom packer, I decided to go the simpler route of simply dumping the unpacked installer from memory so that I could analyze it in IDA Pro.
While there are many ways to dump memory of binary, I ran into some complications. First, lldb (Apple's debugger) cannot be told to ignore EXC_BAD_ACCESS exceptions. This means that if the unpacking code throws any such exceptions (which packers often do and catch themselves or/and process as part of the unpacking process), the debugger will catch it, and (AFAIK), it cannot be ignored or delivered 'back' to the unpacking code. So my efforts with lldb failed :/
$ lldb installDecrypted
Current executable set to 'installDecrypted' (i386).
(lldb) process launch
Process 714 launched: '/Users/user/Desktop/installDecrypted' (i386)
Process 714 stopped
* thread #1: tid = 0x39e1, 0x0000709d installDecrypted, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS
Other tools that can dump memory require the process to be running - which was problematic in this case, as the implant installer would complete and terminate almost immediately. As such, I decided to write an injectable dynamic-library that would suspend the process once loaded...allowing me then attach with a debugger, and dump memory to my heart's desire.
With implant installer loaded, unpacked, and paused, I attached with lldb and dumped the now unpacked section of binary code.
$ ps aux | grep [i]nstallDecrypted
user 519 1.9 0.8 658408 17276 s000
$ lldb -p 519
...
(lldb) memory read --outfile /tmp/dumped.txt 0x7000 0xBFFFF --force
Hopping back to IDA Pro, we can load the memory dump file to finally get a reasonable disassembly:
While the IDA disassembly is not perfect (as it's from a dumped memory segment), its gives a good idea of whats going on; the implant installer (as expected) appears to install a persistent implant.
In general, I like to supplement my static analysis theories (e.g. 'it's installing an implant') with dynamic analysis. Using fs_usage, we can easily see that's exactly what is going on:
$ sudo fs_usage -w -f filesystem | grep install
execve /Users/user/Library/Preferences/8pHbqThW/_9g4cBUb.psr
open /Users/user/Library/Preferences/8pHbqThW/Bs-V7qIU.cYL
write F=8 B=0x8f0
Specifically, the implant after dropping a persistent implant to ~/Library/Preferences/8pHbqThW/_9g4cBUb.psr executes it (via execve). An encrypted data (config?) file named Bs-V7qIU.cYL, is also dropped into the ~/Library/Preferences/8pHbqThW/ directory.
Persistent Implant (RCS)
Once the persistent implant (_9g4cBUb.psr, sha256: 14f4a490be8e4f4aaf672c7e0db8f5bfdda0bbcf78031f5db543879f40156d19) has been saved to disk and executed, it persists itself as user Launch Agent:
$ sudo fs_usage -w -f filesystem | grep _9g4cBUb.psr
lstat64 /Users/user/Library/LaunchAgents/com.apple.FinderExtAvt.plist
HFS_update /Users/user/Library/LaunchAgents
WrData[A] /Users/user/Library/LaunchAgents/.dat.nosync028d.8bNgne
rename /Users/user/Library/LaunchAgents/.dat.nosync0289.8bNgne
Of course, BlockBlock can easily detect and can block this persistence attempt ;)
This binary is also detected by exactly 0 (of 54) AV companies :/
Luckily a tool such as KnockKnock, which enumerates all persistently installed binaries, can easily reveal its presence:
Although the persistent implant is not protected via Apple's native OS X encryption scheme, it is also packed. However, since it is a continually running process, its memory can be trivially dumped. I used @osxreverer's readMem open-source tool.
$ ps aux | grep [_]9g4cBUb.psr
user 649 1.9 0.8 658408 17276 s000 Users/user/Library/Preferences/8pHbqThW/_9g4cBUb.psr
$ sudo ./readmem -p 649 -m -o dumped.bin
---------------------------------
Readmem v0.6 - (c) 2012, 2013 fG!
---------------------------------
[DEBUG] Found main binary mach-o image @ 0x1000!
[DEBUG] Executing get_image_size
[DEBUG] Executing dump_binary
[DEBUG] Dumping __TEXT at 1000 with size 6b000 (buffer:38000)
[DEBUG] Dumping __DATA at 6c000 with size 38000 (buffer:a3000)
[DEBUG] Dumping __OBJC at a4000 with size 7000 (buffer:db000)
[DEBUG] Dumping __LINKEDIT at ab000 with size 6608 (buffer:e2000)
[OK] Full binary dumped to dumped.bin!
Running strings on the dumped (unpacked) memory of the implant quickly reveals, that yes indeed, it's HackingTeams RCS implant.
$ strings dumped.bin | less
runMeh
addBackdoorToSLIPlist
removeBackdoorFromSLIPlist
createLaunchAgentPlist:forBinary:
createSLIPlistWithBackdoor
isBackdoorPresentInSLI:
mBackdoorControlFlag
setMBackdoorControlFlag:
_SLIEscalation
_grabScreenshot:
While this is perhaps an updated version of their implant with new features or surprises, I'll defer full analysis to the experts.
Conclusions
First, it's Friday night and I'm analyzing malware. I think the biggest takeaway is that I need to get out more :|
Other than that, it's nice to finally see some OS X malware that uses Apple's native OS X encryption scheme, as well as custom packers.
To check if you are infected, simply look for the following directory: ~/Library/Preferences/8pHbqThW/ containing _9g4cBUb.psr and/or Bs-V7qIU.cYL. To disinfect yourself, delete that entire directory, and remove the ~/Library/LaunchAgents/com.apple.FinderExtAvt.plist file. Of course if you really are infected - throw out your computer and get a new one!
Finally, a shameless plug for Objective-See's tools such as BlockBlock, KnockKnock, and TaskExplorer (I mean, they are free, so why not?). Obviously traditional Anti-Virus solutions aren't going to protect you...so why not run something that hopefully will? I do :)
P.S. If this blog interested you, I'm giving a talk next week (Wednesday March 2nd) at RSA titled: "Let's Play Doctor: Practical OS X Malware Detection and Analysis. Though not as technically in-depth as this blog post, I'll cover similar concepts...and will be releasing some neat new tools :)