Skip Navigation
BlackBerry Blog

Threat Spotlight: Inside the WannaCry Attack


Over the past few weeks, organizations and individuals have either felt or witnessed the impact of WannaCry as it has swept the globe, wreaking havoc and disrupting services for a range of public and private sector companies. WannaCry has been a highly prominent outbreak, due in part to the infection of high-profile targets, such as the National Health Service in the UK and Telefonica in Spain, and also due to the use of novel exploits developed by the NSA and subsequently leaked by the Shadow Brokers.

As discussed in a previous Threat Spotlight, Cylance has been actively tracking WannaCry to ensure that we protect against all variants discovered in-the-wild. Considering the impact, it was felt that a deep-dive analysis was required, documenting the techniques that made this ransomware such a prevalent and media centric threat.

Also, yes, you’re protected if you’re using Cylance.


WannaCry is highly modular in composition, comprising the following main components:

  • Dropper (mssecsvc.exe)
  • Worm payload DLL (loader.dll)
  • Ransomware service (tasksche.exe)
  • Ransomware payload DLL (t.wnry)
  • User-interface (@WanaDecryptor@.exe)
  • RDP process injection utility (taskse.exe)
  • File deletion utility (taskdl.exe)
  • Tor client bundle (

The remainder of this article provides technical analysis of each of the components, outlining the complete life-cycle of the malware, from installation and propagation through to the ransomware payload and auxiliary modules.


The worm-enabled version of WannaCry arrives as a 3.7 MB, 32-bit Portable Executable (PE) that comprises a self-extracting archive, embedded executable resource, an installation routine and a service dispatcher function responsible for executing the worm propagation mechanism. The initial entry-point of the malware contains a condition check, and will terminate execution if it can contact the following URL (Fig.1): 

Figure 1: Kill-Switch Check

This condition check has come to be known as the “kill-switch,” as shortly after appearing in the wild, the domain was sink-holed, eliciting a successful connection as part of the check and therefore causing the malware to terminate. It is worth noting that due to the access type parameter supplied to the InternetOpenA API, the condition check will bypass any configured proxy servers and attempt to resolve the host name directly, which may fail in certain corporate environments, and therefore allow the malware to run regardless of the sinkhole.

Providing the kill-switch domain fails to respond, the malware will proceed to the installation routine. First, it will create and start a service called mssecsvc2.0 in order to run another instance of itself with the parameters "-m security" in the context of services.exe (Fig. 2).

Figure 2: Creation of mssecsvc2.0 Service

The resulting service instance will try to spread WannaCry through an SMB exploit on any vulnerable computers both on the local network and wider internet (the spreading mechanism is described in more details in the section "Propagation").

In the next step, the dropper unpacks an embedded executable from its "R/1831" resource to C:\Windows\tasksche.exe, and executes the installation routine with the "/i" parameter (Fig. 3).

Figure 3: Resource Loading

The newly created tasksche.exe process will generate a pseudo random string using a checksum of the computer name as a seed for the srand() function. The generated string is composed of fourteen lowercase letters and three numbers, and will be used as a name for both the service and the installation directory to be created under one of the following paths, depending on availability:

  • %SYSTEMDRIVE%\ProgramData
  • %TEMP%

Once the installation folder is created, tasksche.exe is copied there and installed as a service to ensure it runs on every startup. Finally, the process spawns a new instance of itself that will extract the remaining components from an embedded archive and start the ransomware encryption process.


The worm/exploit functionality is contained within a service dispatch routine (Fig. 4) that utilizes the EternalBlue exploit and DoublePulsar backdoor to leverage the MS17-010 SMB vulnerability and propagate to vulnerable systems.

Figure 4: Service Dispatcher Routine

When run as a service, the initial dropper will first try to initialize WinSock and extract both x86 and x64 versions of launcher DLL (6fad24afea23fbe7f51e912134e31f24d65148268c3a51c0a16ba6d26884c38f and f0759600e7df8e79ecd1e4e1fa202d3004404f98a9134e35c231c671f1856733 respectively) from the .data section to allocated memory. It will only proceed further if the above actions are successful. There are two separate threads created to spread WannaCry both globally and inside the local network simultaneously (Fig. 5).

Figure 5: SMB Propagation Threads

LAN propagation thread - execution flow:

  • Get IP addresses of local network interfaces using GetAdaptersInfo API.
  • Generate a list of all possible IP addresses in any available local network and try to connect to them.
    • For each successful connection, create the exploit thread with the IP address as the parameter.

WAN propagation thread - execution flow:

  • In a loop, generate a random global IP address with the use of CryptGenRandom() modulo 255, and skip all addresses starting with 127, 224 (or higher) or LAN addresses calculated above;
              -> Try to connect to the generated IP, and if successful, iterate through all the addresses in the /24 subnet and create an exploit thread with the IP address as the parameter for each successful connection;
  • Global IP addresses are generated as follows: The first octet of a new IP address range is generated every 40 minutes; the second octet is generated every 20 minutes and the remaining octets are generated on each iteration (Fig. 6).

Figure 6: Random Global IP Generation Routine

The exploit thread has the following flow of execution:

  • Check if the remote machine is vulnerable to MS17-010:
              -> Connect to the remote machine on port 445.
              -> Send SMB_COM_NEGOTIATE and SMB_COM_SESSION_SETUP_ANDX packets to establish an SMB session (Fig. 7 and 8).
              -> Connect to the IPC$ share on remote machine by sending SMB_COM_TREE_CONNECT_ANDX packet with TreeID set to \\<ip_address>\IPC$ and UserID set to the value returned by the server in the previous response (Fig. 8).
              -> Check for MS17-010 vulnerability by sending an SMB_COM_TRANSACTION packet, containing PeekNamedPipe subcommand set to FileID = 0 (Fig. 9 and 11).
              -> Check for the error response code 0xC0000205 (STATUS_INSUFF_SERVER_RESOURCES). This means the machine is vulnerable (Fig. 10 and 11).

Figure 7: SMB Negotiate Packet

Figure 8: SMB Vulnerability Check Conversation

Figure 9: SMB Vulnerability Check

Figure 10: SMB Response if Machine is Vulnerable (Error Code 0xC0000205 Highlighted)

Figure 11: MS17-010 SMB Vulnerability Check

Regardless of the vulnerability status, the code first checks for the presence of the DoublePulsar backdoor:

  • Connect to the remote machine on port 445.
  • Send SMB_COM_TRANSACTION2 packet.
  • If the remote machine is infected with DoublePulsar, then the MultiplexID field in the response will be equal to 0x51 (Fig. 12).

Figure 12: Check if DoublePulsar is Already Installed

If the remote machine is already infected with DoublePulsar, then it is leveraged to transfer the launcher DLL and run the payload:

  • Send SMB_COM_TRANSACTION2 packet.
  • Check the SecurityFeatures->CID field from the server's response to determine victim's architecture (0 = x86, 1 = x64).
  • Generate an encryption key based on SecurityFeatures->Key field from the server's response.
  • Use the generated key to XOR-encrypt the appropriate version of launcher DLL and shellcode.
  • Send encrypted shellcode (Fig. 13) and launcher DLL inside SMB_COM_TRANSACTION2 packet. •  DoublePulsar will then execute the shellcode, which in turn will load launcher DLL into the memory and invoke its PlayGame export.

Figure 13: Decrypted Shellcode Resolving Required NT Kernel APIs

If there is no DoublePulsar running, but the remote machine is vulnerable, it will use the embedded EternalBlue exploit to deliver the DoublePulsar backdoor payload:

  • Generate SMB packets to be sent to the victim machine to remotely exploit it (Fig. 14):
    • -> Prepare packets needed to establish the SMB session (SMB_COM_NEGOTIATE, SMB_COM_SESSION_SETUP_ANDX, SMB_COM_TREE_CONNECT_ANDX).
    • -> Prepare SMB_COM_NT_TRANSACT packet needed to trigger the vulnerable SrvOs2FeaToNt function inside srv.sys file on the remote machine (Fig. 16).
    • -> Prepare all subsequent SMB_COM_TRANSACTION2_SECONDARY packets containing chunks of base64 encoded shellcode. Each packet is 10,024-bytes long, comprising a 4-byte size field followed by 20-bytes of supporting data and then a 10,000-byte SMB packet (Fig. 15).
  • Initiate SMB conversation using prepared packets.
  • Deliver shellcode that will inject launcher.dll on the remote machine and invoke its PlayGame export.

Figure 14: Prepare Exploit and Shellcode

Figure 15: SMB Transaction2 Packet

Figure 16: SMB NT Transaction Packet

Launcher.dll has only one exported function, PlayGame, that will extract the original dropper binary from resource W/101 to C:\Windows\mssecsvc.exe on the compromised machine and run it using the CreateProcessA API (Fig. 17).

Figure 17: Launcher.dll

Ransomware Installer

While the initial dropper/worm is busy spreading the malware across the network, the second instance of tasksche.exe takes care of extracting and running the remaining ransomware components. The contents of a password protected ZIP archive (stored inside the embedded "XIA" resource) is extracted to the installation directory using the password WNcry@2ol7.

The installation path is saved in the "wd" registry value under the HKEY_LOCAL_MACHINE\SOFTWARE\WanaCrypt0r key. All files are then concealed by changing their attributes to HIDDEN, before access is granted to all users (Fig. 18).

Figure 18: Resource Unpacking

The ZIP archive contains the components shown in Fig. 19:

Figure 19: Dropped Files (With Size, Modification Date and SHA256 Checksums)

The complete list of dropped files is as follows:

•  b.wnry - Bitmap file with ransom note for desktop background
•  c.wnry - Configuration file
•  r.wnry - Text file with FAQ
•  s.wnry - ZIP archive containing Tor:
          -  Data/Tor/ (empty)
          -  Tor/libeay32.dll
          -  Tor/libevent_core-2-0-5.dll
          -  Tor/libgcc_s_sjlj-1.dll
          -  Tor/ssleay32.dll
          -  Tor/zlib1.dll
          -  Tor/libevent-2-0-5.dll
          -  Tor/libevent_extra-2-0-5.dll
          -  Tor/libssp-0.dll
          -  Tor/tor.exe
          -  (Same hashes as files contained in the official troproject archive:
          -  hxxps://dist.torproject(dot)org/torbrowser/6.5.1/
•  t.wnry – Encrypted ransomware payload DLL
•  taskdl.exe - Small utility to delete files
•  taskse.exe - Small utility to run a process
•  u.wnry - UI executable
•  msg - Folder containing localized ransomware messages:

          -  m_bulgarian.wnry
          -  m_chinese (simplified).wnry
          -  m_chinese (traditional).wnry
          -  m_croatian.wnry
          -  m_czech.wnry
          -  m_danish.wnry
          -  m_dutch.wnry
          -  m_english.wnry
          -  m_filipino.wnry
          -  m_finnish.wnry
          -  m_french.wnry
          -  m_german.wnry
          -  m_greek.wnry
          -  m_indonesian.wnry
          -  m_italian.wnry
          -  m_japanese.wnry
          -  m_korean.wnry
          -  m_latvian.wnry
          -  m_norwegian.wnry
          -  m_polish.wnry
          -  m_portuguese.wnry
          -  m_romanian.wnry
          -  m_russian.wnry
          -  m_slovak.wnry
          -  m_spanish.wnry
          -  m_swedish.wnry
          -  m_turkish.wnry
          -  m_vietnamese.wnry

Once all files are extracted, the malware parses the configuration file and saves the data in memory for later use. It then picks from one of the following hard-coded Bitcoin Wallet IDs and writes it back to the config file (Fig. 20);

•  13AM4VW2dhxYgXeQepoHkHSQuy6NgaEb94
•  115p7UMMngoj1pMvkpHijcRdfJNXj6LrLn
•  12t9YDPgwueZ9NyMgw519p7AA8isjr6SMw

Figure 20: Write Bitcoin Wallet ID

Besides the freshly added wallet IDs, the configuration also contains a list of Tor .onion addresses used to communicate with the command and control (C&C) server and a link to an official TOR browser package (Fig. 21):

Figure 21: Configuration File Contents

Next, the main ransomware payload (stored as an encrypted DLL within t.wnry) is decrypted and executed. In order to decrypt the DLL, the malware first extracts one of the public RSA keys hard-coded within its data section (Fig. 22) and uses it to decrypt the AES key stored at the beginning of t.wnry.

Figure 22: RSA Public Key

The decrypted AES key (Fig. 23) is then used to decrypt the DLL.

Figure 23: Decrypted Key in Memory (Highlighted)

Once decrypted, the DLL is loaded directly into memory and invoked by calling the TaskStart exported function (Fig. 24).

Figure 24: Loading Ransomware Payload DLL and Calling TaskStart Entry-Point

Ransomware DLL

Invoked by TaskStart, the DLL is responsible for the encryption of files on the infected machine. To achieve this, it starts by creating a new mutex named "MsWinZonesCacheCounterMutexA", and four configuration files, as listed below:

After creating the configuration files, the ransomware payload DLL is almost ready to start encrypting files. Five threads are spawned, and a new global mutex named "Global\\MsWinZonesCacheCounterMutexW" is created.

Thread 1 (timestamp thread):

•  Responsible for writing the current timestamp to 00000000.res file if an internal flag is not set.

Thread 2 (test thread):

•  Performs a logical check for the 00000000.pky and 00000000.dky files. If these files exist, then the string “TESTDATA” is encrypted with the key read from 00000000.pky. After which, at 5 second intervals, the file is decrypted using the key contained in 00000000.dky, until successful decryption.  

Thread 3 (ransom thread):

•  Stage one is to enumerate all logical drives and remove %systemdrive%\$RECYCLE\hibsys.WNCRYT files from any drives of type FIXED. The deletion routine includes overwriting the file with zeroes, and renaming it to \x00 before deleting it from the disk. After this, stage two iterates over all directories for files with the following extensions and encrypts them:

.docx, .docb, .docm, .dot, .dotm, .dotx, .xls, .xlsx, .xlsm, .xlsb, .xlw, .xlt, .xlm, .xlc, .xltx, .xltm, .ppt, .pptx, .pptm, .pot, .pps, .ppsm, .ppsx, .ppam, .potx, .potm, .pst, .ost, .msg, .eml, .edb, .vsd, .vsdx, .txt, .csv, .rtf, .123, .wks, .wk1, .pdf, .dwg, .onetoc2, .snt, .hwp, .602, .sxi, .sti, .sldx, .sldm, .sldm, .vdi, .vmdk, .vmx, .gpg, .aes, .ARC, .PAQ, .bz2, .tbk, .bak, .tar, .tgz, .gz, .7z, .rar, .zip, .backup, .iso, .vcd, .jpeg, .jpg, .bmp, .png, .gif, .raw, .cgm, .tif, .tiff, .nef, .psd, .ai, .svg, .djvu, .m4u, .m3u, .mid, .wma, .flv, .3g2, .mkv, .3gp, .mp4, .mov, .avi, .asf, .mpeg, .vob, .mpg, .wmv, .fla, .swf, .wav, .mp3, .sh, .class, .jar, .java, .rb, .asp, .php, .jsp, .brd, .sch, .dch, .dip, .pl, .vb, .vbs, .ps1, .bat, .cmd, .js, .asm, .h, .pas, .cpp, .c, .cs, .suo, .sln, .ldf, .mdf, .ibd, .myi, .myd, .frm, .odb, .dbf, .db, .mdb, .accdb, .sql, .sqlitedb, .sqlite3, .asc, .lay6, .lay, .mml, .sxm, .otg, .odg, .uop, .std, .sxd, .otp, .odp, .wb2, .slk, .dif, .stc, .sxc, .ots, .ods, .3dm, .max, .3ds, .uot, .stw, .sxw, .ott, .odt, .pem, .p12, .csr, .crt, .key, .pfx, .der

Each file is encrypted using a uniquely generated AES key, which is then encrypted with the public RSA key and stored inside the file's header (Fig. 25). Encrypted files are renamed with the file extension .WNCRY (Fig. 26). The malware will randomly choose ten files belonging to the user to serve as proof that decryption is possible, and save their paths to f.wnry. These files will be encrypted with the use of another RSA key, to allow for decryption without having to obtain a private key from the server.

The format of an encrypted file's header is as follows:

•  8-byte ‘WANACRY!’ signature
•  4-byte size of encrypted AES key
•  Variable size encrypted AES key
•  4-byte encryption type (only 0x03 and 0x04 are implemented in the current version)
•  4-byte size of decrypted data

Figure 25: Encrypted Ransomware Payload DLL Contained Within t.wncry; the Same Format is Used For Encryption of User's Files

Figure 26: File Encryption Routine; Only Options 3 and 4 are Implemented

Thread 4 (helper thread):

•  This thread executes taskdl.exe every 30 seconds. The taskdl process is responsible for enumerating drives and deleting any temporary versions of encrypted files in <drive>:\$RECYCLE\ or <drive>:\%TEMP%, in case encryption/decryption of “TESTDATA” fails.

Thread 5 (RDP injection):

•  This thread is responsible for calling the taskse.exe utility, which will try to enumerate active RDP sessions and run a process passed as the first parameter (in this case WanaDecryptor.exe) on connected remote machines (Fig. 27). The persistence of RDP injections is ensured by adding the appropriate value in the autorun registry key:

cmd.exe /c reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v "<service_name>" /t REG_SZ /d "\<installation_dir>\tasksche.exe\"" /f

Figure 27: RDP Injection Inside Taskse.exe

A single shortcut is created using a Visual Basic script named m.vbs, alongside the initial instance of @WanaDecryptor@.exe after the threads have finished processing (Fig. 28).

Figure 28 : Wana Decrypt0r Shortcut Creation

Next, the DLL will terminate the following SQL and MS Exchange processes to more easily encrypt their data files:

•  mysqld.exe
•  sqlwriter.exe
•  sqlserver.exe
•  MSExchange.*
•  Microsoft.Exchange.*

After which, it proceeds to create a ransom message in the installation directory named ‘@Please_Read_Me@.txt.’ The shortcut from earlier is then copied to all directories that were affected by the encryption process along with a copy of ‘@Please_Read_Me@.txt.’

Finally, the DLL is responsible for starting the Tor instance that is used for communication between the infected party and the C&C infrastructure by invoking TaskData\Tor\taskhsvc.exe. After invoking Tor, the DLL will then invoke the ransomware user interface.


When the UI is first presented, the requested payment is $300. True to most Ransomware, if the user does not pay in a timely manner - in this instance three days - the payment increases to $600 (Fig. 29).

This is the binary responsible for the user interface and C&C communication. It can be run with one of three parameters: "co", "fi" and "vs". When run without any parameters it will copy b.wnry to @WanaDecryptor@.bmp and set it as the desktop background (using the SystemParametersInfo API), then determine the system locale and display the user interface (UI) in an appropriate language.

Figure 29: Ransomware UI Demanding Higher Ransom Payment

The UI comprises the following elements:

•  About Bitcoin - Opens in the default browser.

•  How to Buy Bitcoin - Opens in the default browser.

•  Contact Us - Displays a message box where the user can type a message to be sent to an email address specified in the configuration file (if any). The configuration in the recent version of WannaCry doesn't contain any email address by default, but it's possible that the client can obtain one from the C&C at a later point.

  Check Payment - Queries the C&C server for the decryption key. If successful, the C&C will send the private key to be saved as 00000000.dky.

•  Decrypt - Check if 00000000.dky file is present. If so, use it to decrypt files, otherwise, decrypt the files that were selected for "test decryption" list, which is read from the f.wnry file (Fig. 30).

Figure 30: Decryption Example

The attackers also included a link to a webpage that generates quick response (QR) codes from the given bitcoin address (, but this functionality seems to be unimplemented.


Perform C&C check-in:

•  Start listening on
•  Unpack Tor from s.wnry to the installation directory.
•  If s.wnry is either not present or corrupted, download Tor from the URL specified in the configuration file.
•  Copy TaskData\Tor\tor.exe to TaskData\Tor\taskhsvc.exe and run it.
•  Connect to one of the onion URLs specified in the configuration and send the contents of all *.res files to the C&C server.

Figure 31: Start Tor Browser


C&C Communication:

•  If Tor is not running, set it up and run as above (Fig. 31).
•  Send the contents of the 00000000.res file to the C&C server.
•  Save the response from C&C to c.wnry (possibly new/additional wallet ID).

The 00000000.res file contains 88 bytes of config data, including internal flags, counters, and three timestamps:

-  When the encryption routine was executed
-  When the UI module was started
-  When shadow copies were deleted

Figure 32 shows the default 00000000.res file just after infection.

Figure 32: .res File Contents


Prevent various common methods of recovering data using the following commands:

•   vssadmin delete shadows /all /quiet - Deletes all the shadow volumes available on the device without alerting the user. These volumes contain the back-up data for the device in case of a fault.
•    wmic shadowcopy delete - Ensures deletion of any copies relating to the shadow volumes.
•    bcdedit /set {default} bootstatuspolicy ignoreallfailures – bcdedit is the command line tool for altering BCD stores. This command will ensure that the machine boots, even if errors are found.
•    bcdedit /set {default} recoveryenabled no - Disables the Windows recovery feature preventing reverting to a previous build.
•    wbadmin delete catalog - This ensures that a user can no longer use any of the backups created using the Windows Server backup snap-in.


Thankfully, the prevalence of WannaCry was severely limited owing to the discovery and sink-holing of the "kill-switch" domain and, to a lesser extent, due to the prevalence of another strain of malware called Adylkuzz, a BitCoin miner that appeared slightly before WannaCry and utilized the same SMB exploit to propagate. Adylkuzz, however, would modify the Windows firewall settings to close port 445 on infected systems, which would have impacted WannaCry’s ability to spread.

As for the modular nature of WannaCry, it would appear that in addition to the reuse of SMB exploitation code from a pubic repository, there is strong evidence of code reuse elsewhere, making the task of attribution very difficult from a simple code analysis perspective. The individual components also vary in terms of complexity, and although largely trivial with very little use of obfuscation, again seem to hint at the possibility of code reuse and indicate the involvement of multiple authors.

Finally, it has been widely reported that there were as many as several hundred variants found in the wild. Whilst these reports have some credibility, the vast majority appear to have been either doctored versions of the original variant, primarily modified by researches to alter the kill-switch domain, or are subcomponents that have been extracted/carved from on-disk or in-memory images, leading to differing hash values but identical functionality. 


Indicators of Compromise (IoCs):

The following list represents SHA256 hashes for the main ransomware dropper/worm component:



The following rules are used to detect the main ransomware dropper mentioned in this article:

import "pe"

rule WannaCry_Ransomware_Dropper
    description = "WannaCry Ransomware Dropper"
    date = "2017-05-12"

    $s1 = "cmd.exe /c \"%s\"" fullword ascii
    $s2 = "tasksche.exe" fullword ascii
    $s3 = "icacls . /grant Everyone:F /T /C /Q" fullword ascii
    $s4 = "Global\\MsWinZonesCacheCounterMutexA" fullword ascii

    uint16(0) == 0x5a4d and 
    filesize < 4MB and 
    all of them

rule WannaCry_SMB_Exploit
    description = "WannaCry SMB Exploit"
    date = "2017-05-12"

    $s1 = { 53 4D 42 72 00 00 00 00 18 53 C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FE 00 00 40 00 00 62 00 02 50 43 20 4E 45 54 57 4F 52 4B 20 50 52 4F 47 52 41 4D 20 31 2E 30 00 02 4C 41 4E 4D 41 4E 31 2E 30 00 02 57 69 6E 64 6F 77 73 20 66 6F 72 20 57 6F 72 6B 67 72 6F 75 70 73 20 33 2E 31 61 00 02 4C 4D 31 2E 32 58 30 30 32 00 02 4C 41 4E 4D 41 4E 32 2E 31 00 02 4E 54 20 4C 4D 20 30 2E 31 32 00 00 00 00 00 00 00 88 FF 53 4D 42 73 00 00 00 00 18 07 C0 }

    uint16(0) == 0x5a4d and
    filesize < 4MB and 
    all of them and
    pe.imports("ws2_32.dll", "connect") and
    pe.imports("ws2_32.dll", "send") and
    pe.imports("ws2_32.dll", "recv") and
    pe.imports("ws2_32.dll", "socket") and
    pe.imports("ws2_32.dll", "closesocket")

The BlackBerry Cylance Threat Research Team

About The BlackBerry Cylance Threat Research Team

The BlackBerry Cylance Threat Research team examines malware and suspected malware to better identify its abilities, function and attack vectors. Threat Research is on the frontline of information security and often deeply examines malicious software, which puts us in a unique position to discuss never-seen-before threats.