1 Mar 2016

Largely undetected Mac malware suggests disgraced HackingTeam has returned





Researchers have uncovered what appears to be newly developed Mac malware from HackingTeam, a discovery that's prompting speculation that the disgraced malware-as-a-service provider has reemerged since last July's hack that spilled gigabytes worth of the group's private e-mail and source code.



The sample was uploaded on February 4 to the Google-owned VirusTotal scanning service, which at the time showed it wasn't detected by any of the major antivirus programs. (Ahead of this report on Monday, it was detected by 10 of 56 AV services.) A technical analysis published Monday morning by SentinelOne security researcher Pedro Vilaça showed that the installer was last updated in October or November, and an embedded encryption key is dated October 16, three months after the HackingTeam compromise.

The sample installs a copy of HackingTeam's signature Remote Code Systems compromise platform, leading Vilaça to conclude that the outfit's comeback mostly relies on old, largely unexceptional source code, despite the group vowing in July that it would return with new code.

"HackingTeam is still alive and kicking but they are still the same crap morons as the e-mail leaks have show us," Vilaça wrote. "If you are new to OS X malware reverse engineering, it's a nice sample to practice with. I got my main questions answered so for me there's nothing else interesting about this. After the leak I totally forgot about these guys :-)."

Patrick Wardle, a Mac security expert at Synack, has also examined the sample and says that while it appears to install a new version of the old HackingTeam implant, it uses several advanced tricks to evade detection and analysis. For one, it uses Apple's native encryption scheme to protect the contents of the binary file, making it the first malicious implant installer Wardle has ever seen to do so. Wardle was nonetheless able to break the encryption because Apple uses a static hard-coded key—"ourhardworkbythesewordsguardedpleasedontsteal(c)AppleC"—that has long been known to reverse engineering experts. Even then, he found that the installer was "packed" in a digital wrapper that also limited the types of reverse engineering and analysis he wanted to perform.

The sample still leaves many questions unanswered. For example, it's not clear how the malware gets installed. One possibility is that targets are tricked into believing that the file installs a benign application. Another possibility is that it's bundled with an exploit that surreptitiously executes the installer. People who want to know if a Mac is infected should check for a file named Bs-V7qIU.cYL, which is dropped into the ~/Library/Preferences/8pHbqThW/ directory.

Vilaça said he can't conclusively determine that the new sample is the work of HackingTeam. Since the 400 gigabytes of data that was obtained in the July breach included the Remote Code Systems source code, it's possible that a different person or group recompiled the code and distributed it in the new installer. Still,Vilaça said evidence from the Shodan search service and a scan of the IP address in VirusTotal show that a command and control server referenced in the sample was active as recently as January, suggesting that the new malware is more than a mere hoax.







The sample hashes are:

ZIP with dropper: 2ee9e9d9a0cd3cee6519e7b950821d5c90af03da665879615e52fd093dd8e947
Dropper binary: 58e4e4853c6cfbb43afd49e5238046596ee5b78eca439c7d76bd95a34115a273

Both files were submitted to VirusTotal three weeks ago.
And their detection rate was (as mostly expected) zero.
As I have written a couple of times, the first thing we should do is to look at the mach-o headers of the binary files. This can quickly gives us valuable information and save us some future time.
The first thing one can notice on this binary is that extra segment called “_eh_frame”. This is not a normal segment although it is labeled as a section that can be usually found in mach-o binaries. HackingTeam used this same trick in the past so it’s a strong indicator we are analysing HackingTeam malware and that this could still be an old sample.
Next trick is the fact that this binary is using Apple’s Binary protection, which we can observe on the flags trick using SG_PROTECTED_VERSION_1 flag. A good reference on this Apple feature is Amit Singh’s blog post. It’s pretty easy to dump and recover the original code so it’s not an obstacle to reverse engineering this sample, mostly to evade AV detection. Back in 2009 I wrote a blog post on how to manually dump these binaries or you can use “deprotect” from Classdump to automatically do it for you.
The injected segment is also protected with the same Apple feature and deprotect tool seems unable to deal with this fact. We can try to manually dump this segment. For this to happen we need to attach a debugger to the dropper binary, since the segment will only be decrypted when its memory pages are used. This is where we find one interesting trick from this sample :-).

Before we go there, a last screenshot from the binary headers. If we look at the entrypoint it points into the “_eh_frame” segment, which is also very unusual (VirusTotal flags this as suspicious). What happens is that the normal __TEXT segment is fake since it contains no code (look at the size, it occupies 4kb in memory). Same trick as older RCS samples.
I’m not a fan of lldb so I still use old Apple’s gdb. It works for me so why bother with the newer but awkard lldb?
The entrypoint is a good breakpoint so that’s where we start. When we run the dropper gdb gives us a weird error message.
Gdb has hit a EXC_BAD_ACCESS exception at the entrypoint address, meaning that memory permissions are wrong. The segment is now decrypted (you can compare this code with the code you get if you try to disassemble the binary) and we can dump it with gdb itself or my readmem util. What we are unable to do is to step and debug the dropper binary. To dump using readmem just use “readmem -p PID -a 0x7000 -s 0xB9000”, with gdb “dump memory FILENAME 0x7000 0xC0000”. This will give you the full “_eh_frame” segment which you can then load into a disassembler. It’s not a mach-o binary so the disassembler will complain but you know where the entrypoint is so you can disassemble from there.
Anyway, let’s get into the interesting stuff. The gdb error quickly gave me an hint to look again at the mach-o headers. Let’s look at the “_eh_frame” segment header again…
Can you spot anything special here?
Look at the VM memory protections. The maximum VM protection is set to Read and Writable, and the Initial VM protection to Read and Executable. If this code is executable the flags will need to be executable. What happens here is that the maximum VM protection is not executable and this is the reason why gdb is unable to access the memory. The fix is as simple as fixing the maximum protection to RWX (modify hex value to 8). That’s quite a nice anti-debugging trick I don’t remember every seeing before. Hat tip to you HackingTeam ;-).

Looking at the dropper code and comparing with older samples and we can’t spot many differences. The structure is more or less the same and the tricks still the same, so you can refer to my slides and older blog posts if you are interested in those details. The only difference is that this time the dropper only packs a single persistence binary and a configuration file. Older samples packed more stuff. In case you dumped the “_eh_frame” as I described, you can find the packed files at address/offset 0x22A4. At offset 0x22B7 we have the name of the persistency binary, “_9g4cBUb.psr“, and at 0x22D7 the folder name “8pHbqThW“. The folder where the dropper installed binaries is still the same as older samples, “~/Library/Preferences/“.
At offset 0x22F7 we have the size of the binary, 0xB5DF9, and at 0x22FB starts the persistency binary that will be installed by the dropper. At 0xB80F8 we can find the configuration file “Bs-V7qIU.cYL“. Has a size of 0x8F0 bytes (offset 0xB8138), and starts at offset 0xB813C. The configuration file as usual is encrypted.

Let’s recap what we have seen until now. The dropper is using more or less the same techniques as older HackingTeam RCS samples and its code is more or less the same. The new things we can observe is the binary using Apple’s binary protection feature and a small anti-debugging trick. Until now, nothing spectacular. Either this is an old sample or HackingTeam are still using the same code base as before the hack.

Next logical step is to look at the persistency binary we extracted from the “_eh_frame” segment. This is where the core of RCS is and should help us answer interesting questions, in particular how old is this sample. For me this was really what mattered with this sample. Once again, let’s look at its headers.
Right now you are already a mach-o expert and noticed how simple this header is. It only contains two segments and one section. This is not normal, in particular when we expect HackingTeam persistency binary to be Objective-C code as in the past.
Loading this into a disassembler and we get only a tiny amount of code, the rest is what appears to be junk code. This is pretty much a tell tale that this binary is packed. This points straight way to HackingTeam’s own packer, keypress, that can be found in the leaked source code. The easiest way to validate this assumption is to compare the disassembly with the source code. The following piece of disassembly clearly identifies this as keypress.
For legal reasons I’m not going to display the leaked source code but you can easily compare those strings and find them in the unpacker code. This is the first sample I have ever seen using their packer, which makes sense since the packer has a 2014 date and all known samples were older than that.
The packer has nothing special and you can even dump it using my readmem util (this time use the -m option to have it dump the full binary from memory). Just start the persistency binary in a vm and while it’s starting you can quickly start readmem and dump it. The alternative is to load it in gdb and find the original entrypoint and dump from there. It’s a bit of more work because gdb can’t activate breakpoints on this binary so you will need to manually patch int3 all over to get gdb to break. If you are using gdbinit you can use the int3/rint3 commands to automate this work.

With the persistency binary finally dumped we can answer relevant questions. What is the date of this sample?
The date question can be answered two ways, using the information from the configuration file (at this stage still encrypted) and from encoded version information.
The source code has a variable called gVersion that refers, more or less, to the sample data. From the source code leak we can find the latest value for this variable, 2015032101, on a commit from 9th April 2015. The gVersion value is a good approximation to the commit date and allows us to track the sample in time.

A bit of reverse engineering here and there and we can find this variable value for this sample, 0x781C294E, translating to 2015111502. BINGO! This locates this sample around October and November 2015, a super fresh RCS sample and post July hack. Never before we had such a fresh sample. And if this date is really true we have a post hack sample, meaning that HackingTeam are still alive and kicking post July hack.

The next step is to confirm this information using the configuration file. First we locate the configuration file encryption key and then decrypt it. There we can find the configuration dates for this sample, 2015-10-16, confirming that this is indeed a post hack sample. The C&C server IP for this sample is 212.71.254.212. It’s already down and I didn’t verified if it was up before starting to tweet about this sample on last Friday (honesly I don’t care much about the server side). Might have been up and was quickly brought down or was already down (or this is simply a demo but it doesn’t look like it).

The last question about this is to understand what happened to HackingTeam after the July hack. At the time they promised to release a new version that they were telling was not affected by the hack. Is this really true?
Well, if you start disassembling and comparing with the leaked source code you will see that this appears to be totally false. The sample is compiled out of the leaked source code base and I can’t see many new improvements. I can guarantee you that this sample code is coming from that code base, up to the last commit (there are probably newer commits after the leak). HackingTeam appears to have resumed their operations but they are still using their old source code for this. Of course there is a question of are they using both old and the new promised source code or were they just lying about it and resumed operations with old code since they are probably on a shortage of engineering “talent”? This is definitely a question their customers will have to ask them ;-).

Conclusions…

HackingTeam latest sample is a very fresh sample compared with what we got in the past, it is a sample created post July 2015 hack, and it’s using the same code base as before. HackingTeam is still alive and kicking but they are still the same crap morons as the email leaks have shown us.
If you are new to OS X malware reverse engineering it’s a nice sample to practice with. I got my main questions answered so for me there’s nothing else interesting about this. After the leak I totally forgot about these guys :-).

@noarfromspace made a good point that this sample could have been compiled by someone else other than HackingTeam since the source code is out. It is definitely an easier and not so sexier alternative path for this. My feeling is that while possible this is not the case. But never forget that Human biases can always lead us to the wrong path ;-).
For example, the gVersion variable appears to be manually updated on the source code repo (I can’t find any automated scripts for this) and follows the same pattern as previous versions. A definitive answer needs a bit more of reverse engineering time.

Some interesting network info provided by Charlie Eriksen tells us that the host was up at least in January and Shodan has a scan on the same day the sample was submitted to VirusTotal. References here and here.
Update: John Matherly just left some historical Shodan data. Shodan detected this host up as far as from 15 October 2015. The configuration file filters activation date start on the next day. Pretty good data out of Shodan

Looking at VirusTotal submission details we have the following:
The zip file was created on 2016-01-29 11:43:50UTC , and submitted to VirusTotal via the web interface on 2016-02-04 from Italy. Censys updated the C&C server info at 2016-01-18T19:21:09+00:00.
The dropper binary was submitted to VirusTotal twice on the 2016-02-04 from France via API.
The bundle binary that is also extracted in the target persistency folder was submitted the next day 2016-02-25 07:36:07UTC via the API from unknown country and from the installation folder /Users/user1/Library/Preferences/8pHbqThW/w1_X-Hye.gn6.