To unpack the main payload, the loader performs the following actions:
FindResourceWis made to identify the embedded resource by the type ID value of 899 (383 in hex).
LoadResource, the handle is later used to obtain a pointer to the first byte of the resource in memory.
LockResourceuses the previously obtained handle to retrieve a pointer to the resource in memory
SizeOfResourceand it’s stored in a DWORD variable named
resource_decryption, the decryption function takes the buffer containing the payload, and it’s size, as well as the decryption key bytes.
“fgh57767” corresponds to an embedded resource within the loader’s binary file. Inspecting the binary in PeStudio reveals the resource by name. The
type ID is 899 which is how the resource is identified. The size of the embedded resource is 116,042 bytes.
To execute the unpacked main payload the loaded uses process hollowing. While performing injection, the loaded includes basic function call obfuscation by breaking up the function names (strings) used to dynamically resolve them. The loaded uses
GetProcAddress to resolve the necessary functions, the strings passed to
GetProcAddress are broken up and concatenated via
sprintf at runtime.
The following actions are performed to inject the extracted main payload:
CreateProcessis made with dwCreationFlags set to CREATE_SUSPENDED, the first parameter is set to NULL so it creates another process for the current binary.
ZwUnmapViewOfSectionis made to unmap a section of memory from the newly created process, a handle to to created process is passed as the first parameter (hProcess)
FUN_00401559which obtains the “context” of the thread
SetThreadContextis used to set the EAX register to the entry point of the executable written using the previous call
ResumeThreadwhich causes it to execute
We can dump the unpacked main payload by debugging the loader, setting a breakpoint on the unpacking function and capture the buffer containing the unpacked and decrypted resource as it’s being passed into the injection function.
With x64dbg we can follow the lpBuffer parameter in a memory dump and locate it’s memory region and dump it to disk
Once on disk, before being able to analyze it we need to clean it up with HXD (dumping it directly from x64dbg’s memory region window added junk before and after the PE file) and re-sizing it with PeBear (ensure the file size and loaded size match after cleaning it).
Once obtaining the cleaned unpacked main payload, inspecting it in PeStudio reveals a lot of sensitive strings that indicate it’s the main ransomware payload. From here we can perform additional reverse engineering to uncover the ransomware’s functionality.
The malware maintains persistence on the system by setting the
Software\\Microsoft\\Windows\\CurrentVersion\\Run Registry keys for
HKEY_LOCAL_USER. The directory path of a copy of the current process is stored in a value of
msconfig after a call to
RegSetValueExW. The malware attempts to set both the LOCAL_MACHINE and CURRENT_USER key.
Four threads are created:
ShellExecuteExis used to delete the system volume shadow copies via vssadmin.exe
Deleting volume shadow copies:
The malware attempts to delete the systems volume shadow copies using
vssadmin.exe via a call to
ShellExecuteExW. The malware tries to run the command:
vssadmin.exe delete shadows /all /Quiet
A thread executes a function called
kill_processes_by_name, this function is responsible for enumerating current processes and killing specific process by name via a call to
The current processes PID is obtained by calling
GetCurrentProcessId, the PID is checked when terminating processes, processes can’t have the same PID (this ensure the process doesn’t kill itself). The
EnumProcesses function is called to get a listing of the current process, it opens a HANDLE to them and checks the processes name by calling
If a process is running that contains one of the blacklisted subtrings, it’s terminated via a call to
Since this occurs in a loop, the call to
Sleep causes this to happen every 200 milliseconds
|msconfig||MSConfig, used for troubleshooting and managing configurations|
|cmd.exe||Command line utility for Windows|
TeslaCrypt contains network functionality that enables the capability of exfiltrating system information back to a set of embedded TOR based C2 servers. The malware prepares a data buffer containing information such as:
To obtain the systems external IP address, the payload uses
InternetReadFile to reach out to
http://ipinfo.io/ip. The website endpoint returns the external IPV4 IP address, the IP is stored in a char buffer and is passed on to the exfiltration preparation function.
InternetOpenWis used to prepare the network request, it initializes the usage of WinInet, it returns a HANDLE that can be used for subsequent WinInet function calls
InternetOpenWuses the HANDLE returned from
InternetOpenWto make a network request to a domain/IP address
InternetReadFilereads the data obtained from the HTTP response, in this case it’s a
The network requests use a hardcoded HTTP user-agent string
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022 which can be used to identify malicious network requests. In the below image, the censored red data is the returned IPV4 address.
To exfiltrate the prepared data buffer, the malware uses the same WinInet process for making an outbound HTTP GET request to a set of C2 servers. The HTTP requests are sent to the hardcoded
/state1.php endpoint, the data is BASE64 encoded using an OpenSSL encoding function.
The payload loops through a set of embedded C2 servers that use TOR while trying to exfiltrate information
If a C2 server can be contacted it responds with a
---!!!Done!!!--- message to indicate it was successful, the malware checks the buffer returned via a call to
create message window