WannaCry is the ransomware computer worm that targets computers running Microsoft Windows. Initially, the worm uses the EternalBlue exploit to enter a computer, taking advantage of a vulnerability in Microsoft’s implementation of the Server Message Block (SMB) protocol. It installs DoublePulsar, a backdoor implant tool, which then transfers and runs the WannaCry ransomware package. It is also being called WanaCrypt0r 2.0.
The WinMain of this executable first tries to connect to the website www.iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea.com. It doesn’t actually download anything there, just tries to connect. If the connection succeeds, the binary exits.
It was probably some kind of kill switch or anti-sandbox technique. Whichever it is, it has backfired on the authors of the worm, as the domain has been sinkholed and the host in question now resolves to an IP address that hosts a website. Therefore, nothing will happen on any new systems that runs the executable. This only applies to the binary with the hash listed above; there may well be new versions released in the future. The second argument to InternetOpenA is 1 (INTERNET_OPEN_TYPE_DIRECT), so the worm will still work on any system that requires a proxy to access the Internet, which is the case on the majority of corporate networks.
After this check passes, the first thing the worm does is check the number of arguments it was launched with. If it was run with less than two arguments passed, it installs a service called mssecsvc2.0 with display name Microsoft Security Center (2.0) Service (where the binary ran is itself with two arguments), starts that service, drops the ransomware binary located in the resources of the worm, and runs it.
If it was run with two arguments or more—in other words, if it was run as a service—execution eventually falls through to the worm function.
The initialization function called first calls WSAStartup() to initialize networking, then CryptAcquireContext() to initialize the crypto API so it can use a cryptographically-secure pseudo-random number generator. It then calls a function that initializes two buffers used for storing the worm payload DLLs, one x86 and one x64. It copies the payload DLLs from the .data section of the worm and then copies the entire worm binary after it.
The code of each payload DLL is very small, just getting the resource content (i.e. the worm binary), dropping to disk as C:\WINDOWS\mssecsvc.exe (this path is actually hardcoded) and executing it.
After initializing the functionality used by the worm, two threads are created. The first thread scans hosts on the LAN. The second thread gets created 128 times and scans hosts on the wider Internet.
The first thread (in charge of scanning LAN) uses GetAdaptersInfo() to get a list of IP ranges on the local network, then creates an array of every IP in those ranges to scan.
The LAN scanning is multithreaded itself, and there is code to prevent scanning more than 10 IP addresses on the LAN at a time.
The scanning thread tries to connect to port 445, and if so creates a new thread to try to exploit the system using MS17-010/EternalBlue. If the exploitation attempts take over 10 minutes, then the exploitation thread is stopped.
The threads that scan the Internet generate a random IP address, using either the OS’s cryptographically secure pseudo-random number generator initialized earlier, or a weaker pseudo-random number generator if the CSPRNG failed to initialize. If connection to port 445 on that random IP address succeeds, the entire /24 range is scanned, and if port 445 is open, exploit attempts are made. This time, exploitation timeout for each IP happens not after 10 minutes but after one hour.