The use of runtime-packing of malware has long become the standard to defeat traditional AV products. At the same time, malicious programs are continuously becoming more evasive to avoid being detected by first-generation sandboxes. New waves of malware are now combining these techniques to combat AV and sandbox solutions alike.
In this post, we are taking a deeper look at malware used by the Darhotel APT group, and we show how the attackers use just-in-time decryption of system fingerprints to detect, and in turn evade, many security solutions. We show that full-system emulation can be used to expose the fingerprints that the attackers are trying to hide and to remain invisible to the evasive maneuvers of Darkhotel.
Evasion Via Fingerprinting
As we described in many of our previous blog posts, malware authors can use different methods to decide if they are running in an environment in which it is worth to reveal their malicious intentions, or if they may be under analysis and should thus “behave well”.
A very common way to detect a sandbox environment is through system fingerprinting: attackers analyze the host on which malware is running for signs of a security solution. If any such indicator is found, the malware program terminates to avoid revealing any of its internals.
Typical examples for such signs are programs running on the system that may be part of an analysis suite, hooks in system libraries that can be used to monitor program behavior, or kernel drivers loaded as part of the operating system to intercept and record system calls.
Leveraging Fingerprinting For Detection
Although the above list of potential fingerprint mechanisms is far from complete, it is already clear that an effective analysis solution must not have any of its components running inside the sandbox, where they are visible to the executing malware. Because of this, our sandbox runs its analysis as part of a full-system emulator, well-hidden from the attacker, outside the actual analysis operating system.
Unfortunately, assuming that an analysis solution is always able to fully conceal itself is unrealistic. Because of this, there is a constant cat-and-mouse game between attackers leveraging new ways to fingerprint a system and security solutions adapting to this.
However, there is a clear silver lining to this cat-and-mouse game: the more evasive a piece of code becomes, the more likely it is to be malicious. Thus, the longer an attacker decides to play the game, the harder the game becomes and the less likely they are to win it!
Analysis overview of Darkhotel sample showing evasive behaviors
Darkhotel Just-In-Time Decryption
The Darkhotel APT group was originally reported by Kaspersky Labs, who has been keeping an eye on this campaign for a while. A recent update of the malicious code shows an interesting new feature to counteract being detected via the malware’s fingerprinting activity: to avoid revealing any of the fingerprint details (such as strings containing process names), the malware program contains only hashed or encrypted versions of the fingerprint information.
This, by itself, is nothing new, as encrypting data is common practice for malware. What is interesting, however, is that the strings used for fingerprinting are not even decrypted with the rest of the program memory. Instead, the malware uses just-in-time decryption of strings when they are needed, and wipes any memory block containing plain-text data after it has been used. This means that standard unpacking, memory-tracking, or process-snapshotting techniques will not be successful in revealing these fingerprints, and traditional security solutions have a hard time using this data for detection.
The following code shows part of the Darkhotel fingerprinting routine, checking if a target process contains interesting exported functions: the code first decrypts fingerprint strings (in this case, the names of functions) into a temporary buffer using a custom algorithm (see Proc_Decrypt_String). Then, it checks if these functions are exported inside the target process (see Proc_CheckIfFunctionExported): a positive identification reveals the presence of an analysis system. Once the string is no longer needed, the temporary buffer is overwritten with random data (using Proc_GenerateRandomNumber) before the buffer is released. This way, plaintext fingerprint strings reside in process memory only for the absolute minimum amount of time that is necessary.
To make analysis even more difficult, the malicious code avoids passing any decrypted strings to API functions whenever possible: since analysis systems may hook these functions, the plain-text values may be recorded and be used for detecting the malware. Instead, most decrypted strings are used for string comparisons or (substring) search operations. Here, Darkhotel uses custom-built string manipulation and comparison functions (embedded directly in the malware code) which makes hooking very difficult.
The Lastline sandbox uses a full-system emulation approach. Because of this, the code decrypting the fingerprint strings, as well as the logic for checking the system for signs of a security solution, are run on the emulated CPU. This allows our solution to correctly track the use of these fingerprints, and to use them to correctly classify the Darkhotel malware.
Traditional sandboxes, on the other hand, would rely on the fingerprints to be handed off to a library function (or system call), where the analysis components can inspect the data. Darkhotel uses this weakness and avoids passing any plaintext information to the hooked API functions, leaving these solutions in the dark.
Darkhotel Fingerprint Evasions
In this section, we describe some of the fingerprints used by Darkhotel to determine if it should show its malicious behavior. Only if a sandbox is able to recognize and bypass all of these mechanisms can it expose the full behavior.
Analysis Subject: Darkhotel uses a series of checks on its program file to determine if it is being analyzed:
- Check for the length of the executable name: if the length is 32 characters, the malware exits. This tackles a common practice used by security researchers or analysis tools, who rename a sample to its MD5 before execution.
- If the filename length is greater than 8, the malware checks if the filename ends with “.Md5.exe”. Just like the check above, this detects another common practice used by security researchers and sandbox solutions.
- Check if the program is executed from the root of the C:\\ drive.
- Check if the program is launched from one of the following folders - these clearly target artifacts of specific sandboxes:
- \\AVCTESTSUITE\\ (AV comparatives automated testing suite).
Module Paths: The sample checks its integrity at runtime, since some sandboxes monitor behavior from user mode by injecting a DLL into the program address space. This evasion attempts to detect sandboxes by checking the path of all code modules loaded in memory:
- It calculates the hash of each module name and compares it against a hardcoded list of hashes.
- It checks if any module path contains one of the following strings:
Parent Process: Similar to the program module integrity check, Darkhotel applies the same checks on its parent process (the process triggering its execution) by hashing the parent process name and checking it against a hardcoded blacklist of program name hashes.
AVAST: Darkhotel specifically checks for the presence of the sandbox protection offered by Avast Antivirus. It does this by checking the presence of the following libraries in the process memory:
AV Process Check: The malware enumerates running processes on the system, and it checks if any of the programs belong to known AV software by comparing the executable names against a hardcoded list.
Window Check: The malware checks for programs with GUI windows using the following names:
- "START_PROCESS.PY" (used by Cuckoo sandbox)
Program Version Information: Darkhotel enumerates running processes on the system and creates hashes based on the version information for each executable. Most Windows executables contain a resource listing company name, filename, file description, internal name, etc. Darkhotel uses this information, specifically file description and company name, by hashing the data and comparing it against a hardcoded list of fingerprints.
Exported Functions: The program enumerates all modules loaded as part of the current process. It checks if any of the below functions exist in the modules’ export tables, allowing the malware to detect sandboxes that work by injecting user-mode libraries or that use dynamic binary instrumentation (DBI) frameworks:
- "SbieDll_RunSandboxed": Sandboxie user mode hooking DLL
- “hook_disable_retaddr_check": Cuckoo user mode DLL
- “PinWinMain": PIntool (Intel PIN) DBI
- “dr_app_running_under_dynamorio": Dynamo RIO DBI
Named Pipes: The Cuckoo sandbox makes use of a named pipe called \\\\.\\pipe\\cuckoo and can thus be detected by the presence of the pipe.
Mouse position: Darkhotel repeatedly checks for the position of the mouse cursor on the screen. If the cursor remains at the center of the desktop, it is unlikely that a real user is using the system. Because of this, most sandboxes periodically move the mouse cursor or perform some other type of interaction with the desktop.
Username: The malware compares the username of the active account against the following list:
File System: Darkhotel checks if any of the following files exists:
- "\\Documents and Settings\\Administrator\\Desktop\\AVCTestSuite\\AVCTestSuite.exe"
Darkhotel Sandbox CPU Evasions
In addition to the string-based fingerprints mentioned above, Darkhotel uses a set of checks against the CPU to find environment anomalies.
Timing Check / Sleep Patching Detection: Darkhotel checks if an analysis system may be tampering with the system clock, a common technique to evade analysis systems:
- First, it checks whether the GetTickCount function behaves at it should. More specifically, the code checks if the function returns different values over time and enters an infinite loop if not.
- In the next step, the malware code reads the system time using a WMI query and extracts the seconds-part from it. Then, the code sleeps for 4000 milliseconds, followed by another query to the system time. If the difference is less than 3 seconds, the code assumes the time has been tampered with - for example, the sleep has been patched or skipped.
This is an effective and well-known trick, as we documented in our previous post on inverted timing attacks.
Processor check: The malware checks the CPU model of the system to identify sandboxes:
- The code checks if it is executing on one of the following processors, and refuses to run if one of these is found:
- Intel(R) Core(TM)2 CPU T7200 @ 2.00GHz
- Intel(R) Xeon(R) CPU L5640 @ 2.27GHz
- Additonally, it queries the processor name via the Windows registry as well as the CPUID instruction. If the two values don’t match - for example, because a sandbox intercepts and manipulates these values - the malware assumes it is running in an analysis sandbox.
Interestingly, this specific check has a buggy implementation in the Darkhotel variant we looked at for this post: while the values are checked for consistency, they never lead to the malware to terminate - even on a vulnerable sandbox:
Advanced malware is becoming more evasive to avoid being detected by analysis sandboxes. Darkhotel uses a huge arsenal of system fingerprints, trying to determine whether it is running inside an analysis environment, and it avoids revealing its malicious behavior if a sandbox is detected. To avoid leaking details about the fingerprints it uses to identify sandboxes, Darkhotel uses just-in-time decryption as well as hashing of strings.
By using full-system emulation, the Lastline sandbox is able to identify system fingerprinting, even when strings are not being passed to any library functions and only live in memory for a very short time.
Thus, the system can circumvent the evasive checks. Even more, it can use them to classify the Darkhotel malware, as the number of evasive behaviors clearly distinguishes this code from benign programs.