Future Malware Analysis
The sample starts by rigorously checking its environment. If in a sandbox or under manual inspection by an analyst, the sample will prematurely terminate. If the sample finds specific antivirus software installed, it will carefully enable and disable specific functionality to evade behavioral detection.
In many situations, the sample will distance itself from malicious behaviors by
invoking cmd.exe to do its dirty work. For example, modifying sensitive registry values are done by invoking cmd.exe /c reg.exe …. Unfortunately for this sample, SentinelOne tracks the full context of processes to determine the root cause of malicious behavior.
From this point on, the sample’s goal is to remove any antivirus software before running its final payload. To accomplish this goal, the sample must be run as administrator. Two known local privilege escalation exploits are included in the sample (CVE-2014- 4113 and CVE-2015-1701), as well as one UAC bypass, which are used to acquire administrator access. As a last resort, the sample will use a UAC prompt to try and elevate itself to administrator. Once the sample is running as administrator, it will add the current user to the local Administrator group, allowing it to maintain administrator access in the future.
The sample now writes its Native Application binary to disk. Unlike regular application code, this binary can only link to ntdll.dll. It will run at a point in the boot-up process where some Windows subsystems are not yet initialized, and therefore can not call into normal dlls like kernel32.dll and user32.dll. This Native Application is hidden in an NTFS Alternative Data Stream (ADS) at the path C:\Windows\Temp:1. By using ADS, the file will not be visible by normal file browsers, like explorer.exe. The Native Application is registered to run on boot-up altering the values SetupExecute and BootExecute in the registry key HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\\.
To ensure the success of the Native Application, the sample will remove all filter drivers from running after reboot by removing their associated registry entries. Filter drivers are use by anti-virus software to intercept file and network access to run static detection on the contents of the traffic. These drivers are loaded early in the boot process, and could interfere with the execution of the Native Application.
The system is now forced to reboot, allowing the Native Application to run. The Native Application also has similar checks to tell if it is running in a sandbox, and will terminate prematurely when one is detected.
Remove AV goal
The Native Application’s goal is to remove any anti-virus software that is installed on the system and drop its final payload. By running during the boot process, and after the preparation that was done in the previous stage, the Native Application has full control over the system. Removing any anti-virus is trivial at this point because the anti-virus software is not running. The Native Binary writes the final payload of the sample to disk under the filename rdpinst.exe and registers it to be run later in the boot process by creating a registry value in\Registry\Machine\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce.
Structure
There is one large structure that is allocated on the heap. This structure contains mostly function pointers to external libraries and internal function pointers. This creates a problem for static analysis. There are many indirect calls (e.g. CALL EAX) obscuring the program flow for static analysis. This structure is passed as the first parameter to almost every function in the binary.
A large chunk of the .data region is encrypted using RC4. This encrypted region contains the string literals for the sample, creating another problem for static analysis and static detection. Before the process is terminated, this region is re-encrypted, possibly to deter an analyst from recovering the unencrypted contents by using memory dumps.
Included in this encrypted region are three binary blobs that are also encrypted and compressed: final payload, a Windows Native API application; A DLL with a UAC bypass; and a 64-bit executable an exploit for CVE-2014-4113.
Techniques of reversing
To reverse the main sample, I developed a python script to patch out the blacklist and NOP out some test code. By placing a breakpoint on the function that gets called to prematurely terminate the process, we were able to identify checks that failed by inspecting the return address on the call stack.
rc4 packing
The code of the main executable (.text segment) isn’t packed, but a region in the .data section is encrypted using RC4 with the password “dqrChZonUF”. The RC4 implementation looks like a direct copy of the code found in the FreeBSD and XNU kernel:
https://github.com/4R9UN/aa/blob/master/rc4.c
The only modification to the BSD RC4 implementation is the pointer to the global struct containing the function pointers to the RC4 subroutines.
After decrypting this large section, all the string literals are uncovered.
Zeroing out the relocation size in the PE Data Directory also made jumping between IDA and OllyDBG easier because the base address of the executable was not randomized.
Noting the destination address of indirect jumps in IDA comments made reviewing after debugging much simpler.
To debug the Native Application binary, I patched the PE Optional Header field Subsystem field from 1 to 2. This changed the subsystem used by the binary from Native to WindowsGUI. This will let the binary run after bootup is finished, instead of getting this error message:
Also, there are other regions inside of this decrypted region containing more encrypted blobs, like a Matryoshka doll. These contain a Native executable, the UAC bypass DLL, and the 64-bit implementation of the exploit for CVE-2014-4113. Furthermore, the Native binary contains another binary blob that is the compressed and encrypted final payload.
Although RC4 isn’t an esoteric stream cipher, the decision by the author to use such a cipher shows a level of sophistication not seen in typical crime ware.
Anti-Debug - Anti-Sandbox - Anti-AV
an overwhelming number of checks to determine if it is in a sandbox, or if an antivirus application is installed. But why would the author go through so much trouble to evade sandboxes and AV products?
The strategy used by the author seems to be this:
If we are running in a virtual machine, sandbox, or under manual inspection by an analyst, encrypt the .data section and terminate prematurely.
If we are in an environment with Anti-Virus products installed, carefully enable and disable behaviors of the infection to avoid behavioral detection.
list of checks the sample performs in the order that they are executed.
- CPUID Check
- Hostname Check
- Filename Check
- Look for DLLs associated with function hooking
- Looking for Sandbox Artifacts on the File System
- Checking Number of CPU Cores
- Yet Another DLL hooking blacklist
- Kernel Driver Check
- Anti-Process
- Is File Name [hash].exe Check
- Is VMware Tools Installed Check
- Hard Disk Vendor Check
- Misc Hardware Vendors and BIOS Checks
- Anti Network Interface Card (NIC) Check
- Window Title Check
- VMXh VMWare Check
- Direct3D Video Card Check
We will discuss in deft in next article.
To be continue .........