A Brief Examination of Hacking Team’s Crypter: core-packer.

Update: Jos Wetzels just released an awesome blog post which analyzes weaknesses in core-packer’s cryptography. Jos Wetzels uses these weaknesses to build a proof-of-concept which defeats core-packer’s protection.

It is EASY to bypass commonplace protection systems such as antivirus systems - David Vincenzetti, CEO of Hacking Team

In this blog entry we investigate how Italian malware vendor Hacking Team obfuscated their malware, specifically the custom software they developed for this task called core-packer. This analysis was a joint project between Will Cummings and Ethan Heilman.

In July 2015 Hacking Team’s source code and internal documents were leaked online by Phineas Fisher after compromising their network. When source code from the leak was posted to github we decided to exercise our curiosity about the techniques they used to obfuscate their malware. The Hacking Team leak provides a rare and topical view into the world of malware vendors catering to repressive governments.

What are Packers and Crypters?

Packers and crypters are tools which alter malware to frustrate signature based Anti-Virus detection and analysis. They are a crude form of software camouflage.

Packer refers to the fact that a packer uses compression to “pack” an executable into a smaller size. Sometimes this is used solely to reduce file size, but for malware this packing serves a second purpose of making the malware harder to detect and analyze. Crypters provide a similar anti-analysis function but use encryption instead of compression. Both Crypters and packers wrap the malware so that when it is run, it is unpacked or decrypted. This behavior is similar to how a self extracting zip file works, except that this de-obfuscation process happens only in memory, whereas self-extracting zips write the uncompressed contents to disk.

To de-obfuscate the malware once it is run, a stub is added to the obfuscated program. The stub contains all the necessary instructions and cryptographic keys to unpack or decrypt the obfuscated program. When an obfuscated program is run, the stub is run first. Once the stub finishes unpacking/decrypting the malware, the stub passes control to the now de-obfuscated program. The stub is often looks innocent since it only performs a single task.

In the graphic below, we show how a crypter can be used to bypass an Anti-Virus scan for malware.

The idea behind both of these techniques (packing/crypting) is to make it difficult for anti-malware tools to inspect the obfuscated program without running it. Modern Anti-Virus (AV) will attempt to automatically unpack malware, emulating its execution until the malicious payload is revealed and can be scanned. Crypters can include methods to bypass this, some more sophisticated than others: some authors will simply delay decryption of the payload long enough that it becomes impractical for the AV to perform this type of dynamic analysis.

What is core-packer?

Core-packer is a crypter developed by Hacking Team (while core-packer bares the name “packer” it is in fact a crypter). Core-packer can be compiled to both a 32-bit and 64-bit windows executable. The behavior of the 32-bit and 64-bit versions differs, the 32-bit version obfuscates executables, whereas the 64-bit version is only capable of handling DLLs.

Core-packer in Four Steps:

The target exe, is the malware which the packer is obfuscating. The core-packer source has been posted to github. We will be linking to relevant lines of code. Our analysis focuses on the 32-bit core-packer crypting an executable, some of the steps are different under other configurations (64bit, DLLs). The last commit to core-packer was Sept. 2013, so they may have phased it out in favor of off the shelf solutions.

Step One: Stub Extraction. Core-packer has the stub compiled into itself. Upon being run core-packer searches through its process memory to find the stub (named pUnpackerCode in the source code). It identifies the stub code using one of four section names depending on configuration: peexe32, peexe64, pedll32, pedll64.

Once it finds the stub it extracts it so that it can perform step two.

Step Two: Stub Injection.

Core-packer loads the target exe into memory and injects the stub into the target exe.

Step Three: Encrypt Target Exe’s Data and Executable Sections.

Core-packer computes a random encryption key. It then uses this key to encrypt all the executable and .text sections inside the target exe (making sure not to encrypt the stub). The packer uses the TEA cipher if the target is an exe, or RC4 if it is a DLL. It later saves this key into the stub so the stub can reverse the encryption.

Using binvis.io we visualize before and after entropy levels of the malware (shown below). The encrypted sections have a high level of entropy and appear as bright purple.

Step Four: XOR-Encrypt the Decryption Code in the Stub.

Encryption code inside of an executable can be a sign that it has been crypted which in turn is suspicious. To obfuscate the decryption code, core-packer encrypts the TEA decryption code inside the stub by xoring all the bytes with 0x66.

Additional Obfuscation Techniques:

Another common technique seen in core-packer is the use of GetProcAddress to obscure function imports. GetProcAddress is a Win32 API call which given a module and a function name will return the address of the named function. By using GetProcAddress to “import” suspicious functions such as VirtualProtect, malware authors can break detections. The string literals used to look up these functions can be easily signatured, forcing the author to add another level of obfuscation, for example polymorphic string encryption. Hacking Team went down a less sophisticated path: in one case, core-packer emits a number of ASCII strings into the code section and uses a bespoke function to retrieve them. The core-packer code includes numerous instances of commented-out GetProcAddress calls with type defs for function pointer to Win32 calls.That many of these lines are commented out is an indication that they may have moved away from this technique.

How was Core-Packer used to Bypass Anti-Virus Detection?

Core-packer’s first commit is Oct 2012, nine days after Citizen Lab released a report “Backdoors are Forever: Hacking Team and the Targeting of Dissent?” on Hacking Team’s malware. It seems likely that core-packer was developed to prevent future disclosures by increasing the stealth of Hacking Team’s malware. In fact in response to the Citizen Lab they wrote talking points to assure their clients that malware was safe to use. One of these talking points was that they were implementing “technical measures”, perhaps referring to core-packer.

[..]next release will introduce technical measures to lessen the chances of such a scenario happening again - Re: news

Looking through the leaked emails we see several discussions of Hacking Team’s malware being discovered by Anti-Virus and taking actions to evade this detection. For the sake of brevity, we will look at one one example.

On April 24, 2013 Hacking Team malware support received the following email:

Good morning, in invisibility report for version 8.3 is ESET Smart Security reported as antivirus where RCS is working. But, today customer tryied to install it on computer with ESET and installed agent was detected by this anitivirus. [..] Will there will be available some fix for ESET software? - Subject: IUQ-855-32679: ESET Smart Security: Invisibility broken, To: rcs-support@hackingteam.com

April 29th 2013 a member of Hacking Team changed a pointer in core-packer with the commit message “bypass ESET Win32/Kryptik”(as shown above). It appears the intention of this change was to break the signature that ESET Anti-Virus scanner was using to detect the malware. Win32/Kryptik refers to a codename given to Hacking Team’s malware by Anti-Virus vendors.

May 2, 2013 another change was made to core-packer to alter the way in which the string ‘VirtualProtectAlloc’ is called, this change had the commit message “patch in DllEntryPoint to bypass ESET Win32/Kryptik. ??”.

On May 10, 2013 the Hacking Team support ticket tracking the ESET detection is updated to read:

Hiding enhancements for ESET was introduced in new installed release 8.3.3. I hope, problem is solved. - IUQ-855-32679: ESET Smart Security: Invisibility broken

Soon after the support ticket was marked closed, evidently because the issue was resolved.

Conclusion:

We have provided a brief sketch of Hacking Team’s core-packer and some of the techniques used. We also took a brief look at one episode in the cat and mouse game between malware vendors and Anti-Virus vendors. The Hacking Team leak suggests that while the current detect and flag strategy employed by Anti-Virus can be a nuisance to malware vendors, malware ultimately has the upper hand. This is not to say that Anti-Virus vendors could not adopt more effective strategies, we believe in fact that more effective strategies exist, but that the status-quo favors malware.

In our next blog entry we will use the Hacking Team files to develop a simple game modeling the AV and Malware dynamic and look at alternative strategies.

Other Resources on Hacking Team:

Much of our analysis was performed by staring at the source code. In light of this, if you discover any errors or details you would like to see included please let us know at @Ethan_Heilman and we will give credit for the correction or addition.

Appendix

How to build and run core-packer: After some work we were able to build and run core-packer. Based on the project files left by the authors, we found that core-packer was built with Visual Studio 2010. We were unable to get a freeware copy of Visual Studio 2010 but 2012 worked. The project will not compile on later versions of Visual Studio without some trivial code modifications.

Testing the packer on random exe’s and DLLs caused the packer to crash, but when run against binaries compiled by Hacking Team (available at DUMP_ROOT/rcs-dev%5Cshare/HOME/Ivan/full_themida_core/windows/), such as their scout or soldier malware, core-packer ran without issue. Note that the 64-bit version of core-packer appears to only work on DLLs and not exes. All our tests were performed against the 32-bit version of core-packer.

See image below:

Core-Packer May Have Violated the GPLCore-packer uses source code from the distorm project licensed under the Gnu Public License or GPL. The GPL requires that if a software project includes GPL software, that project must distribute the source code when they distribute the compiled software. Thus, by infecting someone with malware protected by core-packer without also including the source, they may have violated the GPL. It is possible thatt when their source code was posted to github they became GPL compliant.