WannaCry - Malware Analysis

Introduction

The WannaCry malware is a Ransomware crypto-worm that first appeared in May 2017 as a worldwide cyber-attack.

It targets Windows machines by spreading via SMB protocol (port 445) and encrypting all the host files and data, with authors demanding payment in Bitcoin to decrypt and restore the data.

WannaCry infected more than 200,000 computers across 150 countries with a total economic loss of hundreds of millions.

Symptoms of infection

The malware is categorized as ransomware which means the authors mean the target system to know about its activities.

After the malware infected the system, it will change the Desktop background and pop up a window with information about its activities and how to decrypt the infected files:

Files will also be encrypted with a ".WNCRY" extension:

Hash values

MD5DB349B97C37D22F5EA1D1841E3C89EB4
SHA1E889544AFF85FFAF8B0D0DA705105DEE7C97FE26
SHA25624D004A104D4D54034DBCFFC2A4B19A11F39008A575AA614EA04703480B1022C

Static Analysis

Performing static analysis to get some indications about the malware's capabilities and intentions.

Basic information

Using PEStudio:

We can notice it's a PE file (the magic bytes are 4D5A = "MZ") executable, written in C++ and x86 architecture (32-bit).

Trying the hashes in VirusTotal.com, we can notice most AVs flag it:

Using PEView to check if the malware is packed, we can see that the difference between the Virtual Size (size is 0x8BCA) and Size of Raw Data (size is 0x9000) is small, which indicates it is not packed malware:

Strings

Looking for strings in the malware using both Floss and PEStudio, we get the next strings grouped by purpose:

Network functions
InternetOpen, InternetCloseHandle, InternetOpenUrl
Registry functions
RegCreateKey, RegQueryValueEx, RegSetValueEx, RegCloseKey
File system functions
CreateFile, MoveFile, ReadFile, DeleteFile, GetFileSize, GetFilePath, WriteFile, CreateDirectory, GetFileAttributes, SetFileAttributes, GetFullPathName, GetTempFile, FluseFileBuffers, SetFileTime, SetFilePointer, fopen, fclose, fread, write
Services functions
StartService, CloseServiceHandle, OpenSCManager, ChangeServiceConfig2, RegisterServiceCtrlHandler, SetServiceStatus, StartServiceCtrlDispatcher, OpenService, ChangeServiceConfig2
Resources functions
FindResource, LoadResource, LockResource, SizeOfResource
Indication of additional PE files embedded in the malware
The string "This program cannot be run in DOS mode!" (found 4 times)
Cryptographic functions
CryptAcquireContext, CryptDecrypt, CryptEncrypt, CryptGenKey, CryptDestroyKey, CryptGenRandom, CryptImportKey, CryptReleaseContext, rand, srand
Some commands and string formats
%s -m security; Cmd.exe /c "%s"; icacls . /grant Everyone:F /T /C /Q; Attrib +h; %s/%s; %s\Intel; %s\ProgramData; C:\%s\%s; C:\%s\qeriuwjhrf;
Some files names and other strings
diskpart.exe, taskdl.exe, taskse.exe, taskhsvc.exe, tashsche.exe, lhdfrgui.exe, mssecsvc.exe, r.wnry, s.wnry, t.wnry, u.wnry, b.wnry, c.wnry, f.wnry, WNcry@2o17, TaskStart
Bitcoin addresses
115p7UMMngoj1pMvkpHijcRdfJNXj6LrLn, 12tYDPgwueZ9NyMgw519p7AA8isjr6SMw, 13AM4VW2dhxYgXeQepoHkHSQuy6NgaEb94
URLs and network addresses
[http]:iuqeerfsodp9ifjaposdfjhgosurijfaewrwergwea..., \192.168.56.20\IPC$, \%s\IPC$

Also found a large list of file extensions (like ".docx", ".avi", ".jpg" and more) and a large list of strings in the format of "msg/m_LANGUAGE.wnry".

Malware's capabilities using CAPA

CAPA is a tool developed by MITRE to detect software's malicious capabilities by a set of rules. I will use it to scan the malware and have more indications about its abilities:

In conclusion, we can see the malware uses network functions, files and cryptographic functions (To perform the encryption and its installation in the machine). It also uses services and Registry (probably for persistence maintenance) and resource functions to extract other files.

Now, I Will use the indications collected to perform a dynamic analysis of the malware.

Dynamic Analysis

The dynamic analysis takes place inside an isolated Windows 10 machine (victim), with a connection to a REMnux (Linux) machine via a Host-only adapter.

The IP address of the victim machine is 10.0.0.3 and the REMnux machine is 10.0.0.4, the victim machine's DNS resolver is 10.0.0.4 and REMnux will use iNetSim to simulate the internet connection.

We will start by activating the malware, using Wireshark in the REMnux machine to capture packets:

We can notice that the victim machines send an HTTP GET request with the URL we found earlier in the malware's strings. The REMnux machine, using iNetSim, sends a response of "200 OK". In the victim's machine, no other activities taking place.

Using Procmon we can notice:

And after a few seconds:

The process is terminated.

We can assume that succeeding with connection to the URL will cause the malware to terminate.

Let's use the IDA disassembler to understand the flow.

Locate the main function and rename it to "main":

Inside the main function, we can see the URL and the WinAPI functions InternetOpenA and InternetOpenUrlA take place.

InternetOpenUrlA (by the WinAPI documentation) opens a resource specified by a complete FTP or HTTP URL. It returns a handler if successful or a NULL if fails.

EAX holds the return value, moving it to the EDI register which is checked by test opcode to check its value. if not zero, means it holds a pointer to a handler and the connection succeeded - the malware terminates (blue square).

Otherwise, if the value is zero, which means the connection to the URL has failed, the program enters the "sub_408090" function (in red) and is fully activated.

We can conclude that the URL is WannaCry's killswitch.

Now, I will use a few tools to check the different activities that the malware takes place in the victim's machine when the malware is fully activated.

The first tool used is TCPView:

We can see the malware tries to send SYN messages via port 445 (SMB protocol) to the victim's network (we can see the IPs 10.0.0.X), so we can assume that's the way WannaCry is spreading:

After the malware pops up its main window, we can see a new TCP connection established, listening on port 9050:

The next tool used is RegShot:

We will take the first shot before activating the malware and take the second one after its main window pops up. After comparing the values, we can see some interesting keys and values added to the Registry.

Keys added:

Values added:

Looking at the services added:

We can conclude that it registered 2 new services and uses the Registry by writing the executables in the "..\Windows\CurrentVersion\Run\" to start right after booting up.

Both services and Registry entries are used to maintain persistence on the victim's machine.

The next and last tool I use is Procmon, to capture all the activities on the file system and processes:

Firstly, I will look for new files created by process name "Ransomware.wannacry.exe", operation of "CreateFile" and since CreateFile is used to open existing files too, I will filter it with detail containing "OverwriteIf":

And the result is the creation of a "tasksche.exe" file in the "C:\Windows\" directory:

Then, looking at the process tree, we can see the "tasksche.exe" process started with the "/i" argument:

The process ID of the new process is 7568, let's filter by it:

So the new process created a new file with the same name inside the "C:\ProgramData\xpaaslxwir046\" directory.

In the process tree, we can notice the new service registered under "services.exe", with the same name as the malware but running with the "-m security" argument.

Under the "services.exe", we can also see the other service we have seen before:

The "tasksche.exe" process runs a few commands and creates a few processes:

"attrib.exe +h" to hide the directory:

"icacls.exe . /grant Everyone:F /T /C /Q" to grant full access to all users:

Execution of a bat file (script):

Creates "@WanaDecrypt0r@.exe" process:

Creates "taskhsvc.exe" process:

And running the next commands

The full command:

This command is used to prevent the recovery of the infected host - it deletes all shadow copies and recoveries using "vssadmin", "wmic", "bcdedit" and "wbadmin".

Adds new Registry key:

Full command:

And creates processes "taskdl.exe" and "taskse.exe":

In the "C:\ProgramData\xpaaslxwir046\" directory we see the next files:

Those files contain the background of the Desktop (the "b.wnry" file), the ransomware text (the "r.wnry" file), some onion addresses and the Bitcoin address (the "c.wnry" file).

The file "f.wnry" contains 10 files paths which are the same files the malware decrypts to prove its decryption abilities:

The file "u.wnry" is an executable:

And "t.wnry" is another unknown file with a "WANACRY!" header:

WannaCry walkthrough Disassembly

The creation of "tasksche.exe" and new services register

Getting back to the disassembly of WannaCry, let's see how the "tasksche.exe" file is created and activated:

After the URL connection has failed, it continues to the "sub_408090" function which will be renamed to "no_kill_switch":

Inside this function, we can notice 2 routes and the route which the program takes will determine by the number of arguments. Since we started the program without any arguments, we will take the left route ("sub_407F20" - which will be renamed to "no_args_exe"):

Inside this function, we have 2 more function calls:

The first function "sub_407C40" creates a new service of WannaCry with the "-m security" argument called "mssecsvc2.0" (as we saw earlier) with SERVICE_AUTO_START attribute (0x02 dwStartType) and SERVICE_ERROR_NORMAL (0x01 dwErrorControl, which logs the errors but keep the startup operation) and finally starts the service:

I will rename this function to "register_service_mssecsvc2_0" and enter the second function "sub_407CE0":

In the "sub_407CE0" function, a few Windows API functions are imported into pointers, will rename them accordingly with the "ptr_" prefix:

Then, it extracts an embedded resource name "0x727":

The handler for the resource is passed to the EBP register which will be used later.

Next, it creates 2 arrays - "Buffer" and "NewFileName" with the size of 0x40 (64) initialized with 0's.

Then, it inserts the "C:\WINDOWS\tasksche.exe" string into "Buffer" and "C:\Windows\qeriuwjhrf" to "NewFileName", trying to move the "tasksche.exe" file to the other second path if exists.

Whether it succeeded or not, it performs the creation of the "tasksche.exe" file in the "C:\Windows\qeriuwjhrf" path.

ESI will contain the handler.

After the creation of the "tasksche.exe" file, write to it:

By looking at the Windows API documentation - ESI is the handler, EAX contains the pointer to the resource from earlier and the EBP contains the number of bytes of the resource:

So, the "tasksche.exe" gets its data from the embedded resource 0x727.

Lastly, it creates the "tasksche.exe" process with an argument "/i":

As for the "mssecsvc2.0" which created, the second route of WannaCry performs changes on the existing service configurations to respond to failures and configure the main procedure of the service and finally dispatch:

Summary

After analyzing WannaCry we can understand its way of activity:

  • WannaCry starts by trying to reach a URL, if successful - the malware terminates.

    If it fails, WannaCry is activated.

  • Tries to spread via SMB protocol (port 445) in the victim machine network.

  • The malware opens port 9050 on the victim's machine.

  • It has embedded resources that are extracted in the process.

  • Registers 2 new services "mssecsvc2.0" for "Ransomware.wannacry.exe -m security" and "xpaaslxwir046" for "tasksche.exe". By doing it, the malware maintains its persistence on the victim's machine.

  • Register the new services into the "...\Microsoft\Windows\CurrentVersion\Run" key in the Registry to start it automatically after booting up.

  • Hides the directory of "tasksche.exe" and grants full authorizations for it.

  • Deletes and disables recoveries.

  • Performs encryption of most of the files in the host - by encrypting files' data, creating a new file with the same name with the ".WNCRY" extension and deleting the source file.

  • Encrypting 10 files with the ability to decrypt them without an internet connection (embedded decryption key).

  • Changes the Desktop's background and pops up continuously the ransomware window.

  • Keeps encrypting new files, not encrypting files whose file extension is not in the list of strings found (for example ".qwe").

YARA rules

rule wannacry {

    meta:
        last_update = "10/08/2023"
        author = "Ido Abramov"
        description = "wannacry ransomware rule"
        sha256 = "24D004A104D4D54034DBCFFC2A4B19A11F39008A575AA614EA04703480B1022C"

    strings:
        $PE_magic_bytes = "MZ"

        //URL
        $kill_switch_URL = "http://www.iuqeerfsodp9ifjaposdfjhgosurijfaewrwergwea.com" wide ascii

        //Bitcoin wallets
        $bitcoin1 = "115p7UMMngoj1pMvkpHijcRdfJNXj6LrLn" wide ascii
        $bitcoin2 = "12tYDPgwueZ9NyMgw519p7AA8isjr6SMw" wide ascii
        $bitcoin3 = "13AM4VW2dhxYgXeQepoHkHSQuy6NgaEb94" wide ascii

        //Files
        $file1 = "taskse.exe" wide ascii
        $file2 = "taskdl.exe" wide ascii
        $file3 = "tasksche.exe" wide ascii
        $file4 = "taskhsvc.exe" wide ascii
        $file5 = "lhdfrgui.exe" wide ascii
        $file6 = "diskpart.exe" wide ascii

        $r_wnry = "r.wnry" wide ascii
        $s_wnry = "s.wnry" wide ascii
        $t_wnry = "t.wnry" wide ascii
        $u_wnry = "u.wnry" wide ascii
        $b_wnry = "b.wnry" wide ascii
        $c_wnry = "c.wnry" wide ascii
        $f_wnry = "f.wnry" wide ascii

        //More strings
        $str1= "WNcry@2ol7" wide ascii
        $str2 = "C:\\%s\\qeriuwjhrf" wide ascii

        $str3 = "mssecsvc2.0" wide ascii
        $str4 = "\\\\192.168.56.20\\IPC$" wide ascii
        $str5 = "%s -m security" wide ascii

        //Commands
        $cmd1 = "attrib +h" wide ascii
        $cmd2 = "icacls . /grant Everyone:F /T /C /Q" wide ascii

    condition:
        $PE_magic_bytes at 0
        and
        (
            (
                1 of ($bitcoin*)
                or
                $kill_switch_URL
                or
                1 of ($str1,$str2)
                or
                all of ($file*)
                or
                all of ($*.wnry)
            )
            or
            (
                2 of ($str*)
                and
                2 of ($file*)
                and
                2 of ($*.wnry)
                and
                1 of ($cmd*)
            )
        )
}