Advanced Static Analysis - Reverse Shell
- Hacking By Doing
- Dec 28, 2022
- 4 min read
In this post, I will be presenting an advanced static analysis of a reverse shell malware downloaded from the HuskyHacks GitHub page

This is the information I have on the file

The IR and RE teams have gotten a sample of a dropper program on which I need to perform advanced analysis on.
Basic Static Analysis
First I searched the hash on virustotal and found out it was flagged as malicious by 51 different security vendors, most of which have flagged the file as a trojan

Then I looked at the strings using pestudio

There are a few suspicious API calls here, for example, there's VirtualProtect, which is often used by malware to modify memory protection,
Or WriteProcessMemory, which is used for writing data into a specified region of memory, this is often used by malware as a part of process injection to inject malicious code into a specified process.
Basic Dynamic Analysis

At initial detonation, something popped up for a split second that I couldn't capture, and after checking my Wireshark logs (while using inetsim)
I didn't find anything useful.
Host-Based indicators:

The main file unpacks another file named werflt.exe


TCP Socket:

Reverse Shell:


Advanced Static Analysis
Opening werflt.exe with cutter

At first glance it seems like a pattern for a CreateRemoteThread process injection;
CreateRemoteThread process injection is a common evasion technique used by malware writers to execute malicious code within the context of another process.
This allows the malware to evade detection and operate covertly on the infected host.
The process injection technique involves creating a new thread within the target process and then injecting the malicious code into the new thread.
The injected code runs as part of the target process and can perform any actions that the target process is capable of.
This can include modifying system settings, stealing sensitive data, or installing additional malware.
The value of arc_ch is passed into eax as we see in here

Then eax is pushed into the stack

So in other words, we are opening a process, and the parameters are passed in and asking for all access to this process, and the process ID will be the argument passed into the main function
So then arch_ch will be the process ID

And then it takes the process ID and moves it into the edi register

Then we request the handle to a process to open it up to be able to
access it.
and we're giving that to an API call that will allocate memory inside of that process.

Moving on to another API call - WriteProcessMemory,
The first parameter is the handle to the process, which is the same one we've been using which was passed at the start of the program,
then we need a base address, the buffer size, and the number of bytes written

so we get the edi which contains the content of the process handle (we went over this before in the "mov edi, eax" line)
then we use it again in the WriteProcessMemory API call

the esi has the base address of the process

and the eax has the lpBuffer

So now we see that we have 3 arguments from the top and 3 arguments going to be the lpBuffer,
To understand what is the buffer we need to go back to the top where it's set up at the top of the program.
to go over what it means is that we start by opening up a process, which is specified by the argument that's passed into the main function,
then we allocate an area of memory inside of that process with the rights to be able to write into that memory.
then we are taking those bytes from the lpBuffer variable and write them into that process in the section of memory that we've allocated, and then the next API call will be the end of the CreateRemoteThread
And if we look at the CreateRemoteThread function, we can see that it has a bunch of parameters being passed into the API.

but if we look at the stack there are only two that are pushed onto the stack, which are the 1st parameter and the 4th parameter

So if we go back to CreateRemoteThread, the first one is the handle to the process and the fourth will be the start address, which will be where this thread begins its execution, so the value in esi is currently what we need to look at because that's what it is going to be executing.
Visual Representation
Let's start by opening process hacker 2 and executing the program.

As we see, WerFault.exe is spawned in a suspended state Immediately.
while it spawned in a suspended state, the rest of the program is executing,
then the process ID of WerFault.exe is passed on to the unpacked program werflt.exe so when werflt.exe executes it takes WerFault.exe process ID.
It opens the process and bypasses it in the process handle

Then it allocates an area of memory inside that process

It writes the bytes of the shell code that it's using into that process

Then it creates a remote thread and executes the shellcode finally giving us a reverse shell

Now if we go to process hacker 2 and open up WerFault.exe we will get a legitimate application.

But if we go to the memory tab we can find the area of allocated memory, notice the read, write, and execute permissions.

Conclusion
When we create a remote thread we are going to create a thread inside of a remote process by taking it from the arguments of the main function, and then going to the contents of esi which is the lpBaseAddress, which is the base address of the data that is written in during the VirtualAllocEX and WriteProcessMemory API calls.
We start by handing this program a process ID, then it takes the process ID and opens up that process with the level of access
required to be able to write into that process, then it allocates a section of memory with read, write, and execute permissions, and writes the content of a specified variable into the allocated memory,
Finally, it starts a thread in that remote process and tells the thread to go to the address that we allocated during the WriteProcessMemory API call and execute its content.
This is a common way for a shellcode to be injected into a remote process, because you can write your shellcode into the body of the program and then copy those bytes into the remote process, write them into memory and execute them with a new thread via the CreateRemoteThread API call.
I hope this was useful to you and thank you for reading.




