2013-02-04
Abstract
Raul Alvarez looks into the execution path of malware that resembles a piece of shellcode inside a help file.
Copyright © 2013 Virus Bulletin
These days, we seldom use the help (.hlp) file in our daily computing tasks. We have the Internet at our disposal for more or less everything that we need to learn. What’s more, .hlp files are not supported by all operating systems.
In this article, we will discuss code that drops malware onto your local machine once an .hlp file is opened. We will look into the execution path of a piece of malware that resembles a piece of shellcode inside an .hlp file.
Recently, researchers found a help file named ‘Amministrazione.hlp’ that installs a keylogger on the local machine. Once the file is opened, it shows a message stating that the file could not be read. In the background, however, a file is being dropped, which in turn creates the keylogger. We have also seen another .hlp file which has similar code that runs in the background. It is safe to assume that the two samples belong to the same family. We will investigate these pieces of code as we move on.
Let’s look at the first sample.
The malware first decrypts 716 bytes using a simple decryption algorithm, as shown below. It uses the basic assembly instructions: SUB (subtract), SHL (Shift Left), and ADD. LODS is used to grab the WORD value from the current ESI and store it at the AX register, while the STOS instruction is used to store the value of the AL register in the memory pointed to by EDI:
LODS WORD PTR DS:[ESI] SUB AX,6161 SHL AL,4 ADD AL,AH STOS BYTE PTR ES:[EDI]
After the decryption routine, the malware parses the PEB (Process Environment Block) to locate the imagebase of kernel32.dll. Once the imagebase is acquired, it locates the export table of kernel32.dll and searches for the first API names in the table. The malware acquires the addresses of all the APIs it requires by hashing the API names found in the kernel32.dll export table and comparing them to its own list of values.
The malware has a list of constant values that are equivalent to the hashes of the API names that it needs (see Figure 1). These constant values are the input parameters for the subroutine that returns the addresses of the APIs.
The subroutine first computes the hash value of the first API name found in the export table of kernel32, then compares it with the current constant hash value. If the two are not the same, it will proceed to the next API name in the table. The computation of the hash value for each API name will continue until it finds one that matches the current constant hash value.
The API names are hashed using simple ROR and ADD instructions. (Figure 1 shows a snapshot of the code used for hashing and the table of API hashes used by the malware.) Once the correct hash has been found, the address of that API becomes the resulting value returned by the subroutine.
After getting all the required API addresses, the malware tries to locate the handle of the original help file by getting its file size.
The malware uses the GetFileSize API and a HANDLE parameter with a value of 1. If the result is INVALID_FILE_SIZE (0xffffffff), it will increase the HANDLE value by 1 and check the file size again. It will keep increasing the HANDLE value until it gets a result other than INVALID_FILE_SIZE. Once the result of GetFileSize is anything other than 0xffffffff, the malware assumes that the HANDLE is for a valid file.
The malware reads and parses the contents of the file in memory by checking for ‘XXXXYYYY’. If the marker is not found, it will go back to the loop that gets the file size of the incremented HANDLE. If ‘XXXXYYYY’ is found, the malware double checks that it is reading the right file by checking for the second marker, ‘YYYYXXXX’.
Once the correct help file is loaded in memory, it creates an empty TMP file in a %temp% folder using the GetTempPathA and GetTempFileNameA APIs. It also sets the newly created TMP file to be deleted on the next reboot by calling the MoveFileExA API and sets the parameters NewName to NULL and Flags to DELAY_UNTIL_REBOOT.
The malware decrypts the rest of the malware body, which is loaded in memory, using a simple XOR instruction with decrementing key values. It writes the decrypted malware to the TMP file (see Figure 2).
The malware transfers control to the TMP file by calling the WinExec API.
Once the TMP file executes, it drops the following files in the ‘\Documents and Settings\[username]\Local Settings\Application Data\’ folder:
RECYCLER.dll Windows Security Center.exe UserData.dat Windows Security Center.lnk
This sample also starts by decrypting approximately 738 bytes of code/data. It uses a different decryption algorithm from the first sample, using a combination of INC (Increment), IMUL (signed multiplication), and XOR instructions:
INC ECX INC ECX INC EDX IMUL EAX,DWORD PTR DS:[ECX+41],10 XOR AL,BYTE PTR DS:[ECX+42] XOR AL,BYTE PTR DS:[EDX+42] XOR BYTE PTR DS:[EDX+42],AL POP EAX PUSH EAX CMP BYTE PTR DS:[ECX+43],AL
The API resolution is almost the same as for the first sample. The malware acquires the imagebase of kernel32.dll by parsing the PEB, and also locates the export table to hash the API names.
It is interesting to note that the first sample started by getting the hash value of the first API name found in the kernel32 export table, but sample 2 starts from the last API name found in the table.
Sample 2 uses the same computation to hash the required APIs. Although the list of required APIs is not exactly the same as for sample 1, as shown in Figure 3, the hash values themselves are a strong indicator that the two samples belong to the same family.
Sample 2 uses the same technique as used by sample 1 to locate the original help file. The file marker for this sample is 57 64 50 49 EF FE EB BE (in hex). Once this marker is found, the malware knows that it is looking into the original help file.
Sample 2 decrypts the rest of the malware body but does not drop a separate file. Instead, after decrypting the rest of the malware and putting it into the allocated memory, it transfers control to the newly decrypted code.
We will not follow the execution of the newly decrypted code, since we are looking at the execution of the common code between samples 1 and 2.
After executing the newly decrypted code, the malware creates a new file in the %temp% folder named ‘help.hlp’, using the _lcreat and _lwrite APIs.
Finally, the malware uses the WinExec API to open the help.hlp file, using ‘cmd.exe /c %temp%\help.hlp’ as the parameter. ‘Help.hlp’ contains the actual help document that displays something that looks like a news article.
In previous articles we have discussed Quervar [1], which infects document files, and which can also infect other files that contain the document extension name. We have also looked at the DLL-infecting Floxif [2]. Now, we are looking at infected help files. It seems as if pretty much any type of file that exists on our computer is susceptible to infection. The most reliable form of defence is to make sure anti-malware software is kept up to date and that our computers are scanned regularly. Stay safe!
[1] Alvarez, R. Filename: BUGGY.COD.E. Virus Bulletin, October 2012. http://www.virusbtn.com/virusbulletin/archive/2012/10/vb201210-Quervar.
[2] Alvarez, R. Compromised Library. Virus Bulletin, December 2012. http://www.virusbtn.com/virusbulletin/archive/2012/12/vb201212-Floxif.