Demystifying WannaCry: A Deep Dive into Malware Analysis

S Shri Meenaakshi
16 min readOct 10, 2023

--

In the world of cybersecurity, understanding how malware operates and behaves is crucial for developing effective defenses and mitigating threats. One infamous piece of malware that wreaked havoc in 2017 is WannaCry ransomware. In this blog post, we will walk through the process of analyzing WannaCry, both statically and dynamically, to gain insights into its functionality and behavior.

Throughout this blog, I’ll guide you through these processes step by step, ensuring that you gain a deep understanding of WannaCry while prioritizing safety and responsibility.

Note: At the end of this blog I have given key points of the whole analysis , Please do go through for a quick reference…

Static Analysis

Static analysis involves examining a malware sample without executing it. This initial step provides valuable information about the malware’s structure, characteristics, and potential threats.

Dynamic Analysis

Dynamic analysis involves executing the malware in a controlled, isolated environment to observe its behavior.

File Inspection

The journey into WannaCry’s secrets begins with obtaining a sample of the malware, typically labeled as “WannaCry.exe”, refer this link for the sample https://github.com/HuskyHacks/PMAT-labs/tree/main/labs/4-1.Bossfight-wannacry.exe .

Before even running the file, it’s essential to examine its properties using tools like file, PEiD, or PEview. This initial assessment helps us understand the basics, such as the file type and any notable imports , we will look at it one by one.

Strings Analysis

Strings within the binary can often reveal significant information about the malware’s behavior. During this step, we extract and analyze these strings to look for any hardcoded URLs, encryption keys, or any text that may give hints about the ransomware’s functionality.

Upon opening the tool ‘cmder’(Utility software already present in the Flare VM) on the exe, we are able to see all the associated strings data with it.
Command to create a text file that contains the strings :
-> cd path_of_the_sample_
-> floss.exe Ransomware.wannacry.exe > strings.txt (we are directing the output to a text file)

Fig.1

While there are over a thousand strings present within the binary, it’s impractical to individually inspect each one. Among them, you’ll find clusters of random characters interspersed with meaningful words, offering insights from which we can draw inferences.

Within these strings, something suspicious has also been detected.

Fig.2

We can notice a bunch of API calls and it seems they are imported from other executables.

Fig.3

Here we can notice Token replacements , one .exe file , An URL indicator and can come to an conclusion that there are some packed executables.

Fig.4

Can see windows binary like ‘icals’ and the command ‘attrib +h .’ suggests that it has some hidden directory somewhere!

Now moving on Open ‘PE Studio’ and load the binary into it and take a look at the import address table.
We can start from the ‘indicators’ and see if there are any significant indicators there, and it turns out that there are apparently three other packed executables inside of this first stage executable and it does identify the URL.

Fig.5

Also interesting to note here that PE studio is identifying file extensions like a ransomware | wiper , it likely sees the .wrncy extension that is added to each of the files after they are encrypted.

Fig.6

Now let’s go down to the ‘libraries and imports’ and see if we can ascertain anything from this , so among the ones that are identified in the blacklist we find the windows Socket API ideal and the Windows Internet extensions for Win32 API DLL
So we can anticipate that there’s some kind of socket usage here and some kind of internet usage as well.

Fig.7

Let’s go ahead and sort ‘imports’ by blacklist here and take a look at different imports. Now right at the top we find that there are a couple of API’s that are dealing with cryptography.
So we anticipate that this is a ransomware binary , it make sense that the API’s that are imported into the binary are going to deal with crypto

Fig.8

We also correlate that the win socket ws2_32.dll in here for close , receive send different types of socket API calls.
So we’re anticipating that the binary maybe opening ports and maybe attempting remote connections to different ports.

Fig.9

Down here we have the network indicators that were noted in the library, imports InternetopenA URL
And the other one I want to note here is create service and change serive config.
So we may be able to anticipate that there are some kind of service creation with this binary

Fig.10
Fig.11

Checking the difference between the raw and virtual size, we can say that there is a significant difference with which we can conclude that this is a packed exe file and does have hidden payloads inside it.

Fig.12

What conditions are necessary to get the sample to detonate?

WannaCry will attempt to contact a URL, and that URL is that weird long one that we’ve already seen in the strings output and identified in PE studio.
The interesting thing is that if it does make a connection to this weird URL , it does not trigger the payload

Now arm up the binary(Change the extension to .exe)
Now let’s start ‘inetsim’ back up and open ‘wireshark’ in Remnux

Fig.13

Now, let’s go back to Flare VM and run WannaCry as Administrator

Fig.14

We see that after our TCP handshake, we have the HTTP packet that makes a full request URI to http://www.1uqerfsodp9ifjaposdfjhgosurijfaewrwergwea.com/

Fig.15

Now inetsim responds with a 200 OK for this

Fig.16

But if we go back to flare VM we see that this WannaCry does not execute. That is it actually does not execute in case of 200 OK to the callback URL that it it attempting.
So what we would have to do in this case is go back to Remnux and we will give control C kill inetsim.
And in Flare VM open ‘cmder’ and now we will flush out the DNS resolver cache.
Command : ipconfig /flushdns

Fig.17

Therefore the conditions necessary to get the sample to detonate is we need inetsim to be turned off

So we’ve to think about how we want to approach gathering the rest of the network indicators for this sample. One of the other things we can do is use the tools on the endpoint itself to gather network artifacts.

Now go to ‘sysinternalsSuite’ (in C drive) and we’ll go find ‘TCP view’.
And let’s take a look at what happens in TCP view when we detonate this binary, so we will right click and run it as Administrator.
We can notice that there is a whole bunch of traffic going out to port ‘445’ to remote addresses (in this case ,which are169.254.130.1).

Fig.18

This simply means that there’s no real address connectivity presence to be able to make a connection to that , that’s like a auto assigned IP address.
But notice all of the network connections going out on port ‘445’ , ostensibly to what would be different hosts around the network.

So this is super interesting because we’ve actually discovered how WannaCry is trying to propagate itself through the network

Remember: This is a ransomware binary, but it also has worm capabilities.
And the way that it’s able to propagate is through EternlBlue Exploit, which is an exploit against Windows SMB of certain versions, SMB off course uses port ’445'

Now there is one more interesting network indicator here, that is if we let the binary run for a while, we see that there is a new process that spawned ‘takhsvc.exe’ and can see that it opens up a listening port on port ’1950’

Fig.19

Host based indicators:

We’ll go over to ‘Procmon ’(Process Moniter) and open up the ‘Filter’ tab
We will filter on a few different things , we can filter for the ‘Process Name contains wannacry’, which is our process and we can start with ‘Operation is createfile’ So go ahead and hit OK and then run WannaCry as Administrator

Fig.20

One of the first things that we notice is that there is a creation of a file called ‘taskhsvc.exe’ which is in C windows, So we’ll go check that out.

Fig.21

So given that there is another executable that is created from the initial executable, let’s go ahead and drill down on that.
One way to do that is by using the ‘Process tree’(Tab at top )
And it looks like from the original WannaCry binary taskhsvc.exe is unpacked and then run with an argument of /I

Fig.22

Now let’s take the PID(process ID) of the original ransomware binary 3336, and we’ll add that as the parent PID to see if we can identify what taskhsvc.exe might doing. So we will go to filter tab and add ‘Parent PID is 4944’ and hit add and remove the other criteria out given there.

Fig.23

Now we can see that there is a process started and that’s the beginning of the execution of this secondary payload

Let’s go ahead and filter for ‘Operation is createfile’ , add it and hit OK

Fig.24

We see that in C:\ProgramData it appears that there is a strange name directory .

Fig.25

So we can open this up and see that this directory is right here.

Fig.26

And so we can open this up, and this ends up being like a staging area for WannaCry’s execution and unpacking all of it’s packed resources. This is installed as a hidden directory that uses the ‘att_+h’ cmd we saw in statc analysis

Fig.27

So this is the another host based indicator(that is the 2nd stage of WannaCry installing as hidden directory in the c:\ProgramData)

Now when we see the service creation in the Task manager
In Services tab , we can see a service created in the same weird name as the folder name just we saw. And so this is the Persistence mechanism

Fig.28

So this is the service that makes it so that if you restart the computer , WannaCry kicks back on and will re-encrypt anything that’s added to the host let it be USB drive or more files that are added.

Let’s take a look at kill switch function:

Open the tool ‘Cutter’, and we will start by finding the main function, and go to the graph mode view

Fig.29

One of the first things that we can see is that string reference to this weird URL is loaded into ‘esi’ right at the beginning of the program.
Therefore, a whole bunch of arguments are marshaled to be able to make an API call

Fig.30

The first API call that we make is InternetopenA, so this is goin to prep to open up a handle to a given web resource , at this point the contents of ‘eax’ are moved into ‘esi’ and pushed on to the stack as well.

Fig.31

Then once we take a look at the Decompiler tab (down left), here the outcome of the InternetopenA URL is loaded into the register ‘eax’ then it is loaded into the ‘edi’ register.

Fig.32

So basically the InternetopenA will return output as a binary value like yes or no value(1 or 0).
So the binary value is put into the ‘edi’ register.

Fig.33
Fig.34

Now come back to the graph mode, right there is the test instruction for ‘edi’ to test itself and then there will be a jump for whatever is the value of ‘edi’

Fig.35

So if the ‘edi’ value which was the result of the InternetopenA URL , a API call. If ‘edi’ is tested against itself and there is a zero in that value, the Zero flag is set to one. And then this ‘jne’(jump if not equal), the zero flag is evaluated ans whether or not the zero flag is set one of the two things will happen!

So if the outcome of this API call is true, so it reaches out to the specified URL and there is a result meaning the API call succeeds and it says there is a result here , we’re going to this location in memory.

Fig.36

This location cleans up the arguments on the stack and it returns out of the program.
Now the opposite side o that, if this API call reaches out to the URL and there is nothing there, the zero flag will indicate that we’re going to jump to this location .

Fig.37

This location is almost exactly the same thing , but there’s one difference is this function call right here.
If we trace into this, is the rest of the encryption payload ,this installs itself as a service

Fig.38
Fig.39

This opens up and unpacks the rest of the resources in wannacry’s binary
and it will kick off the encryption routine and wreck the computer that it is run on.

So this is the kill switch URL function, and the routine goes like:

-> Check the URL
-> If there s a result , exit out of the program completely.
-> If not result there , run the function call and this function call does every other part of the encryption and payload routine.

So now let’s try to execute the program even if it gets result for that URL that it calls out.
Now run the inetsim on Remnux
Then in Flare VM go to ‘cmder’ and get the DNS resolver cache flushed out Command: ipco nfig/ flushdns

At this point, if we are to arm and detonate this binary, there should be no actual payload detonation because inetsim is up and running.
But let’s load this into a debugger!!!

So open the ‘x32 debugger’ and attach the exe to the executable
Now we want find the main function , so hit F9

Fig.40

Open up the ‘search’ and we’re going to search all modules for a string reference. And search for that wired url(http://www.1uqerfsodp9ifjaposdfjhgosurijfaewrwergwea.com/) in the search bar.
Then go ahead and set a breakpoint (toggle breakpoint)

Fig.41

The idea is that this is going to be loaded into that API call and pushed on to the stack at some point. So we want to find when that happens.
Then go to CPU view and hit F9 one time. And it seems that this is the point in which our random weird URL string is moved onto ‘esi’

Fig.42

And we can correlate that because we see InternetopenA and InternetopenurlA are the API call right here

(Refer these points , Video reference is there after the explanation)

  1. So now the URL has been pushed on to the stack let’s go ahead and step over by hitting F8 of these instructions until we get to the point where the zero flag is evaluated to see if we want to run the rest of the program.
  2. Register ‘edi’ currently has the results of the InternetopenA URL call, and so it is currently not zeroed out (see in stack right side)
  3. Now if we test ‘edi’ against itself, we’ll go ahead and hit F8 once more,
    and the results means that the flag is currently not set, in other words we reached out to this URL.
  4. And now the ‘jne’ is going to evaluate the zero flag and say if it is set to one, go ahead and take the jump, if not , go ahead and continue. Now double click the zero flag(right side) and set it to one , so this jump call is not going to be taken
  5. Then in four more instructions down , we have the method call to the remainder of the payload.
    So even though inetsim is up and running and this HTTP request made to the wired URL was made ‘200 OK’
    In normal operations this binary would take this jump call, and exit out of the program by hitting this return instruction.
  6. But since we manually changed the zero flag to one we are not taking the jump call
    Hit F8(four times), now the reaming parts of the payload is going to be executed.
  7. Now finally hit F8 one more time and the rest of the binaries payload just kicked off and can see that it has encrypted the test of the contents on the desktop!!!

For video reference visit the link given below:

https://drive.google.com/file/d/1UkpbagTPnMym0Xi_levI3lPQsPLEwXfc/view?ts=65259358

Fig.43

Therefore we got WannaCry to execute even though it made a successful call out to tis kill switch URL…

Quick go through:

Q: Record any observed symptoms of infection from initial detonation. What are the main symptoms of a WannaCry infection?
A:
Symptoms include:
- Changed wallpaper on the infected host.
- A program window indicating the host has been infected that has a countdown timer and pay buttons.
- Encryption of files on the host’s file system. Files are encrypted and appended with a `.WNCRY` extension.
- The appearance of a @WanaDecryptor@ executable and a @Please_Read_Me@ text file on the desktop.

Q: Use FLOSS and extract the strings from the main WannaCry binary. Are there any strings of interest?
A:
The most interesting strings are URLs. FLOSS identifies one that is built on the stack at runtime (a **stackstring**) that contains a long, unpronounceable website name.
```
http://www.iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea.com
```

Other strings of interest include UNC paths that call to different remote shares (`\\192.168.56.20\IPC$`, `\\192.168.56.20\IPC$`), a bunch of language pack files in a `msg` directory (`msg/m_korean.wnry`, etc), and the following:

```
%s -m security
C:\%s\qeriuwjhrf
tasksche.exe
icacls . /grant Everyone:F /T /C /Q
WNcry@2ol7
```

Q: Inspect the import address table for the main WannaCry binary. Are there any notable API imports?
A:
Interesting API calls include:
- CryptGetRandom
- CryptAcquireContextA
- InternetOpenA
- InternetOpenUrl
- CreateServiceA
- ChangeServiceConfig2A

Q: What conditions are necessary to get this sample to detonate?
A:
The binary attempts to initiate a connection with the weird URL
```
http://www.iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea.com
```
If a connection is not established, the rest of the ransomware payload is executed.
If a connection is established, the program exits without executing the rest of the ransomware payload.
In a lab setting, this means that INetSim must be turned off in order to detonate the sample.

Q: **Network Indicators**: Identify the network indicators of this malware
A:
Network indicators of this sample include:

- Attempted access of the weird URL.
- A flood of numerous SMB connection requests to non-private remote addresses.
- A secondary process, taskhsvc.exe, opens port 9050 to a LISTENING state and attempts to connect to non-private remote addresses over HTTPS.

Q: **Host-based Indicators**: Identify the host-based indicators of this malware.
A:
Host-based indicators for this sample include:

- A new directory with a random character name is created in C:\ProgramData.
- The directory is set to hidden.
- This new directory contains many unpacked artifacts from WannaCry’s initial detonation.
The artifacts include the taskhsvc.exe executable and a “Tor” directory that unpacks a “tor” program.
- A new service is created to start tasksche.exe as a persistent executable.

Q: Use Cutter to locate the killswitch mechanism in the decompiled code and explain how it functions.
A:
The killswitch operates like this:

- In the main function of WannaCry, the string of the killswitch URL is moved into ECX.
- The arguments for InternetOpenA are pushed onto the stack. The boolean result of InternetOpenA is moved into EAX.
- The arguments for InternetOpenUrlA are pushed onto the stack, including the killswitch URL.
The result of InternetOpenUrlA is moved into EAX. Then, this result is also moved into EDI.
- The handle is closed and the program evaluates the value of EDI.
- If the value is 0x0 (i.e, NULL), WannaCry makes a call to the first function in the payload.
- Else, WannaCry exits without triggering the payload.

Tools :

  1. Cmder
  2. PE Studio
  3. TCPview
  4. Wireshark
  5. ProcMon
  6. Cutter
  7. x32dbg debugger

References :

  1. Malware Sample — https://github.com/HuskyHacks/PMAT-lab

Thanks for reading my blog :)

--

--