Despite all the advances in malware detection, the most common endpoint protection method (and pretty much the only method available to end-users) remains signature-based detection. This method relies on known malicious file hashes and regular expression-like signatures to detect malware. While signatures are by no means ineffective, they rely on malware samples having already been analyzed for signatures to be created from them, and thus new malware variants or malware hiding itself from those signatures can often be missed as a result. To this end, malware often uses a few different evasion techniques to avoid signature-based detection and sometimes even static analysis.
Obfuscation is the act of obscuring the intended meaning of something, which in the case of malware is the intended functionality of the malware. Since much of signature-based detection and static analysis relies on finding malicious actions being performed by the malware, obfuscating these can make detection more difficult.
In the case of document-based malware relying on scripts, this typically involves techniques to make the script unintelligible to analysts and software alike. An analyst, of course, would immediately spot the obfuscation and know that it is likely concealing malicious activity, but signatures rely on what’s repeated whereas obfuscation typically is generated programmatically to create as much variance as possible in the samples.
Consider the Caesar Cipher where each letter is mapped to a number, but by rotating these numbers, 26 different ciphers can be created out of the English alphabet. In terms of malware obfuscation, this would be 26 different signatures to track just for the same code snippet. Actual obfuscation schemes are not necessarily more complex than this example, but they have much higher variance than 26 outputs, allowing for too many versions of the same obfuscated code to realistically track with simple signatures. Depending on the static analysis techniques being used, it’s possible for even this to be evaded sometimes.
In some ways a form of binary-level obfuscation, packers were originally designed as a way to compress executable files to take up less space. This compression also makes it more difficult to reverse engineer the code, which is useful both to legitimate software companies to protect proprietary data as well as malware authors to make it more difficult to detect the malware and what it does.
The compressed data is extracted and executed at runtime by a loader included by the packer. From a signature standpoint, the code that does the unpacking can be detected, but because there are legitimate uses for packers this can also occasionally generate false positives if packer libraries are blocked outright by antimalware software.
It is also possible for malware authors to create their own packers to avoid signature detection and create more work for malware analysts. It is not uncommon for malware to be packed multiple times with different packers to further make detecting the actual raw content of the file more difficult.
Encryption and cryptors
While packers obfuscate code through compression, encryption completely hides the code using cryptography. Malware utilizing encryption in this way is often tagged as a cryptor. Cryptors will resolve and run the code at runtime much like packers, but instead of relying on a loader to decompress the code they can simply use a decryption process, which operating systems will have options for built in already rather than relying on the process being included in the file itself.
The cryptography library can still be included in the file if the author chooses, though, since there are a number of open source libraries available and — although it is never recommended in the world of cryptography — custom decryption code can also be used. Encryption also ensures that none of the original code can possibly be included in the binary whereas packers might end up with unobfuscated statements given how compression works.
Detecting malicious code
Hiding malicious code is by far the simplest evasion method used by malware yet it can unfortunately still be quite effective against signature and static analysis detection methods. It can also create more work for malware analysts trying to determine what malware is doing to improve detection against it.
Ultimately, all malware detection relies on finding malicious indicators, and without dynamic analysis these indicators must reside in the binary itself in order to be detected. More advanced static analysis systems can account for common packers and cryptors used by malware, but this slows the analysis process and doesn’t help when malware uses custom implementations.
You can read the rest of the Malware 101 series here.