1. Executive SummaryA delayed execution of a compressed or crypted executable may cause memory scanners as well as file scanners using a generic unpacking engine (emulation) to scan a file while it is still encrypted. This will result in a signature mismatch so that malware becomes undetected.
2. BackgroundWe assume that (i) certain on-access memory scanners try to scan an executable file immediately after its execution in order to reduce the time span in which malware can perform harmful activities or cloak itself, (ii) certain on-access memory scanners scan an executed file only once in order to minimize the scanner's impact on system resources, (iii) generic unpacking engines are slower than static unpacking engines and, therefore, must stop the emulation of a compressed or crypted file after a certain time period has expired, (iv) generic unpacking engines generally try not to emulate non-encrypted files.
Against this background, we asked ourselves what will happen if an encrypted/compressed executable firstly performs a few instructions and then stops its execution for several seconds before it proceeds to unpack/decrypt itself into the memory. Will this behavior cause a memory scanner or generic unpacking engine to scan the file before it is decrypted? If yes: will the scanning of an encrypted file simply result in a signature mismatch so that the scanner effectively becomes blind or are there any fallback systems like clever heuristics that come into play?
3. Test ProcedureWe took a few compressed/crypted malware samples (Bionet, Lithium, Optix Lite & Optix Killer) from our test archive. Subsequently, we modified these compressed/crypted samples so that the decompression/decryption procedure is delayed:
(a) Original Trojan Samples
Bionet 3.18 (crypted with Netwalker)
Lithium 1.03 (compressed with PeX099)
Optix Lite 0.4 (compressed/crypted with UPX, PeX099 or Netwalker)
Optix Killer 3.0 (compressed with PeX099)
(b) MessageBox Variants
The MessageBox variants contain additional instructions displaying a message box. The file will not be decompressed/decrypted before the OK Button of the message box is pressed (i.e., the message box allows to "simulate" a stealthy decompression/decryption delay).
In order to use the message box function we added the required imports from user32.dll or, alternatively, we "hardcoded" the respective function into the file (such samples will only run on Windows XP SP2). Moreover, we changed the original entry point of the compressed file so that it directs to a "cave" (i.e., an empty region of the file which does not contain any relevant data). At the location of the new entry point the instructions displaying the message box are located. After the respective instructions are performed a jump directs the execution flow to the orginal entry point where the file will be decompressed/decrypted as usual by the relevant decompression/decryption stub.
(c) Sleep Variants
The Sleep variants are more dangerous than the MessageBox variants and come very close to a "real world" threat (e.g., a compressed rootkit that uses a decompression delay in order to bypass on-access memory scanners or emulations until it had the chance to cloak itself so that it becomes entirely invisible). The executed sleepy variants are not decompressed/decrypted until they had a good night's rest (i.e., the execution of the file is delayed for a few seconds before the instructions of the decompression/decryption stub are performed).
In order to use the sleep function we added the required imports from kernel32.dll and proceeded in the same way as described above under (b).
(d) Sleep.WSA Variants
In addition to the sleep function these variants contain a few instructions that may be used to fool a generic unpacking engine (i.e., very basic anti-emulation code). More specifically, we used instructions that are generally not performed prior to the decompression/decryption of a packed/crypted sample so that an emulation may come to the conclusion that it deals with a file that has already been decompressed/decrypted. In such case, the emulation may stop and the scan engine may be unable to match the sample with its signature database. This will depend on whether code-based signatures or alternative detection methods (e.g., heuristics or signatures taken from the resource section) are used.
(e) Brute.Loop Variants
These variants are based on the Sleep.WSA variants or, respectively, the original compressed samples. The Brute.Loop variants repeat thousands of "redundant" instructions before the PeX decompression stub is processed. The idea is to exploit the speed disadvantage of generic unpacking engines (i.e., because an emulation is much slower than a real computer it may have to stop the emulation before the unpacking stub is reached). The Brute.LoopC variants do not require a change of the original entry point or added imports. Starting from the original entry point the execution flow is simply directed to a loop and then redirected to the unpacking stub.
The modified trojan variants were scanned with the help of various file and memory scanners. In addition to the modified variants we also scanned the original, uncompressed samples and non-modified, compressed/crypted samples. (This is to make sure that a scanner does not have any general problems to detect the particular trojan or handle the relevant packer/crypter.) In order to test the capabilities of an on-access scanner it was necessary to execute the test samples.
Please note that we did not further modify the variants. In particular, we did not rebase or encrypt the samples (or otherwise complicate their detection).
We do not describe the above test procedure (i.e., the creation of the modified variants and the tools used for adding imports, calculating jumps, assembling instructions etc.) in more detail because this is not a hacker site. We would like to mention, however, that it takes only a few minutes (or even less time) to modify a trojan in the above-described ways (i.e., we are not talking about complex code but only about 2-7 instructions and a few additional mouse clicks). Even inexperienced attackers may be able to replicate the above-described steps (and combine them with other anti-detection techniques).