Same Zeus, different features

2013-10-10

Raul Alvarez

Fortinet, Canada
Editor: Helen Martin

Abstract

We have seen hundreds, if not thousands, of variations of Zeus in the wild. The main goal of the malware does not vary, yet different functionalities have been added over time. Raul Alvarez takes a detailed look at some of those functionalities and shows how Zeus does things slightly differently from other malware.


We have seen hundreds, if not thousands, of variations of Zeus in the wild. The main goal of the malware does not vary, yet different functionalities have been added to its different iterations over time.

This article discusses some of Zbot’s functionalities in detail, such as: dropping a copy of itself and its components using random filenames, generating the registry key and some of its mutexes, and injecting codes with an anti anti malware trick. These functionalities are common in malware, but we will look into the details of how Zeus does things slightly differently.

Paths and folders

We will not discuss the details of the malware’s initial decryption algorithm, since several existing write-ups focus on them. However, we will look at some of the decryption algorithms that the malware uses while performing its malicious activities.

Zbot starts preparing the path and folders for its file manipulation functionalities using the SHGetFolderPathW API. The malware gets the Windows folder name using the SHGetFolderPathW API with the parameter (0x24) CSIDL_WINDOWS, also known as the ‘FOLDERID_Windows’ parameter. CSIDL_WINDOWS generates the name of the Windows directory or SYSROOT, also known as %windir% or %SYSTEMROOT%, respectively. Then it uses the PathAddBackslashW API to add a backslash (\) to the resulting Windows path name.

This is followed by getting the volume GUID (globally unique identifier) path of the Windows folder using the GetVolumeNameForVolumeMountPointW API. I

f a call to the GetVolumeNameForVolumeMountPointW API fails, the malware will remove the backslash from the Windows folder name using a deprecated PathRemoveBackslashW API. It also removes the last element of the Windows path name using the PathRemoveFileSpecW API, producing just the root folder, e.g. ‘c:\’. Then it makes another call to the GetVolumeNameForVolumeMountPointW API using the root folder.

A successful call to the GetVolumeNameForVolumeMountPointW API will yield a result such as ‘\ \ ? \ V o l u m e { 3 e a 9 a 7 c 1 - 3 4 5 3 - 1 1 a a - a 0 a d - 8 0 6 d 6 1 7 2 6 9 6 a } \’, where the CLSID has been extracted using a call to the CLSIDFromString API.

To obtain the path that contains application-specific data, Zbot once again uses the SHGetFolderPathW API with the parameter CSIDL_APPDATA (FOLDERID_RoamingAppData), which typically yields ‘C:\Documents and Settings\{username}\Application Data’. In order to remove any excess backslash symbol(s), the malware calls the PathRemoveBackslashW API.

Last section

After setting up the required paths and folders, Zbot looks for the ‘.reloc’ section of the current decrypted module by parsing the section names from the PE header.

Zbot copies (0x504) 1,284 bytes of encrypted code to the stack memory and uses a simple XOR decryption algorithm. Each byte is XORed using another byte taken from a different memory block. It masks the whole 1,284 bytes of encrypted code using another 1,284 bytes of key code (see Figure 1).

The .reloc section contains some information needed by Zbot for some of its malicious activities.

Partial view of the .reloc section.

Figure 1. Partial view of the .reloc section.

Random generator

Before we go any further, let’s discuss the random generator used by Zbot to produce the random filename, folder name and registry keys.

The seed value for the random generation algorithm is taken from the result of calling the GetTickCount API. There are two different sets of instructions that generate a list of random values.

The first set of instructions, let’s call it ‘Randomize 1’, is as follows:

   CALL GetTickCount
START:
   MOV  EDX,DWORD PTR DS:[EAX]
   MOV  ESI,EDX
   SHR  ESI,1E
   XOR  ESI,EDX
   IMUL ESI,ESI,6C078965
   ADD  ESI,ECX
   MOV  DWORD PTR DS:[EAX+4],ESI
   ADD  EAX,4
   INC  ECX
   CMP  EAX,OFFSET 00440EE4
   JL   SHORT START

There is no complicated instruction in the above algorithm. Initially, EAX will contain the seed value, which is moved to EDX and copied to ESI. This is followed by SHR, XOR, IMUL and ADD instructions. The final value of ESI is then copied to the memory location [EAX + 4].

EAX is increased by four (EAX + 4), then checked to see whether it is equal to 0x00440EE4. If it isn’t, it goes back to the start of the loop and performs the same set of instructions until EAX reaches 0x00440EE4.

Since the initial value of EAX is 0x00440528, the number of iterations it takes to complete the algorithm is approximately (0x270) 624. Randomize 1 will generate 624 random DWORD values in memory, then call the second set of instructions, ‘Randomize 2’.

The second set of instructions uses the 624 random values generated by Randomize 1, and the last GetTickCount value.

Within the Randomize 2 algorithm, Zbot uses a combination of a series of XOR, AND and SHR instructions to generate another list of random values, which are stored in the same memory locations as used by Randomize 1.

The final DWORD is the returned value of the random generator function.

Generate random folder name

Zbot gets the file attributes of the %appdata% folder using the GetFileAttributesW API. This is followed by generating a random folder name to be added to the %appdata% folder’s path.

The random folder name is generated as follows:

Initially, the malware calls the random generator to determine the length of the folder name to be generated.

This is followed by another call to the random generator to produce the index pointer to either ‘bcdfghklmnpqrstvwxz’ or ‘aeiouy’. Then, it stores the selected character to the stack memory and adds a zero byte to produce a Unicode version of the string. It will keep repeating these steps until it reaches the number of characters needed for the folder name.

Once the random folder name is generated, Zbot converts the first character to upper case using the CharUpperW API. Then, it adds the random folder name to the appdata path using the PathCombineW API, e.g. ‘C:\Documents and Settings\{username}\Application Data\Hoyqub’. This is followed by a check as to whether the folder already exists, which is done by calling the GetFileAttributesW API.

To actually create the new folder, a call to CreateDirectoryW API finishes the job.

First dropped file

After creating a new folder, Zbot creates a new file within it.

First, it generates a random name using the same steps as it used to create a random folder name. Then it attaches that random filename to ‘%appdata%\{random folder name}’, with the extension name ‘.exe’.

The format of the generated executable file is ‘%appdata%\[random folder name]\[random filename].exe’. For example:

C:\Documents and Settings\{username}\Application Data\Hoyqub\vigon.exe

This is followed by a check as to whether the file already exists by using the GetFileAttributesW API. If it doesn’t already exist, a new file will be created using the CreateFileW API with GENERIC_READ|GENERIC_WRITE access.

The content of this file will be discussed later.

More folders and files

After creating the first file, Zbot creates two more files with random filenames and random extension names. The new files are placed under two separate folders with random folder names.

The formats of the generated files are:

%appdata%\[random folder name 1]\[random filename 1].[random extension name 1]
%appdata%\[random folder name 2]\[random filename 2].[random extension name 2]

For example:

C:\Documents and Settings\{username}\Application Data\Coyv\enbi.ifo
C:\Documents and Settings\{username}\Application Data\Moeki\exhya.weo

The contents of these files are created after all the code injections have been performed.

The registry keys

After the new folders and files have been created, Zbot opens the registry key HKEY_CURRENT_USER\Software\Microsoft using the RegCreateKeyExW API. This is followed by creating a random Unicode string using the same random generator as used in creating filenames. Then it creates a new subkey using the RegCreateKeyExW API, e.g. ‘HKEY_CURRENT_USER\Software\Microsoft\Gafamu’.

Three more subkeys are generated under ‘HKEY_CURRENT_USER\Software\Microsoft\Gafamu’ with random names, e.g. ‘Empyutso’, ‘Laukerr’ and ‘Sida’ (see Figure 2). These keys contain information gathered from the infected system.

Generated keys with random names.

Figure 2. Generated keys with random names.

Generating the executable file

After the registry keys have been generated, Zbot gets the computer name and the current version of the operating system using the GetComputerNameW and GetVersionExW APIs, respectively. This is followed by opening the registry key ‘HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion’ and querying the values of ‘InstallDate’ and ‘DigitalProductId’. Zbot encrypts this information to be added to the overlay area of the original Zbot file.

After gathering the information above, Zbot gets the path name of the original module using a combination of the GetCommandLineW and CommandLineToArgvW APIs.

Zbot loads the original file into memory and decrypts the file’s overlay area. The decryption algorithm is similar to the decryption of the last section, as discussed earlier. Then, the malware updates the overlay area with the new information, and encrypts it again.

Afterwards, Zbot sets the file attributes of the first dropped file, e.g. ‘C:\Documents and Settings\{username}\Application Data\Hoyqub\vigon.exe’, to FILE_ATTRIBUTE_ARCHIVE. (Note that ‘vigon’ is a randomly generated filename.)

Then, Zbot opens ‘vigon.exe’ using the CreateFileW API with GENERIC_WRITE access, and copies the contents of the memory to the file using the WriteFile API. The memory contains a copy of the original Zbot plus the modified version of the overlay area.

Then, Zbot executes the dropped EXE file, ‘vigon.exe’, using the CreateProcessW API.

Code injection

The binary for Zbot’s code injection is already visible in the decrypted code within the execution of the original process, but it is only activated within the ‘vigon.exe’ process. (Note that ‘vigon.exe’ is spawned from the original process and it uses a randomly generated filename – ‘vigon.exe’ is not always the filename used.)

Within the vigon.exe execution, Zbot parses the process list using a standard call to the CreateToolhelp32Snapshot, Process32FirstW and Process32NextW APIs.

After a call to the CreateToolhelp32Snapshot API, Zbot checks for the value of the PID (processID) and skips both system processes and its own process for code injection.

The malware prepares the binaries for code injection by decrypting some of the code using a simple masking technique, as discussed in the ‘Last section’ part of this article. After getting the necessary information from the decrypted content, it combines the bits and bytes of information to generate a possible mutex value, ‘\BaseNamedObjects\{883D274C-A605-1AD2-7045-FE06EA6D7800}’, relative to the currently parsed process.

After creating the mutex using the CreateMutexW API, it opens the currently parsed process using the OpenProcess API. It follows this by opening the access token by calling the OpenProcessToken API with TOKEN_QUERY as the parameter. If the token is not accessible, Zbot will parse another process from the list.

If the token of the currently parsed process is accessible, it gets the length of the SID (security identifier) of the token information using the GetLengthSid API. If it is not equal to 0x1c, Zbot will skip the parsed process.

If the SID length is equal to 0x1c, Zbot will open the process using OpenProcess, but this time with PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION access mode. Zbot ascertains that it has complete access to the process. After successfully opening the parsed process, it performs its anti-anti malware trick (discussed in the following section) to determine if the parsed process can be injected with its code.

If the executable file is not used by an anti-malware application on the list, Zbot will allocate a remote memory location within the parsed process using the VirtualAllocEx API and write the decrypted code to the newly allocated remote memory using the WriteProcessMemory API.

Then, Zbot passes the handle of the mutex created earlier to the parsed process using the DuplicateHandle API. The parsed process now has access to the mutex, ‘\BaseNamedObjects\{883D274C-A605-1AD2-7045-FE06EA6D7800}’.

After everything is in place, Zbot will activate the remote code using a call to the CreateRemoteThread API and will release the parsed process by calling the CloseHandle API.

Before calling the next process, the generated mutex, ‘\BaseNamedObjects\{883D274C-A605-1AD2-7045-FE06EA6D7800}’, is removed using the CloseHandle API.

Zbot will perform this code injection routine on all processes running in the system if they satisfy all the specified conditions.

Anti-anti-malware trick

A standard trick used by malware to avoid injecting its code into anti malware applications is to check the process list for anti malware names or check for the services used by anti malware applications. This variant of Zbot does it differently.

Before Zbot injects itself into a process, it opens the process and gets the ProcessImageFileName by calling the ZwQueryInformationProcess API. (The ProcessImageFileName will be used later after getting the right device name.)

Then, the malware obtains a list of valid drives in the system using the GetLogicalDriveStringsW API and it gets information about each device using the QueryDosDeviceW API. Zbot uses the resulting device type and compares it against the ProcessImageFileName to determine the exact path of the executable file of the currently parsed process.

Once Zbot knows the exact path of the equivalent executable file of the parsed process, it starts gathering information by calling the GetFileVersionInfoSizeW API to determine if the file contains version information. If there is no version information available for the executable file, Zbot will skip this part of the routine.

This is followed by actually getting the file version information using a call to the GetFileVersionInfoW API. Then, the malware uses the VerQueryValueW API with ‘\VarFileInfo\Translation’ as the parameter, to get the pointer to the translation array from the version-information resource. It uses the resulting array of language and code page identifiers to determine the ‘\{lang-codepage}’ value for the next call to the VerQueryValueW API.

Finally, Zbot gets the ‘Product Name’ of the executable file using another call to the VerQueryValueW API with an lpSubBlock parameter of ‘\StringFileInfo\{lang-codepage}\ProductName’.

After getting the ‘Product Name’ of the executable file, Zbot checks it against specific strings found in some anti malware applications (see Figure 3).

If the executable file’s ‘Product Name’ contains substrings of an anti malware name, Zbot will not perform the code injection for the executable’s process.

Zbot’s anti-anti-malware technique.

Figure 3. Zbot’s anti-anti-malware technique.

Wrap-up

We all know that Zbot is a well-coded piece of malware. It uses a non-standard way of doing things compared with other malware. Instead of using the GetWindowsDirectory API to get the %windir% folder, it uses the newer SHGetFolderPathW API. Instead of checking the process names for anti malware strings, it looks for the product name of the actual file in the disk. And generating 624 random DWORD values a few times just to generate a single DWORD is probably a little excessive.

Zbot is one of the main players in the malware underground. Its structure is as well coded as it is designed. It has lots of functionalities and capabilities, and this article only touches on a small percentage of them.

As we have seen so far, there is always room for enhancements and upgrades pertaining to its code. We are likely to see further adaptation of Zbot to its ecosystem and its environment in the near future.

As always, we will be there to keep you up to date.

twitter.png
fb.png
linkedin.png
hackernews.png
reddit.png

 

Latest articles:

Nexus Android banking botnet – compromising C&C panels and dissecting mobile AppInjects

Aditya Sood & Rohit Bansal provide details of a security vulnerability in the Nexus Android botnet C&C panel that was exploited to compromise the C&C panel in order to gather threat intelligence, and present a model of mobile AppInjects.

Cryptojacking on the fly: TeamTNT using NVIDIA drivers to mine cryptocurrency

TeamTNT is known for attacking insecure and vulnerable Kubernetes deployments in order to infiltrate organizations’ dedicated environments and transform them into attack launchpads. In this article Aditya Sood presents a new module introduced by…

Collector-stealer: a Russian origin credential and information extractor

Collector-stealer, a piece of malware of Russian origin, is heavily used on the Internet to exfiltrate sensitive data from end-user systems and store it in its C&C panels. In this article, researchers Aditya K Sood and Rohit Chaturvedi present a 360…

Fighting Fire with Fire

In 1989, Joe Wells encountered his first virus: Jerusalem. He disassembled the virus, and from that moment onward, was intrigued by the properties of these small pieces of self-replicating code. Joe Wells was an expert on computer viruses, was partly…

Run your malicious VBA macros anywhere!

Kurt Natvig wanted to understand whether it’s possible to recompile VBA macros to another language, which could then easily be ‘run’ on any gateway, thus revealing a sample’s true nature in a safe manner. In this article he explains how he recompiled…


Bulletin Archive

We have placed cookies on your device in order to improve the functionality of this site, as outlined in our cookies policy. However, you may delete and block all cookies from this site and your use of the site will be unaffected. By continuing to browse this site, you are agreeing to Virus Bulletin's use of data as outlined in our privacy policy.