<< back to Blog

Introduction to TProbe - part 3: Tracking injected code

In this tutorial we will explore a case in which malicious process injects code into another, legitimate process. For this purpose we will use a sample of Hamweq bot. It's an old sample, but it's simplicity will provide for a smooth introduction into some of the advanced TProbe features. You can get the sample here. The password is "infected".

We will execute this analysis scenario using Windows XP guest OS. In order to make sure our TProbe configuration corresponds to this system, let's verify the configuration file:

$ nano /usr/lib/<your installation directory>/tprobe.py

Make sure that the corresponding Window XP profile is the only one uncommented. If you are unsure what is your installation directory, you can verify it with this command:

$ dpkg -L tprobe-volatility

Now, boot the tprobe-qemu with a qemu drive of your choice containing Windows 7. After logging in, download and extract the sample. Shut down the system and create a disk snapshot so that you can easily reverse it to the pre-infection state.

$ qemu-img snapshot -c save <windows_7_drive>

If everything went smoothly, start the clean machine and after the booting process has finished, attach tprobe:

$ tprobe

Upon succsesful attaching to the target machine, the UI will appear.

Explorer spawning malicious process

In a real attack, malicious actors are usually trying to trick users into spawning malicious processes by disguising them as non-executables, creating them with scripts embedded in office documents or simply as a result of exploitation. However, in order to demonstrate, how you can swiftly change process contexts using TProbe, while debugging Explorer.exe process, we will simply execute the malicious program by double-clicking on it.

So, first, we will place a breakpoint on the CreateProcessW library function in this process.

Reloading module list in selected process

Select the explorer.exe process in the Process View. From the context menu, reload the module list for this process.

After module list have been refreshed, reload the symbol list of the kernel32.dll library, which exports the CreateProcessW function.

Reloading symbols in a selected module

Next, place a breakpoint on it and release the execution.

Inserting breakpoint

After that, we can execute the malicious sample by double-clicking on it. If we did everything correctly, the execution should stop in explorer.exe context, as it tries to use the call for creating a new process. We can apply symbols to the Code View for better insight into the meaning of particular calls.

Applying symbols to Code View

Let's wait until this operation finishes by clicking Run until return (ret scan).

Waiting for CreateProcessW to return

At this point, the internal operating system structures for the hamweq5.exe sample have been created, but it haven't started its execution yet. Let's put a breakpoint on it's entry point, so that we can trace the execution of the malware from the beginning.

Inserting breakpoint

After releasing the execution for the second time, the execution of sample commences and TProbe halts on our breakpoint.

Entry point

Now, we are "inside" the actual malicious code. During its execution the saple will perform many various operations in our system. We will focus on one specific: injecting code into another process.

Code injection

For the purposes of code injection, analyzed sample uses an old CreateRemoteThread technique. In this technique, malware allocates memory in the process selscted for injetion, writes its code into it and starts another thread in that process with help of the mentioned function. In order to analyze it, we will create a breakpoint on this function in the context of sample process. Use  the context menu to reload module list of hamweq5.exe and symbols in kernel32.dll library. Place a breakpoint on CreateRemoteThread function.

Inserting breakpoint

After releasing sample execution, the next TProbe halt will occur on the first instruction of CreateRemoteThread. Let's examine the description of this function from MSDN:

HANDLE CreateRemoteThread(
 HANDLE                 hProcess,
 LPSECURITY_ATTRIBUTES  lpThreadAttributes,
 SIZE_T                 dwStackSize,
 LPTHREAD_START_ROUTINE lpStartAddress,
 LPVOID                 lpParameter,
 DWORD                  dwCreationFlags,
 LPDWORD                lpThreadId
);

From our perspective, two arguments of this call are of importance. The hProcess parameter indicates handle of an open process which is target for injection, and the lpStartAddress is starting address of a newy created thread. We can examine these parameters by opening a new Memory View (DWORD) and synchronising it with ESP register. Also, we can examine handle list to learn, which process is targeted for injection.

Viewing handles

Now, let's move to the targeted process. Change the context in Process View for explorer.exe (which is the target). Navigate to the start of the new thread by choosing approporiate function in the context menu and place a breakpoint there.

Inserting breakpoint

Release the execution and wait for the hit.

Breakpoint hit

Now, we are inside the injected thread.

Injected thread

To summarize our experiments, we started by analyzing process creation process in the context of legitimate explorer.exe process, then navigated to the malicious sample's code injection operations, then back again to the targeted explorer.exe process. We did this with a simple clicks in a single TProbe instance. This illustrates one of the main advantages of this solution over popular userspace debuggers. Because it's outside of the debugged operating system, it is not restricted by it's boundaries and allows an Analyst to explore every aspect of process in the machine.

To continue our exploration of an injected code - let's apply symbols to the Code View.

Applying symbols

We can track the execution of this code and many operations that it performs. For example - resolving domain names.

Explorer.exe is resolving a DNS name

Explorer.exe resolving a domain name - now that's something that should raise an eyebrow :)

We hope that you enjoyed this post. If you have any comments or questions regarding it - please do not hesitate to contact us using the form below. And be sure to read the next post in the introduction series - on crossing the userspace/kernelspace border.

<< back to Blog

Questions?

Contact us!

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.