WannaCry (also known as WCry or WanaCryptor) malware is a
self-propagating (worm-like) ransomware that spreads through internal
networks and over the public internet by exploiting a vulnerability in
Microsoft’s Server Message Block (SMB) protocol, MS17-010. The href="https://www.fireeye.com/blog/products-and-services/2017/05/wannacry-ransomware-campaign.html">WannaCry
malware consists of two distinct components, one that provides
ransomware functionality and a component used for propagation, which
contains functionality to enable SMB exploitation capabilities.
The malware leverages an exploit, codenamed “EternalBlue”, that was
released by the Shadow Brokers on April 14, 2017.
The malware appends encrypted data files with the .WCRY extension,
drops and executes a decryptor tool, and demands $300 or $600 USD (via
Bitcoin) to decrypt the data.
The malware uses encrypted Tor channels for command and control (C2) communications.
|
|
|
|
|
|
mssecsvc.exe | width="126"> | width="57"> | width="66"> | width="84"> | width="54"> |
tasksche.exe | width="126"> | width="57"> | width="66"> | width="84"> | EXE |
Unavailable | width="126"> | width="57"> | 2009-07-14 | Encryptor | width="54"> |
@WanaDecryptor@.exe | width="126"> | width="57"> | 2009-07-13 | Decryptor | width="54"> |
Table 1: File characteristics
The malware creates the following two registry run keys to ensure persistence:
Value: <Full_path>\tasksche.exe
Value: <Full_path>\tasksche.exe
The malware creates the following service to ensure persistence of mssecsvc.exe:
The malware creates the following service to ensure persistence of tasksche.exe
Loader Files
Encryptor Files
Decryptor Files
The following artifact can be found on remotely exploited systems:
The malware starts by attempting to connect to the following domain with InternetOpenUrl:
NOTE: If this succeeds, the malware immediately exits. For a list of
observed killswitch domains, see Appendix A.
If the connection fails, however, the malware checks the number of
arguments passed to the program. If zero, the malware continues with
installation; otherwise it enters service mode.
Note: Network proxies and other enterprise network security features
may prevent the malware from contacting its killswitch domain and
inadvertently trigger encryption. Organizations may wish to adjust
their proxy configurations or other network configurations to avoid
this problem.
In service mode, the malware first updates the service config so
that failure actions occur if the service exits without entering
a SERVICE_STOPPED state. The malware then executes the service
function, which registers the service handlers and attempts
exploitation of MS17-010 against identified SMB services. This allows
remote code execution and enables spreading across the network. This
execution is performed in a thread, and the service exits after 24
hours regardless of the status of the thread.
The spreader begins by setting up the Windows socket APIs and
generating a RSA crypto context. This crypto context is later used to
generate random numbers. The malware then builds two DLLs in memory –
they are 32 and 64-bit DLLs that have identical functionality. Each
one contains a single export named PlayGame that loads
the W resource, writes it to C:\WINDOWS\mssecsvc.exe, and executes it.
The W resource in each case has been populated with a copy of the
running binary (MD5: db349b97c37d22f5ea1d1841e3c89eb4).
The malware continues by spawning two threads, the first thread
enumerates the network adapters and determines which subnets the
system is on. The malware then generates a thread for each IP on the
subnet. Each of these threads attempts to connect to the IP on
port 445 and, if successful, attempts exploitation of the service via
a vulnerability described in MS17-010. An example of an attempt to
exploit MS17-010 on a remote system can be seen in Figure 1.

Figure 1: WannaCry network traffic attempting
SMB exploit
One of the unique features of this traffic is an SMB Tree Connect
AndX Request containing the following UNICODE string:
This packet is hand-crafted and hard-coded into the malware.
The second thread generates random IPs and attempts to connect to
them on port 445. If the connection is successful, the malware then
attempts to perform the SMB attack on the system. 128 instances of the
second thread area created with two seconds separating each thread creations.
The malware continues by creating a service
named mssecsvc2.0 with a binary path pointing to the running
module with the arguments "-m security". Once created, the
malware starts the service. The malware then locates its R resource
and loads it into memory. The malware then writes the R resource data
to the file C:\WINDOWS\tasksche.exe. The malware executes
C:\WINDOWS\tasksche.exe /i with the CreateProcess API. The malware
then attempts to
move C:\WINDOWS\tasksche.exe to C:\WINDOWS\qeriuwjhrf,
replacing the original file if it exists.
The malware begins by generating a unique identifier based on the
computer name. The identifier, <sys_id>, has the form of
8-15 random lowercase characters followed by 3 numbers. The malware
then checks to see if it was passed the /i argument.
The /i command copies the running binary to
<system_drive>\ProgamData\<sys_id>\tasksche.exe if <system_drive>\ProgamData exists,
otherwise it will be copied
to <system_drive>\Intel\<sys_id>\tasksche.exe. <system_drive>is
the drive letter on which Windows was installed (C:\ for C:\Windows).
The malware then updates its current directory to the created directory.
The malware then attempts to open the service
named <sys_id>. If it does not exist, the malware creates
it with a DisplayName of <sys_id> and a BinaryPath of cmd
/c <path_to_copied tasksche.exe>. The malware then starts
the service. The malware attempts to open the
mutex Global\MsWinZonesCacheCounterMutexA0. If the mutex is not
created within 60 seconds, the malware re-lauches itself from the new
installation directory with no arguments. The malware then waits 60
seconds for the mutex to be created. If the mutex is created in either
instance, the initial executable exits. If the mutex fails to be
created, the malware continues as if it was run without the /i argument.
The malware updates %CD% to the path of the running module and
sets HKLM\Software\WanaCrypt0r\wd to %CD%. The malware then loads the
XIA resource and decompresses numerous files (see Table 3) to %CD%.
The malware then opens %CD%\c.wnry (the configuration data) and
loads it into memory. It expects the file to be of size 0x30C. The
malware then chooses randomly between the three
strings 13AM4VW2dhxYgXeQepoHkHSQuy6NgaEb94, 12t9YDPgwueZ9NyMgw519p7AA8isjr6SMw,
and 115p7UMMngoj1pMvkpHijcRdfJNXj6LrLn; writes it to offset 0xB2 in
the configuration file; and writes the updated configuration data back to %CD%\c.wnry.
The malware then sets the hidden attribute for %CD% by executing the
following command with CreateProcess:
The malware then executes the following command – granting all users
permissions to %CD% and all of its subdirectories:
The malware then imports the hard-coded RSA Private key, shown in
Figure 2.

Figure 2: Imported private key
The malware then opens and reads %CD%\t.wnry. The first 8
bytes of the file are checked to match the magic value WANACRY!. The
file has the following structure:

The encrypted key decrypts to the 128-bit AES
key BEE19B98D2E5B12211CE211EECB13DE6. This key can then be used to
decrypt the enc_data. The decrypted data is saved as a DLL (MD5:
f351e1fcca0c4ea05fc44d15a17f8b36). This DLL is then manually loaded
into memory and the TaskStart export is called.
The TaskStart export of the decrypted DLL is the encryption component
of the ransomware.
The files shown in Table 2 are extracted from the XIA resource. They
are dropped into the %CD% of the running malware.
|
|
|
r.wnry | valign="top"> | width="171" valign="top"> |
s.wnry | valign="top"> | width="171" valign="top"> |
t.wnry | valign="top"> | width="171" valign="top"> |
taskdl.exe | width="212" valign="top"> | *.WNCRYT file deletion |
taskse.exe | width="212" valign="top"> | Utility used to launch |
u.wnry | valign="top"> | width="171" valign="top"> |
b.wnry | valign="top"> | width="171" valign="top"> |
c.wnry | valign="top"> | width="171" valign="top"> |
Table 2: XIA extracted resources
Table 3 shows RTF documents containing the ransom note in various languages.
|
|
m_bulgarian.wnry | width="225" valign="top"> |
m_chinese (simplified).wnry | valign="top"> |
m_chinese (traditional).wnry | valign="top"> |
m_croatian.wnry | width="225" valign="top"> |
m_czech.wnry | width="225" valign="top"> |
m_danish.wnry | width="225" valign="top"> |
m_dutch.wnry | width="225" valign="top"> |
m_english.wnry | width="225" valign="top"> |
m_filipino.wnry | width="225" valign="top"> |
m_finnish.wnry | width="225" valign="top"> |
m_french.wnry | width="225" valign="top"> |
m_german.wnry | width="225" valign="top"> |
m_greek.wnry | width="225" valign="top"> |
m_indonesian.wnry | width="225" valign="top"> |
m_italian.wnry | width="225" valign="top"> |
m_japanese.wnry | width="225" valign="top"> |
m_korean.wnry | width="225" valign="top"> |
m_latvian.wnry | width="225" valign="top"> |
m_norwegian.wnry | width="225" valign="top"> |
m_polish.wnry | width="225" valign="top"> |
m_portuguese.wnry | width="225" valign="top"> |
m_romanian.wnry | width="225" valign="top"> |
m_russian.wnry | width="225" valign="top"> |
m_slovak.wnry | width="225" valign="top"> |
m_spanish.wnry | width="225" valign="top"> |
m_swedish.wnry | width="225" valign="top"> |
m_turkish.wnry | width="225" valign="top"> |
m_vietnamese.wnry | width="225" valign="top"> |
Table 3: Ransom notes in various languages
The TaskStart export takes two arguments; the handle to the
module and an integer that must be zero. TaskStart first
creates a mutex named "MsWinZonesCacheCounterMutexA" and
reads the contents of c.wnry from the current directory. If the
mutex exists or c.wnry is not present, the malware exits. The
malware creates another mutex named "Global\MsWinZonesCacheCounterMutexA0".
The malware then loads and verifies a key from the file
00000000.dky. The malware then attempts to load a key
00000000.pky. If the key does not exist, the malware imports a
public RSA key (seen in Figure 3), generates a new 2048-bit RSA key
and saves the public key to 00000000.pky. The malware then
saves the generated private key to 00000000.eky, encrypted with
the embedded public key.

Figure 3: Public RSA key
The 00000000.eky starts with the number of bytes in little
endian (0x500) followed by the encrypted key.
The malware launches a thread that writes 136 bytes to
00000000.res every 25 seconds. The buffer written includes the
current time of the system. If the file 00000000.res does not
exist while the malware is initializing, it creates the file. The
initial contents begins with eight randomly generated bytes followed
by 128 zero bytes.
The malware launches another thread that verifies it can encrypt and
decrypt using the keys contained in 00000000.dky and
00000000.pky every 25 seconds. If the decryption is successful,
the malware sets a global flag that stops the encryption process.
The malware launches another thread that scans for new drives
attached to the system every three seconds. If a new drive is attached
to the system and is not identified as a type CDROM drive, the malware
begins the encryption process on the new drive. On new drives attached
to the system, the malware may create the directory
<Drive_letter>:\$RECYCLE and execute the following command:
The malware creates a thread that executes the process
taskdl.exe every 30 seconds.
and creates another thread that executes either of the following two
binaries (depending on administrator permissions and if the malware is
running at system level):
A registry key name starting with 8 to 15 characters between 'a' and
'z' followed by three random values between '0' and '9' is then
generated by the malware. It may then create the following registry
paths with the generated key name:
To create the registry key, the malware executes the following command:
The malware loads another embedded RSA public key shown in Figure 4.

Figure 4: Additional embedded RSA public key
The malware executes the file @WanaDecryptor@.exe with the
argument "fi". This appears to be an initial check-in with
the server and the response may contain an updated bitcoin address.
The malware updates c.wnry with the current time at offset 0x60.
The malware then copies u.wrny to @WanaDecryptor@.exe
and executes the script shown in Figure 5 to create
@WanaDecryptor@.exe.lnk. The script is saved to a randomly
generated filename based on the current time and a random value using
characters from '0' to '9'. Example filename: "188391494652743.bat".

Figure 5: WannaCry internal script for moving
and deleting files
The malware then writes either "$<Value>worth of
bitcoin" or "%.<Value> BTC" depending on
the configuration – followed by the contents of the file r.wnry
to @Please_Read_Me@.txt, which reads as follows:
Q: What's wrong with my files?
A: Ooops, your important files are
encrypted. It means you will not be able to access them anymore until
they are decrypted.
If you follow our instructions, we
guarantee that you can decrypt all your files quickly and
safely!
Let's start decrypting!
Q: What do I do?
A: First, you need to pay service fees
for the decryption.
Please send <Ransom Amount>
to this bitcoin address: <Bitcoin_address>
Next, please find an application
file named "@WanaDecryptor@.exe". It is the decrypt
software.
Run and follow the instructions! (You may need to
disable your antivirus for a while.)
Q: How can I trust?
A: Don't worry about decryption.
We will decrypt your files surely because nobody will trust us if
we cheat users.
* If you need our assistance, send a
message by clicking <Contact Us> on the decryptor window.

Figure 6: Encryption warning displayed to user
The malware then targets files on the user's desktop and documents
folders. When the malware starts scanning a directory it creates a
temporary file with the prefix "~SD", and deletes it if successful.
When selecting which files to encrypt, the malware skips over files
with .exe, .dll, and .wncry extensions. The files with the extensions
shown in Figure 7 are selected for encryption. Files larger than
209,715,200 bytes may also be encrypted.

Figure 7: Files targeted for encryption
The malware may ignore folders with the following names:
The malware will also compare folder names with the following
string, and avoid encryption if identified:
Note: The string contains a leading whitespace. This particular
check is likely included for testing/development purposes.
When a directory contains a file that will be encrypted, the malware
copies @Please_Read_Me@.txt and @WanaDecryptor@.exe to
the directory. It verifies that the first eight bytes do not contain
the string WANACRY! and performs additional checks on the
header to verify the file is not already encrypted.
The files are encrypted with a randomly generated 128-bit AES key in
CBC mode with a NULL initialization vector. The key is generated per
file, is encrypted with the generated RSA public key, and included in
the encrypted file header. Each file encrypted by the malware starts
with the string WANACRY! and has the WNCRY extension.
Depending on the file properties, the malware may also stage files in
a WNCRYT extension.
Table 4 shows the file format of encrypted files.
|
|
0x0000 | valign="top"> |
0x0008 | valign="top"> |
0x000C | valign="top"> |
0x010C | valign="top"> |
0x0110 | valign="top"> |
0x0118 | valign="top"> |
Table 4: Encrypted file format
When encrypting the AES key with RSA, the malware may use the
embedded RSA key or a key randomly generated. If the file
f.wnry does not exist during initilazation, the malware
generates a random number if the file size is less than 209,715,200
bytes. If the number is a multiple of 100, the malware uses the
embedded RSA key to encrypt the AES key. A maximum of ten files can be
encrypted with this key. When an AES key is encrypted with this RSA
key, the malware writes the file path to the file f.wnry. If
the random number is not a multiple of 100 or the file f.wnry
already exists on the system, the malware will encrypt the AES key
with the randomly generated RSA key.
Once the malware completes encrypting the desktop and documents
folders, it executes the following commands:
The malware then encrypts files found on logical drives attached to
the system that are not type DRIVE_CDROM.
The malware may execute the command:
The malware executes the command:
The malware will copy b.wnry to @WanaDecryptor@.bmp
and place it in each user’s desktop folder, as well as a copy of @WanaDecryptor@.exe.
The malware communicates with an Onion server using a Tor server
running on local host TCP port 9050. The malware registers the system
with the Onion server, transferring encryption keys and deleting
volume shadows. Once the ransom is paid, the malware obtains the
decrypted RSA private key from the Onion server and decrypts ransomed files.
It first attempts to read the contents of the registry path
HKLM\Software\WanaCrypt0r\wd. If this fails, the malware attempts to
read the contents from a similar registry path within the HKCU
registry hive. If one of the registry paths exists, the malware sets
the current directory to value read from the registry.
The malware attempts to open c.wnry from the current
directory and read 780 bytes if it exists. If the file does not exist,
the file is created with the contents shown in Figure 8.

Figure 8: Contents of c.wnry
The value at offset 0x6c (0x59140342) in c.wnry is the
timestamp the file was created. The remaining values are hardcoded
within the binary.
The decryptor component accepts the command line arguments shown in
Table 5.
|
|
fi | Connects to an |
co | Appears to be an |
vs | Deletes volume |
Table 5: Accepted commands
fi Argument
The malware reads 136 bytes from the file "00000000.res"
in the current path. If the file does not exist the malware exits. The
malware reads two URLs from c.wnry at offsets 0x242 and 0x1DE.
The first URL at offset 0x1DE in c.wnry is:
The alternate URL at offset 0x242 is not configured.
The malware then binds a TCP socket to the localhost (127.0.0.1) and
connects to port 9050 on the localhost.
The malware then checks if the path
"TaskData\Tor\taskhsvc.exe" exists. If the file does
not exist it is extracted from the archive s.wnry. If
s.wnry does not exist, the malware downloads the first URL in
the configuration – and if this fails it attempts the second.
When downloading from a URL, the downloaded file is first saved to a
filename generated with GetTempFileNameA with a "t" prefix
within the TaskData folder. The downloaded file is a Zip archive that
is extracted to the "TaskData" folder.
Once extracted, the malware copies
"TaskData\Tor\tor.exe" to
"TaskData\Tor\taskhsvc.exe" and executes it.
The malware parses the string obtained at offset 0xE4 in the
configuration file c.wnry for Onion servers to connect to. The
Onion servers listed in the configuration file are as follows:
The malware sends the first eight bytes of the file
00000000.res, the host name, user name and the string
"+++" to the Onion server. The command and control protocol
appears to be custom and XOR encoded with a randomly generated buffer.
The response from the server is added to c.wnry if the string
is 30 to 50 characters in length. The following is an example message
sent to the server:
co Argument
This argument the malware scans for file names in the format
<8_Uppercase_Hex>.res. The file the malware is likely
looking for is 00000000.res that is created by the encryption
DLL. The malware then generates a C2 message containing four values
(Table 6) obtained from the ".res" file in the following format:
Note: In the aforementioned example, the values are separated with a
TAB character.
|
|
--- | Hard-coded |
Time0 | Time value |
Time1 | Time value |
Unknown int0 | width="347"> |
Unknown long | 64-bit |
Index | Count of the |
Table 6: C2 message values
Figure 9 shows an example of a message.

Figure 9: Sample C2 message
After sending the message, the malware exits.
vs Argument
The malware sleeps for 10 seconds and then executes the following
command using CreateProcess or RunAs (depending on group membership):
No Argument
The malware copies b.wnry from the current directory to the
desktop with the filename @WanaDecryptor@.bmp. The desktop
wallpaper is then set to the path of the bitmap and the dialog shown
in Figure 6 is then displayed.
When the user clicks on the "Contact us" link, the malware
sends the message to the Onion server using the following format:
Depending on the response from the server, the malware may display a
message box with one of the following values:
When the user clicks on "Check Payment". The malware first
check if the file 00000000.dky is present on the system. If the
file is present, it attempts to verify the key by encrypting a file
with the key obtained from 00000000.pky and decrypting it with
the key obtained from 00000000.dky.
If the file is not present, the malware sends the contents of
00000000.eky to the Onion server. The response from the server
is saved to 00000000.dky. If the key cannot be validated, the
malware displays a message box with the contents:
You did not pay or we did not confirmed
your payment!
Pay now if you didn't and check again after 2
hours.
Best time to check: 9:00am - 11:00am GMT from Monday to Friday.
When the decrypt button is clicked without the ransom being paid,
the malware decrypts the files listed in f.wnry. The files
listed in f.wnry are those randomly selected to be encrypted
with the embedded public key. This process is covered in the
Encryption component section above.
(MD5: db349b97c37d22f5ea1d1841e3c89eb4)
(MD5: 84c82835a5d21bbcf75a61706d8ab549)
(MD5: f351e1fcca0c4ea05fc44d15a17f8b36)
(MD5: 7bf2b57f2a205768755c07f238fb32cc)