PMA - CH 9-1
Analysis of Lab09-01.exe
Last updated
Analysis of Lab09-01.exe
Last updated
As always throwing the file in PEStudio we can see two interesting imports shell32.dll and ws2_32.dll. Used to execute shell commands and access internet functionality.
Checking the string we can see GET, DOWNLOAD, UPLOAD, and NOTHING (could be different commands that could be run during execution). We also see a URL string and what appears to be a file directory.
Running the file nothing appears to happen and after checking the file we can see that it deletes itself. Looking at "main" we see a comparison check to 1 checking if any arguments were supplied, when we executed the file we supplied no arguments so following the execution flow we will make a call to sub401000 (renamed check_reg_config)
Jumping into the function call we can see calls to RegOpenKeyExA and RegQueryValueExA. The malware is checking the registry specified which is "SOFTWARE\Microsoft \XPS" named and is reading the contents of the registry name "Configuration", following we have a call to CloseHandle and then we can see the value 1 being stored into EAX before we return. Looking at the 3 other exit routines none add the value 1 into EAX which will become important for the malware to execute properly.
Returning from our function call we have an immediate test EAX, EAX which if you remember should hold the value 1. If not we will jump to function sub402410 (renamed self_del)
Diving into sub402410 (renamed self_del) we have calls to GetModuleFileName and GetShortPathNameA which will retrieve the file path information. The malware makes a lot of rep movsd and repne scasb which basically concatenates the strings pushed onto the stack such as "/c del", ">> NULL", and "cmd.exe". And then after we have a call to ShellExecuteA which will execute the command that was created
Basically, this function will delete the file from the system. Looking at it in x32dbg we can see the full string concatenated together
Following the other execution path, we see a call to sub_402360 which we will further analyze later as for the features to work the malware must first execute properly.
So looking at the beginning of "main" again we can see the comparison check and then the jump this means that the malware is looking for another command-line argument when executing.
Example: Path/to/executable/file.exe <argument>
After we supply an argument the malware will make a call to sub_402510 (which has been renamed to password_check). Looking at the code block we are moving our two parameters supplied into EAX and ECX. We get the last parameter supplied and pass it into EAX before pushing it onto the stack and making a call to password_check.
Looking at this function we don't make any calls. The malware is checking our parameter that was pushed onto the stack to the value of 4 if not the malware will pre-maturely exit and then call self_del again. Looking at the rest of the code it is checking each character in our parameter before finally moving the value 1 into EAX and exiting the function call. We could reverse engineer the code and figure out the password but for now, we can patch the code to skip this check altogether.
To patch the code all we need to do is change the first two instructions in the function call like so:
We move the value 1 into EAX because after the function call we have a Test EAX, EAX
The next few code blocks are again checking our parameter this time it is checking for the strings "-in, -re, -c, and -cc" all of which are not four characters long which makes me think that the previous parameter check (password_check function call) is a password that needs to be provided for the malware to properly run. In this case, we will need to provide three parameters:
Example: Path/to/executable/file.exe < -in, -re, -c, -cc > < password >
We push our parameter that we passed then a string "-in" and then we call mbscmp which compares our strings. If it fails it will keep moving down the code block and check for "-re" "-c" and "-cc". Following the execution for "-in" we see two function calls
Checking out sub4025B0 (renamed as get_path_filename) is quite simple it makes a call to GetMoudleFileNameA which will get the path to our executable file and then calls __spiltpath which will return just the file name of our executable.
You can see after the call to __spiltpath we have our file name stored in memory
After the call we return to "main" we push our file name onto the stack before calling our next function sub402600 (renamed service_install_config). Looking at this function we can see some important things start happening
We make another call to get_path_filename. Before moving a lot of data (repne scasb and rep movsb). Looking at this block in x32 we see that it is concatenating three strings together.
"%SYSTEMROOT%\\system32\\Lab09-01_patched.exe"
Following this, the malware makes calls to OpenSCManagerA, OpenServiceA, CreateServiceA, and ChangeServiceConfigA. All of these calls are to edit services within windows. The malware is opening a service, depending on if something is already created the malware will either edit the service or create a service.
If there is no service named Lab09-01_patched then the malware will create a service with the display name "Lab09-01_patched Manager Service"
We can also verify this by checking our services
After we will close our service handle and make a call to CloseServiceHandle. Next, the malware calls ExpandEnvironmentStrings which replaces a variable with a value assigned in this case WOW64.
CopyFileA is passed which copies our executable into SysWOW64 directory (during analysis is says it will be placed into system32 however I found it in SysWOW64)
We can also verify this
We are finally making it to the end of this function. The malware calls sub_4015B0 (get_kernel32) and sub_401070 (get_request_create_reg).
Within function call kernel32 we only make one call to GetSystemDirectoryA and then again are concatenating strings together the final output will be "C:\Windows\system32\kernel32.dll before calling sub_4014E0 (renamed to GetFileTime) we pass our string that we concatenated together and then our path to our file (located in system32).
Within GetFileTime function we call CreateFile to open a handle to kernel32.dll we then make a call to GetFileTime which "Retrieves the date and time that a file or directory was created, last accessed, and last modified". Then open a handle to lab09-01.exe and SetFileTime. This is known as time stomping modifying the creation date and time of files. We then exit function GetFileTime and move back into get_kernel32 which we do some cleanup and then return back.
Before looking at (get_request_create_reg) we can see four strings being passed "60" "80" "http://practicalmalwareanalysis.com" and "ups". This function is again concatenating string together so looking at this in a debugger we can see the final string
This string will be used for RegCreateKeyExA which creates a registry key with the display name as "SOFTWARE\\Microsoft \\XPS" and then calls RegSetValueExA and the data contained inside is our string that was generated above is stored and has the display name as "Configuration". We then return back to service_install_config and then return again back to "main"
Let's recap what "-in" is actually doing. The malware checks for a service named "Filename Manager Service" if there is no service one will be created. The malware then copies itself into System32 (in my case SysWOW64) directory and time stomps the file with kernel32.dll finally the malware creates a new registry key stored under SOFTWARE\Microsoft \XPS and stores the string "ups <url> 80 60". This concludes the "-in" parameter, we can conclude that "-in" most likely installs the malware onto the system.
Without even running our malware with the "-re" parameter we can assume that "-re" will remove itself from the system. Looking at the function calls it will undo everything that it did.
Let's then move on to the "-c" parameter. This parameter only makes one function (get_request_create_reg_config) call and if we notice this function is called twice once when we install the malware and the other when we remove the malware. This function was responsible for adding data to our configuration registry key that was created. Before the call, we are moving parameters that are passed when executed. We'll also notice that after the string comparison (mbscmp) we make another CMP this time against the value 7. This is because the malware is expecting more parameters to be passed, let's see if we can find out what these parameters will do.
We can expect that the parameters passed are used to update the Configuration registry key that was created. Running this in x32 we can see that we are correct.
We can also verify this by checking our registry key and we can see that it has been updated with the parameters that we passed. We now know that "-c" is used to update the registry key with new information.
Finally, we can see what "-cc" will do. Looking at the execution flow we can see that "-cc" will call sub401280 (renamed reg_open_query_config)
Looking at the function we can see calls to RegOpenKeyExA and RegQueryValueA and then the malware concatenates whatever is inside the registry and moves it into memory.
We can see after our call to RegQueryValueA we can see the data in the registry is now loaded into memory
After we have stored the data into memory we return back to "main" we can then see our four parameters being pushed to the stack before calling sub402E7E (renamed print_output_string)
Looking at this function it is quite simple
Looking at sub403A88 (renamed jump_table_check) we see this...
I didn't even bother trying to statically analyze this function and decided to leave it to the debugger. Looking at this in x32 starting at sub_402E7E we step over the __stbuf function at 402E87, step over our jump_table call at 402E98, and again step over __ftbuf and we can now see in our console window output displayed. Which is the data stored in the "Configuration" registry.
We now know what every command does, to recap:
-in: will install the malware onto the system
-re: will remove the malware from the system
-c: allows the attacker to update the information stored in the Configuration registry
-cc: will print the information stored in the Configuration registry to the console
We have one last important function to analyze which we touched on at the beginning of the post, sub_402360 (renamed parent_comms_init). If we recall when running the executable with no parameters we will not jump and call check_reg_config, following is a call to parent_comms_init
The function calls reg_open_query_config which will grab the information stored in the Configuration registry created and put the data into memory.
We then push the port number that is stored in the registry (port 188 otherwise it would be 80 as I had changed the data stored in the registry previously)
Next, we push our URL before calling comms_check (sub_402020)
Looking at this function we can see another string comparison block as before this time with different commands (SLEEP, UPLOAD, DOWNLOAD, CMD, and NOTHING). With this information, we can start determining that this is a full-blown backdoor RAT.
Stepping into http_init_checking (sub_401E60) we have four different function calls, first, we have xor_query_config (sub 401420) which returns our URL stored in the registry key
Then we call atoi_query_config (sub_401470) which returns our port number stored in the Configuration registry. Then we call comparison_loop (sub_401D80) which seems to return a random string that will be used to make the http GET request next
Finally, in this function, we call http_request (sub_401AF0) which initializes the use of ws2_32.dll, and then sends an HTTP/1.0 GET request, which we can assume will return with one of our commands (SLEEP, UPLOAD, DOWNLOAD, CMD, NOTHING). After we see two more function calls this time to _strstr which looks for an occurrence of a string in this case ( '`'`'`' ) backtick and apostrophe and then concatenates a string.
After our http_init_checking function, we will then start the string comparison of the command that was received, taking a quick look at what the functionality is of each command we see:
SLEEP: sleeps for a specified time
UPLOAD: Creates a file then connects to the remote host (attacker) and reads the content to the new file created
DOWNLOAD: Reads the contents of a file and sends it to the remote host (attacker)
CMD: Executes a shell command with cmd.exe and sends output to remote host
NOTHING: Does nothing...
That concludes the analysis of this file. I hope you enjoyed and as always if you notice any errors or have any comments always reach out and let me know. Thanks for reading! :)
Michael Sikorski and Andrew Honig. Practical Malware Analysis: The Hands-On Guide to Dissecting Malicious Software (Kindle Locations 5895-5907). No Starch Press.