In Part One of this series, we discussed how MailTo ransomware installs itself on the victim's system and then initialized itself with configuration options and persistence via the registry. Today we're going to continue our deep dive by looking into how MailTo executes and injects itself into the system.
After the MailTo ransomware has finished initializing, it begins the process of starting a new “explorer.exe” instance and injecting a copy of itself into it. Two different methods of execution transfer can be used but in either case, it maps itself into the process in the same way.
The ransomware maps itself into an instance of “explorer.exe” by using the API function “NtMapViewOfSection” and then manually fixes its relocations rather than using the Windows API “LoadLibrary” or “LdrLoadDll”. This method has the advantage of not being linked in the “PEB->InLoadOrderModuleList” member and being mapped outside of the expected memory range (above the executable mapped image base).
The next step after the ransomware has mapped itself into the “Explorer.exe” process, is to transfer execution to the ransomware. The ransomware has two different methods to do this. The first method we will call “Debug Injection” and the second method “APC Injection”. Debug Injection is used if the operating system is newer than Windows 2000. APC injection is used if debug injection fails or the minimum operating system version requirements are not met.
With the Debug Injection method, the ransomware first uses the function “CreateProcessW” with the “DEBUG_ONLY_THIS_PROCESS” creation flag. Creating the “Explorer.exe” process in this state allows the ransomware to suspend the process and modify its memory. This is when then ransomware calls “NtMapViewOfSection” to copy itself to the process and fix its relocations. Afterward, it calls “NtGetContextThread” to receive the thread context of the main thread for “Explorer.exe”. It then sets the instruction pointer (EIP) to the mapped ransomware’s selected entry point. “ContinueDebugEvent” is then called to continue the execution of “Explorer.exe” and the following call is to “DebugActiveProcessStop” which finally detaches the ransomware’s debugger from the process.
With this method, the ransomware will begin by starting the “Explorer.exe” process as a suspended process using the “CreateProcess” Windows API function and “CREATE_SUSPENDED” flag. The ransomware then manually maps itself into “Explorer.exe” using the same method described in Debug Injection. To transfer execution however, the ransomware will use the undocumented “NtQueueApcThread” Windows API function and lastly call “NtResumeThread” to continue the process from its suspended state.
The main purpose of the injected routine inside of “Explorer.exe” is to perform file encryption of shared network drive, network paths, and local disk drives. The ransomware also performs uninstallation and deletes shadow copies. The routine also will create a second “Explorer.exe” instance if the “useKill” option in the configuration is set to true. The second “Explorer.exe” instance is injected into using the same discussed techniques and will serve the purpose of killing processes, services, and scheduled tasks.
The second “Explorer.exe” is started from the first “Explorer.exe” injection routine and is responsible for killing processes, services, and scheduled tasks. Each of these objectives is achieved in their own thread.
MailTo kills processes listed in the ransomware configuration under the field “kill->prc”. Many of the listed names appear to be processes that could potentially be performing an operation on a file that could prevent the ransomware from encrypting the file.
Process killing in MailTo works using the Windows API function “NtQuerySystemInformation” and more specifically, with the “SystemProcessInformation” class which is used to return a list of all currently running processes on the system.
These processes are iterated over and have their image names hashed with CRC32. The CRC32 hash is compared against its own process image name hash and two other hard-coded hashes. A list of mostly wildcarded process names resides in the ransomware’s configuration file (see Part One). The image base name of the iterated processes is compared with each of the wildcarded process names in the configuration (found under ‘kill->prc’).
If the comparison results in a match, the ransomware will call the “OpenProcess” and “NtTerminateProcess” Windows API functions to terminate the process.
MailTo has the capability to kill listed services for what appears to be the same reason as with killing processes as again, the listed services appear to be common services which could be performing an operation on a file which would stop the ransomware from being able to encrypt the file the service is operating on. The listed services can be found in the configuration under the field “kill->svc”.
Services are killed throughout three functions in this ransomware.
- Iterate all the currently running services and match them against the configuration blacklist.
- Iterate all dependent services on the matched service.
- Stop the dependent services from running as well as the originally matched service.
The expected outcome of this capability is for the services in the blacklist to be stopped. However, this does not happen and with further inspection, it was discovered that the malware author made a critical mistake that prevented any services from being stopped. Simply put, service killing in this sample does not work.
The mistake in question is related to step one of the process of iterating all the currently running services and match them with the blacklist. That part never takes place. In fact, we even discovered code to perform that step one but it simply was not used. When the time comes for the ransomware to kill services, it tries to begin with step two, which does not make sense because there is no matched service for step two to work with. What happens is step two is given the value zero which is supposed to be a handle to a service. Step two will check if the given value is zero and if this comparison is true, step two will simply return right there and then, consequentially doing nothing as step three is never performed. The mistake is that step two is always given the value zero.
*StartRoutine() is a wrapper for CreateThread()
The code “if (!lpThreadParameter)” checks to see if the parameter (“lpThreadParameter”) is zero which as we can see in the above image will always evaluation as true.
The below image is a part of a function which performs the first step of the process for stopping services. This function shows the correct usage for continuing to step two of the process for stopping services. At the bottom of the image, you can see the code “StartRoutine(KillServiceByHandle, param);” the “param” will contain a handle to a service that was matched against the configurations blacklist. This means that step two will be able to correctly function and move onto step three where the service will be stopped as well as other services which depend on the matched service.
The MailTo ransomware makes use of the “CoCreateInstance” Windows API function to get access to the ITaskService interface which will then lead to getting access to the ITaskFolder interface through the ITaskService->lpVtble->GetFolder() function.
The ITaskFolder interface is used in conjunction with other functions to iterate over task names, paths, and arguments, then compare them to a blacklist of words in the configuration.
If any of the words in the configuration are a part of the task name, path, or arguments, the scheduled task will be stopped, disabled, and then deleted.
MailTo is now all set to begin encryption.
So in this part of our deep-dive analysis, we saw how MailTo inserts itself as a running process and kills various processes and services to ensure the best environment to begin to take your data hostage. In our next part, we will look at how MailTo gets to business encrypting your valuable files.