Книга: Practical Malware Analysis: The Hands-On Guide to Dissecting Malicious Software
Назад: Lab 13-1 Solutions
Дальше: Lab 13-3 Solutions

.

.

represent the clearing of a register and can be ignored. The instructions labeled are contained in library functions and can also be ignored. We are left with two functions of interest: sub_40128D and sub_401739 . Additionally, at 0x0040171F is in an area of code that has not been defined as a function.

We’ll refer to sub_401739 as heavy_xor since it has so many xor instructions, and sub_40128D as single_xor since it has only one. heavy_xor takes four arguments, and it is a single loop with a large block of code containing many SHL and SHR instructions in addition to the xor instructions. Looking at the functions called by heavy_xor, we see that single_xor is related to heavy_xor since the caller of single_xor is also called by heavy_xor, as shown in .

(0x0040171F), we see that it is in a function, but the function was not automatically identified due to lack of use. Defining a function at 0x00401570 results in the creation of a function that encompasses the previously orphaned xor instruction. As seen in , this unused function is also related to the same cluster of likely encoding functions.

To confirm that heavy_xor is the encoding function, let’s see how it is related to the temp files that were written to disk. We can find where the data is written to disk, and then trace backward to determine if and how encoding functions are used. Looking at the imported functions, we see WriteFile.

Checking the cross-references to WriteFile, we find sub_401000, which takes as arguments a buffer, a length, and a filename, and opens the file and shows the contents of sub_401851 (which we rename doStuffAndWriteFile), leading up to the call to writeBufferToFile at .

, we see two function calls to sub_401070 at and sub_40181F at that both use the buffer and length as arguments. The format string "temp%08x" at combined with the result of GetTickCount at reveals the source of the filename, which is the current time printed in hexadecimal. IDA Pro has labeled the filename, as indicated at . From the code in , a good hypothesis is that sub_401070 at is used to fetch some content (let’s call it getContent), and that sub_40181F at is used to encrypt the contents (which we’ll rename encodingWrapper).

Looking first at our hypothesized encoding function encodingWrapper (at 0x0040181F), we see that it is merely a wrapper for heavy_xor. This confirms that the functions depicted in are our encoding functions. The function encodingWrapper sets up four arguments for the encoding: a local variable that is cleared before use, two pointers both pointing to the same buffer that is passed in from doStuffAndWriteFile, and a buffer size that is also passed in from doStuffAndWriteFile. The two pointers pointing to the same buffer .

). The second breakpoint will be after the first file is written, so we set it at 0x0040190A.

After starting the malware with OllyDbg, setting the breakpoints, and running the program, the malware will stop at the first breakpoint (0x00401880). At this point, the arguments on the stack represent the buffer to be encrypted and its length.

Right-click the top value on the stack in the stack pane (the value located at ESP) and select Follow in Dump. Next, open one of the encrypted files that the malware created in WinHex and select Edit ▸ Copy All ▸ Hex Values. Then, in OllyDbg, select the values from the top of the dump pane to the end of the memory block (OllyDbg requires the entire target area to be selected before allowing you to paste content). This selection represents the buffer that is about to be encoded, which we will now fill with the contents of the file. (Don’t worry if the memory block is longer than the buffer size; OllyDbg will paste the content only up to the length of the file.)

Now right-click the Hex dump portion of the dump pane and select Binary ▸ Binary Paste. (If you’re using an editor that allows you to copy binary values directly, paste into the ASCII portion of the dump pane instead.) With the buffer prepared, run OllyDbg until the final breakpoint, and then check the malware’s directory for a new file with the same naming convention as the previously created ones. Give this file a .bmp extension and open it. You should see a screenshot that was taken while the malware was running.

, as well as in . We create the Python script shown in by saving the file with a .py extension in the PyScripts folder under the ImmDbg installation directory.

based on your environment.

, the first breakpoint stops execution just before the arguments are pushed on the stack. The open call at opens the encrypted file that has already been written to the filesystem. The next few lines read the file into memory and calculate the size of the buffer. The remoteVirtualAlloc call at is used to create an appropriately sized buffer in the memory of the running process, and writeMemory is used to copy the file contents into that new buffer. The two writeLong calls at replace the stack variables for the buffer to be encrypted and its size. The next few instructions push those variables onto the stack to be used for the following encryption routine and the writing of the file.

Open the malware in ImmDbg, choose ImmLib ▸ Run Python Script, and then select the script that has been created. The script should run, and the debugger should halt at the second breakpoint. At this point, the malware should have written a single file in its own directory. Navigate to the malware’s directory and identify the most recently written file. Change the extension of this file to .bmp and open it. You should see the decrypted screenshot that was taken earlier by the malware.

Назад: Lab 13-1 Solutions
Дальше: Lab 13-3 Solutions

sss
sss

© RuTLib.com 2015-2018