Note to readers: PhishLabs will be represented by Paul Black at MalCon 2016 in Puerto Rico from October 18-21. At MalCon 2016, Paul will review the evolution of malware targeted at banks and financial institutions, reviewing notable trending data and methods to combat them. Contact PhishLabs for ongoing concern, questions and a deeper dive into the latest remediation techniques.
The cat and mouse game between malware researchers and threat actors operating banking Trojans began with the creation and propagation of the Zeus banking trojan in 2007. Since Zeus’s release, the number of banking trojans has increased continually, yet the anti-analysis mechanisms used by cybercriminals to obstruct researchers appear to have plateaued.
The success and ubiquity of banking trojans allow malware developers to become less concerned with complete prevention of payload analysis and more with buying time for a campaign to propagate and become profitable. The new techniques we see introduced by developers to hinder the reverse engineering of their payloads are generally simple derivations of existing reliable, established, and easy to encode procedures. We have seen the reuse of several anti-analysis mechanisms throughout our 2+ years of observation of several popular banking trojans (Zeus, Citadel, Rovnix, Vawtrak, Dridex, Tinba, GozNym). The most common being API obfuscation, packing, string obfuscation, and virtual environment and debugger detection. While these techniques have evolved slowly, they continue to achieve their goal of slowing analysis.
Figure 1: Flowchart of Malware Analysis
Historically, analysts could uncover a treasure trove of information by merely running a program known as ‘strings’ against a specific binary to find notable artifacts. The Zeus banking trojan prevents this analytic technique through the use of a table in memory to store XOR-encoded strings. This table also includes the XOR decryption key, which corresponds to each string. By implementing a table in memory to store its XOR-encoded strings, Zeus is able to limit the usefulness of the ‘strings’ tool. As ‘strings’ is executed, it attempts to locate all sequences of printable characters. In XOR-encoded form, the strings found in the malware file will appear to have an unintelligible sequence.
In addition to tabular XOR encryption keys, Zeus employs the RC4 algorithm (a well-known stream cipher developed by RSA Security) for the encryption of its configuration data. The second version of Zeus added VisualEncrypt, a moniker for a specific encoding mechanism using recursive XOR encoding. With the addition of this extra layer of complexity in v2 of the payload, the analyst will have to decipher the change occurring in the algorithm. As the malware’s campaigns and infrastructure become disrupted faster, threat actors are relying on the additional complexity of stronger encryption to expand analysis time.
Citadel uses virtual environment and debugger detection to hide from analysis. The trojan will check for any running operating system processes for the following strings:
If any such string is encountered, Citadel will connect to a randomly generated fake command and control center instead of the true command and control center. While not uncommon, conditional code logic within the malware sample hinders automated analysis as the binary looks for specific indicators that it is in an isolated environment. Many analysts may notice this communication and assume that the command and control center is either down or was never set up, stopping their hunt for the true command and control center. If Citadel does not encounter any of these strings, execution of the payload continues until the next anti-analysis mechanism is encountered. The Citadel banking trojan uses AES (Advanced Encrypt Standard, also known as the Rijnadel Cipher), in its efforts to encrypt its configuration information. The AES key used to encrypt the config is generated from the RC4 encrypted login key.
Rovnix first attempts to infect the Volume Boot Record of the victim’s machine. The Volume Boot Record is a section of code that is first initiated when the computer starts, but before Windows fully loads. Rovnix will not install its bootkit, but will run from a registry key if it finds Bitlocker, TrueCrypt or VeraCrypt full disk encryption programs have been installed. These modifications ensure the malware’s persistence, as it will run even after the victim restarts the machine. After persistence is achieved, Rovnix’s Portable Executable header is purposely corrupted during the injection of the process in such a way that causes a debugger such as OllyDbg to terminate. The impact is considerable as OllyDbg is a favorite debugging tool used by many security analysts.
Further down Rovnix’s execution path, it spins up multiple threads in an effort to find the process name and process paths for indicators of the following virtual environments:
A positive result from these checks will inform the malicious payload that execution is occurring inside of a virtual machine most likely under the review of a malware analyst. A further confirmation that something is awry is a check against the ‘BeingDebugged’ flag found in the Process Environment Block (PEB). This flag is a telltale sign of an executable being under the watchful eye of a debugger.
The latest iteration of Vawtrak downloads its configuration file upon the launch of the first browser instance. Vawtrak then waits for the launch of a second web browser to occur, where the first layer of encryption is removed from the configuration data and each target inject is decrypted one URL at a time upon visiting the alleged target’s website.
Figure 2: Flowchart of the initial Vawtrak infection.
While unraveling Dridex’s initially packed code, Dridex will attempt to call Windows API functions via an address as opposed to the function name. It calls a function that acts as an API resolver, which then returns an integer. Subsequently, Dridex dynamically returns the address of an API function that will be used during execution; this is commonly referred to as API obfuscation.
During execution, the Dridex loader will inject itself into ‘explorer.exe’. Following the injection, Dridex will use the ‘schtask’ scheduler to call reg32svr to run the dropped Dridex module. The parameters set for the schedule will cause this task to occur every 10 minutes, causing Dridex to delay loading until 10 minutes have elapsed. To find if your machine is infected with Dridex use the following query:
schtasks /query /fo list|findstr /i /c:”user_feed”
Tinba capitalizes on the isolated nature of the sandbox to evade the analyst. Researchers utilize sandbox solutions such as Cuckoo to automate the analysis of malware payloads (Step 3 within Figure 1). Within these solutions, a single payload is run on a virtual machine and observed via the sandbox’s software. By only running the payload on the virtual machine, no other software package can interfere with the mouse cursor. This is significant because Tinba takes advantage of the GetCursorPos Windows API Function. This function checks for any change in the mouse cursor’s position by comparing its previous position with its current position. No change in position would indicate the mouse cursor has not moved. Tinba also will call the GetForeGroundWindow API function to determine the user’s active window, and will repeatedly check the active window and mouse location in a continuing loop that will continue until the active window has changed and the mouse cursor position has moved.
To further evade analysis, Tinba will check the number of disk cylinders on the user’s machine using IOCTL_DISK_GET_DRIVE_GEOMETRY_EX. If there are not at least 5000 (0x1388) cylinders, or 41 GB, the payload halts its execution because this small amount of memory would more likely be allocated to an analyst’s virtual machine.
GozNym unpacks itself into rundll32.exe with a fake command argument including a randomly generated DLL filename. Referencing the example below, ‘-ya’ is the fake command and ‘abalsdf.dll’ is the randomly generated DLL filename:
Example: rundll32.exe –ya abalsdf.dll
Upon execution, GozNym will import functions dynamically at runtime via two values pushed onto the stack. This prevents the analyst from knowing which functions will be used initially by the sample because these functions are usually found in the import table. Since GozNym imports these functions dynamically at runtime, they forego the import table and avoid detection.
Any constants in memory that are used by the payload are XOR-encoded. These values are only decoded when a function is called in by the payload.
We continue to see significant trending data in the evolving world of malware targeted at banks and financial institutions. Of note, the level of complexity included in the malware samples is limited to ensuring the campaign runs for a short period of time and compromises new and unsuspecting victims. An organization can combat these threats and prevent losses by deploying and frequently updating anti-virus software, end-point protection tools and other utilities to aid in the extraction of malware configurations.
Leverage open source resources (like the PhishLabs blog and resources page) to stay up to date on current threats and best practices to protect your assets, your identity, and valuable data.