A Peek Behind the Cryptowall

A Peek Behind the Cryptowall

Bridging static and dynamic analysis using Lastline process snapshotting

Authored by: Arunpreet Singh and Dr. Christopher Kruegel  

Scareware is a type of malware that takes advantage of people’s fear of revealing their private information, losing their critical data, or facing irreversible hardware damage. Ransomware is a particular class of scareware that locks a victim’s computer and renders their files inaccessible – typically, by encrypting the files on the file system and sending the key to the attacker. Then, the victim is forced to pay a ransom to regain access.

Cryptowall is the name of a popular ransomware family, similar to the infamous Cryptolocker family. This malware encrypts a variety of files on the victim’s computer using public key cryptography (using strong 2048-bit RSA key). Once the files are encrypted, the malware presents a dialogue to the user that informs the victim about the fact that the files are no longer accessible. Moreover, it provides instructions on how to pay the ransom and obtain the private key to decrypt the files. The attackers often demand hundreds of dollars to unlock the locked files, and they create a sense of urgency by threatening to increase the necessary payments or even delete the key after a certain period of time has elapsed.

In this post, we dissect a Cryptowall sample and look under the hood of this malware threat to reveal its inner workings in more detail. We show how Lastline’s automated malware analysis exposed a range of unwanted activity right of out the box, and how the process snapshot feature built into the sandbox aided the analysis in various ways.

Unpacking the sample

Like most malware, the Cryptowall sample that we used for analysis is packed. In this case, the malware authors have leveraged a custom packer using well-known techniques: when the packed sample is executed, the sample first runs several rounds of decryption, peeling back one layer at the time until the final payload is revealed. At the end of unpacking, the code overwrites the original PE image memory with the malware payload . What makes this (fairly standard) process a bit more interesting is the presence of a trick (or maybe a bug) that makes automated dumping of the decrypted payload a little harder. Specifically, when the PE header of the original image is overwritten, the packer fails to compute the correct new offset (to the final payload PE) from the start of the section header.

Here is more detailed explanation:

1_compute_Section_header.png

As can be seen in the screenshot, the sample executes a pop instruction at 0x008C09D4 to obtain the instruction pointer (%eip) that is stored at the top of the stack.

To obtain the correct address of section_header, which directly follows a jump instruction after the pop, it should add 6 to %eax (1 for the length of the pop instruction, and 5 bytes for the jmp instruction). However, as it can be seen in the next screenshot (that shows the code that is executed after the jump), the sample only adds 3 (see the add instruction at 0x008C0A7A). One possible reason is that the programmer incorrectly assumed that the jump instruction is only three bytes long (which would be the case for a short jump, which has only a 16-bit offset).

2_section_header_copy.png

Because of this discrepancy between the actual and the computed value, the start address of section_header is considered to be at 0x008C09D7 (which is in the middle of the jump instruction, three bytes before the actual location). This breaks some of the automated dumping/unpacking tools that rely on (blindly) parsing the PE headers to dump the image as in memory. Specifically, these tools will fail to recognize the section as valid PE, since many fields will no longer contain valid values.

In Lastline’s analysis environment, we take memory snapshots at different stages of the execution and do not simply rely on parsing the PE image from memory. As a result, we are not affected by this trick, and the unpacked malware payload (file) is correctly provided in the exported snapshots. Memory snapshotting also enables us to detect the activity over overwriting the original PE image with a new one. More precisely, we detect this activity as “wiping PE Images from the memory,” as one of many behaviors shown in the analysis overview of the analysis report:

3_llama_detection.png

In the rest of this post, we will accompany description of the Cryptowall behavior with screenshots based on the process snapshots.

Analyzing the unpacked sample

As a first step, the sample resolves the addresses of all the API functions that it needs to call later. This is done by using a list of hashes, one for the name of every API call. In this way, the malware does not have to use an import table or store API names directly as strings, which could help antivirus solutions to recognize the malware.

In the next step, the malware produces a machine identifier (we refer to this identifier as the system_info_hash). To this end, the code computes the MD5 hash of the following pieces of system information:

  1. ComputerName
  2. UserName
  3. SystemDrive serial number
  4. CPU INFO (using PROCESSOR_IDENTIFIER)
  5. Number of CPUs (using PROCESSOR_Level)
  6. Revision Number of CPU (using PROCESSOR_REVISION)
  7. OS Major version
  8. OS Minor version
  9. IsWow64
  10. Keyboard Layout

After that, the malware creates a second MD5 hash system_info_network_hash, which is created by combining a hardcoded string (which, in our case, is “crypt”) with the just-computed system_info_hash as well as a information about the C&C network configuration (Network_Info_structure, described in more detail later).

4_Cryptowall_Info_struct.png

Additionally, the malware also gets information on OS version, WOW64 status, and whether the current user has administrative privileges as shown in above screenshot. Together with the calculated hashes, this information is stored using the following structure:

Crytptowall_Info
{

   char * hardcoded_string;
   size_t hardcoded_string_len;
         char *system_info_hash;
   size_t system_info_hash_len;
   int unknown;
   char *system_info_network_hash;
   unsigned int OSCode;
   unsigned int Wow64Status;
   unsigned int IfAdmin;
}

Injection into explorer.exe

After the initial setup, the malware injects itself into the explorer.exe process and continues its malicious activity in this new context. The injection is done using a variation of the standard process hollowing technique: instead of replacing the original code of explorer.exe, the sample creates a new section in the target process and copies the malware image, relocating the code to the new section base address accordingly. Thus, the section mapped into explorer.exe is the same unpacked malware program, merely executed with a different entry point (and the execution is achieved using ZwQueueApcThread).

The main goal in this phase is to achieve persistence and hide the tracks of the original malware process. To this end, the malicious program is copied into the %appdata% directory using characters 9 through 18 from system_info_network_hash as name. Then the sample creates a registry entry under HKEY_USERS{UserSID}SOFTWAREMICROSOFTWINDOWSCURRENTVERSIONRUN for the newly created file, causing the malicious code to be run on each boot. Last, the code terminates the primary malware process and deletes the original file from disk.

The malicious code attempts to delete and disable the system restores by carrying out the following steps:

  • Delete previous restore points by calling SRRemoveRestorePoint. This function takes as argument the number of the restore point to be deleted. The code attempts to delete the previous one thousand restore points by invoking SRRemoveRestorePoint with arguments from 0 to 999.
  • Disable the system restore by setting the value “DisableSR” to 0 in the registry key  (HKLMSOFTWAREMicrosoftWindows NTCurrentVersionSystemRestore)
  • Call vssadmin.exe with the following arguments to delete any shadow volume copies: 
    vssadmin.exe Delete Shadows /All /Quiet

Injecting code into a foreign process triggers the generation of a process snapshot. This allows an analyst to download the malware code that is running in the context of the hollowed process (explorer.exe). Further, as we describe in a previous post, the snapshot only contains the relevant (malicious) parts of the code, allowing to focus on the relevant parts quickly.

The following screenshot shows part of the restore-point removal described above:

5_remove_system_restore.png

 

Injection into svchost.exe

Our analysis continues in the context of svchost.exe. Again, the malware injects its code into a new process by adding a new section with the original malware code. And, again, a different entry point is selected to invoke a different malware functionality. 

After the malware has previously made itself persistent and covered its tracks, it is now time to carry out the intended malicious functionality. As the first step, the malware checks in with its miscreant operators. 

To phone home, the Cryptowall samples store a hardcoded list of command and control servers. This list is first compressed (using RtlCompressBuffer) and then encrypted using RC4. These steps are executed in reverse order (first decryption, then decompression) by the function DecryptNetworkConfig, using a hardcoded RC4 key embedded in the binary. Reversing this function (whose disassembly is partially shown in the screenshot) shows that the sample stores its network/C&C configuration using the following structure:

Network_Info_structure
{
      char rc4_key [];
  size_t  data_size;
  byte  encrypted_data[data_size];
}

Now we wrote a simple IDA Python script (formatted version) that can be used to decode the information from the data extracted from the process dumps.

6_LLAMA_Svchost_C_C.png

Running this script on our sample yielded the following C&C list:

abelindia.com/1LaXd8.php
purposenowacademy.com/5_YQDI.php
mycampusjuice.com/z9r0qh.php
theGinGod.com/HS0ILJ.php
yahoosupportaustralia.com/8gX7hN.php
successafter60.com/iCqjno.php
alltimefacts.com/EiFSId.php
csscott.com/YuF59b.php
smfinternational.com/eRs70a.php
lexscheep.com/OIsSCj.php
successafter60.com/r_kfhH.php
posrednik-china.com/etdhIk.php
ks0407.com/VoZQ_j.php
stwholesaleinc.com/yL54uH.php
ainahanaudoula.com/GH09Dp.php
httthanglong.com/yzoLR7.php
myshop.lk/6872VF.php
parsimaj.com/60wEBT.php
kingalter.com/uVRfPv.php
shrisaisales.in/ZUQce4.php
cjforudesigns.com/E8B2gt.php
mabawamathare.org/WEAbCT.php
manisidhu.in/zJE0fD.php
adcconsulting.net/XEGeuI.php
frc-pr.com/dA91lI.php
localburialinsuranceinfo.com/zDJRc8.php
smfinternational.com/AYNILr.php

Our script can be used to extract the C&C info from any Cryptowall 4.0 sample with little modification. This is very helpful to quickly extract any new command and control information when new samples are caught in the wild, producing valuable threat intelligence. Also, since the Lastline sandbox already exports all needed memory dumps and makes them available via APIs, the script can be invoked whenever the system finds and analyzes a new Cryptowall sample.

Network communication

Once the list of C&C servers have been decoded, it is time to connect. However, Cryptowall does not send information in clear text. Instead, a simple protection layer is used. To establish this protection layer, the sample first selects a random number between 10 and 15, which is used as the length for a randomly generated RC4 key. The characters of this randomly generated key are then sorted to derive a second RC4 key. Using this second key, the sample encrypts

  • the hash identifying infected client (as discussed above),
  • OS version information,
  • information whether the processor is running in 32-bit or 64-bit mode, and
  • whether the malware is running with administrative privileges (which the code gets by checking the process SID)

using the following schema:

{1|hardcoded_string|system_hash|os_code |wow64_status |admin_status}

The first (randomly generated key) is simply included as a POST parameter of the HTTP C&C request, which follows the format:

server_url/?(random number [a-z]) =  Unsorted RC4 key

The key is included so that the server can extract the transmitted data. It is also used to encrypt the response back to the sample.

If the C&C server is up, it responds with the following information (again, all encrypted using RC4):

unique_id | attacker base domain | country code | payment addresses separated by “~” | public key | image (To be shown to user after infection)

7_decrypted_traffic.png

The public key downloaded from the server is used to protect the key that is later used to scramble the files on disk.

The payment addresses are shown to the user as part of the ransom process where payments need to be made to the attacker. The image is unique for every user and contains instructions for how to pay the ransom (and recover the encrypted files):

[attacker domain].[payment gateway]/[user unique id]

8_crytpwall_page.png

 

File Encryption

Once the sample has received a response from the C&C server, it is time to start encrypting the files on the victim’s machine. To this end, the malware first creates a random AES key, using local Win32 APIs. Using this AES key, it encrypts the files (including filenames) on the victim’s machine. As part of the encryption process, the malware also adds some metadata to each encrypted file (in particular, a hash of the public key, and the AES key encrypted with the public key). Once the files are encrypted, the AES key is purged. This makes it impossible to retrieve the decryption key from the local machine.

When the victim pays her ransom, she gets access to the private key that corresponds to the public key that was used to encrypt the AES key. Using the private key, the AES key can be decrypted (which is stored as metadata with each file). Using the AES key, the files can be restored.

It is interesting to observe that the malware checks the keyboard layout before starting the file encryption process:

9_keyboard_blacklist.png

When the keyboard layout belongs to one of the following entries, the malicious activity is not invoked.

Russia
Kazakh
Ukrainian
Uzbek – Cyrillic
Uzbek – Latin
Turkmen
Belarusian
Azeri – Cyrillic
Azeri – Latin
Armenian
Tajik
Kyrgyz – Cyrillic
Georgian

Similarly, the malware also checks a CRC32 sum of the victim machine’s country code against a list of hardcoded country values. More specifically, the malware retrieves the country-code from the C&C server (most likely based on the client IP), generates the CRC32 sum, and compares this to a list of country code sums hardcoded in the malware binary:

10_country_code_crc32.png

Once again, when a match is found, no files are encrypted.

Summary

As we show in the overview of the analysis report, Lastline detected and highlighted all relevant Cryptowall behaviors of the sample. One can see the behaviors related to making the sample persistent, the injection of code into legitimate processes, the stealth activity to hide the sample’s tracks, suspicious network activity, and the encryption process that is seen as a process iterating over a large number of files in the file system.

At the same time, process snapshots are taken at various interesting points throughout the execution of the malware programs. This allows for deeper manual malware analysis by security researchers.

Both features – the deep insights into behavior of malware executing in the sandbox as well as extraction of forensic metadata – are made possible through Lastline’s full-system emulation (FUSE) sandbox and allows the detection of previously unseen malware.

Arunpreet Singh

Arunpreet Singh

Arunpreet Singh is a Malware Reverse Engineer at Lastline. Prior to joining Lastline, he worked as a Security Researcher for McAfee. His research interests are malware reversing and window internals.
Arunpreet Singh