The Nyetya attack was a destructive ransomware variant that affected many organizations inside of Ukraine and multinational corporations with operations in Ukraine. In cooperation with Cisco Advanced Services Incident Response, Talos identified several key aspects of the attack. The investigation found a supply chain-focused attack at M.E.Doc software that delivered a destructive payload disguised as ransomware. By utilizing stolen credentials, the actor was able to manipulate the update server for M.E.Doc to proxy connections to an actor-controlled server. Based on the findings, Talos remains confident that the attack was destructive in nature. The effects were broad reaching, with Ukraine Cyber police confirming over 2000 affected companies in Ukraine alone.
For Talos, June 27th, 2017, started with a message from our intelligence partners in Ukraine. A massive ransomware attack was underway, and they were asking for help. An organized attacker had the means to deliver arbitrary code to users of the most popular accounting software in Ukraine, and that includes multinational corporations that do business there. The actor in question chose to use this capability to encrypt critical files and hard drives, with no way to decrypt the software.
Since the BlackEnergy attacks of late 2015, Talos has worked with public and private organizations in Ukraine to respond to attacks in the region. Once already this year, Talos has assisted organizations targeted by actors with destructive intent. Interestingly, in those cases a wiper very similar to prior BlackEnergy malware was deployed and, when that was blocked by our Advanced Malware Protection (AMP) product, the actor fell back to using a ransomware variant in an attempt to disrupt the organization’s activities. With this recent history in mind, we were immediately concerned that there was more to this story than just another ransomware attack.
Early on it became clear that, while a majority of the early events were in Ukraine, the malware was infecting organizations that didn’t immediately have any known connection to the country. Because of the scale of the event, Talos initiated an internal response management system call TaCERS (Talos Critical Event Response System) and began the research and response process. TaCERS divides up activities into intelligence, telemetry analysis, reverse engineering, communications and detection research. Talos researchers and engineers from around the world came together to address this threat.
Based on endpoint telemetry, it was clear that a Ukranian accounting software package called “M.E.Doc” was at the center of activity. Like WannaCry, there were reports of an email vector. This is most likely because some of the earliest infected machines had concurrent Lokibot infections with indications of an email vector for that malware. After careful research Talos concluded that for the delivery of the Nyetya malware, all installations came through the M.E.Doc update system.
M.E.Doc is a widely deployed accounting package created by a Ukrainian company named Intellect Service and that it was used to interact with Ukrainian tax systems. At this point we were in a position to reach out to M.E.Doc directly and offer assistance.
M.E.Doc was quick to accept an offer of assistance. As part of Cisco’s global response to this event, two incident response specialists from the Advanced Services group arrived in Ukraine on the evening of June 29th and an additional incident response specialist supported the investigation from the UK. M.E.Doc was exceptionally open in arranging access to engineers and administrators who walked the team through the system and provided access to log files and code. They also agreed to share the results of our investigation for the purposes of this report.
In every Cisco incident response investigation, anywhere in the world, a dedicated Talos resource is made available to the incident response team to coordinate intelligence analysis, reverse engineering escalations and telemetry analysis activities. The two teams work together constantly, and that experience was put to full use in this investigation.
Early in the investigation, a web shell was discovered at http://www.me-doc[.]com[.]ua/TESTUpdate/medoc_online.php. The timestamp in the file was May 31 14:45 2017. Our analysis shows the webshell to be a slightly modified version of the open source PHP webshell PAS. The webshell is stored in an encrypted form and requires a passphrase set in a HTTP POST variable to decrypt. The decryption of the shell shows a fully featured PAS webshell.
As the incident response team extracted logs and additional forensic data, it was uploaded to Talos. This started a 24-hour cycle where at around 10am EDT, when it was evening in Ukraine, the Cisco incident response team would brief Talos on their findings and new data. Then at 3am EDT, as Ukraine was getting to work, Talos would brief the Cisco incident response team on their overnight findings.
Almost immediately, indications of problems were found. In the July 1st briefing, Talos identified key evidence in the logs:
usc-cert sshd: subsystem request for sftp
usc-cert su: BAD SU to root on /dev/pts/0
usc-cert su: to root on /dev/pts/0
[emerg] 23319#0: unknown directive “” in /usr/local/etc/nginx/nginx.conf:3
[emerg] 23376#0: location “/” is outside location “\.(ver|txt|exe|upd|rtf|cmnt)$” in /usr/local/etc/nginx/nginx.conf:136
An unknown actor had stolen the credentials of an administrator at M.E.Doc. They logged into the server, acquired root privileges and then began modifying the configuration file for the NGINX web server. We were unable to recover the nginx.conf file, as it was subsequently overwritten, but additional log files were important in understanding what was changed. What we found were thousands of errors that looked like this:
[error] 23401#0: *374685644 upstream timed out (60: Operation timed out) while connecting to upstream, client: <REDACTED>, server: upd.me-doc.com.ua, request: “GET /last.ver?rnd=1b2eb092215b49f5b1d691b5c38e3a74 HTTP/1.1”, upstream: “http://176.31.182[.]167:80/last.ver?rnd=1b2eb092215b49f5b1d691b5c38e3a74”, host: “upd.me-doc.com.ua”
The NGINX server had been reconfigured so that any traffic to upd.me-doc.com.ua would be proxied through the update server and to a host in the OVH IP space with an IP of 184.108.40.206. Subsequent investigation found that this server was operated by a reseller, thcservers.com, and that the server had been wiped the same day at 7:46 PM UTC.
When we compare the time of the first and last upstream error messages on the server to our in-field endpoint telemetry, we find that they bracket the beginning and the end of the active infection phase of the event. The initial log message was at 9:11:59 UTC and the last message was seen at 12:31:12 UTC. In our telemetry we see no new organizations infected outside of this timeframe.
We found one other piece of forensic evidence showing that the event concluded on or around 12:30 PM UTC. The file timestamp for nginx.conf at the time we analyzed the servers was Jun 27th, 12:33 PM UTC. The actor had returned the NGINX configuration to its original state at this time. There is only one other indicator to share, which was a Latvian IP address that disconnected from the system at 2:11:07 PM UTC:
Received disconnect from 220.127.116.11: 11: FlowSshClientSession: disconnected on user’s request
M.E.Doc confirms that neither the OVH server nor the Latvian IP address have any association with M.E.Doc.
At this point we understood that the actor in question had access to much of the network and many of the systems of M.E.Doc through compromised credentials. The questions remaining were: What were they doing with control of the upgrade server? How were they delivering the malicious software?
While we didn’t know it at the time, we can now confirm ESET’s research into the backdoor that had been inserted into the M.E.Doc software. The .net code in ZvitPublishedObjects.dll had been modified on multiple occasions to allow for a malicious actor to gather data and download and execute arbitrary code:
M.E.Doc Update Version
Looking further back in the logs provided by M.E.Doc, we could see the same “upstream” activity on June 22nd. Unfortunately, we do not have logs available for May or April, but it is reasonable to assume similar behavior occurs back through those dates as well.
ZvitPublishedObjects.dll Backdoor Analysis
The backdoor was added to the ZvitPublishedObjects.Server.UpdaterUtils.IsNewUpdate function in ZvitPublishedObjects.dll:
Between lines 278 and 279 on the left, we can see on the right that code was added to retrieve every organization’s EDRPOU and name. Then it creates a new MeCom object and a thread for it which will contact http://upd.me-doc[.]com.ua/last.ver?rnd=<GUID> every 2 minutes. It will also send any replies to this URL.
If a proxy has been configured, when the MeCom object is created at line 288 on the right, it proceeds to retrieve the proxy’s host, port, username and password:
It then retrieves the SMTP host, username, password and email address for every organization in the application’s database:
It also writes the previously collected proxy info to a registry key: HKCU\SOFTWARE\WC. It stores the proxy username and password in the “Cred” subkey and the full proxy information in “Prx”.
At line 294 in IsNewUpdate is a call to meCom.CreateMeainThread. The code creates a thread that performs the “MainAction”. This thread will continuously query the request URL (http://upd.me-doc[.]com.ua/last.ver?rnd=<GUID>) looking for commands and will then start a new thread per command to execute, waiting a maximum of 10 minutes for the thread to complete. It will then send back the result of the thread to the response url, which in this case is the same as the request URL: http://upd.me-doc[.]com.ua/last.ver?rnd=<GUID>.
The GetCommandsAndPeriod function will retrieve the commands from the web request:
When sending the request, it will pass along in cookies the EDRPOU and the username that the program is running as. From the response, it will read the first 8 bytes as the initialization vector for the encryption. The rest of the data is encrypted with the TripleDes using a 24-character key: \x00 to \x17 (i.e. characters 0 to 23). It will decrypt, decompress and deserialize the commands it has to execute. It will also retrieve information on how long it should wait until the next time it goes to ask for commands (this was originally set to 2 minutes when the object was created).
SendAnswer will send multiple web requests with a maximum of 2048 bytes each, with the result of the executed command stored in cookies. It will encrypt this data the same way as the received commands, using a random 8-byte IV and the 24-character key 0-23.
These are the encryption and decryption functions:
Finally, the Worker object (see Line 372 of MainFunction) handles executing the commands. There are a total of 6 commands that Worker can execute.
Detail of Commands
This appears to be the mechanism used for delivering the Nyetya malware. The command line arguments perfectly match what was observed in endpoint telemetry when M.E.Doc machines executed the initial sample.
First we need to put together everything we know. In the past Talos has observed an actor specifically targeting Ukrainian institutions attempt to use the BlackEnergy wiper malware and, when that attempt was blocked, fall back to using a ransomware variant as an acceptable replacement for a wiper. We’ve also already documented in our previous blog that “Given the circumstances of this attack, Talos assesses with high confidence that the intent of the actor behind Nyetya was destructive in nature and not economically motivated.” Finally, now that we can confirm that M.E.Doc was the installation vector, we can assess that the targets for this attack were Ukraine and those organizations that chose to conduct business with Ukraine.
Our Threat Intelligence and Interdiction team is concerned that the actor in question burned a significant capability in this attack. They have now compromised both their backdoor in the M.E.Doc software and their ability to manipulate the server configuration in the update server.
In short, the actor has given up the ability to deliver arbitrary code to the 80% of UA businesses that use M.E.Doc as their accounting software, along with any multinational corporations that leveraged the software. This is a significant loss in operational capability, and the Threat Intelligence and Interdiction team assesses with moderate confidence that it is unlikely that they would have expended this capability without confidence that they now have or can easily obtain similar capability in target networks of highest priority to the threat actor.
Based on this, Talos is advising that any organization with ties to Ukraine treat software like M.E.Doc and systems in Ukraine with extra caution since they have been shown to be targeted by advanced threat actors. This includes providing them a separate network architecture, increased monitoring and hunting activities in those at-risk systems and networks and allowing only the level of access absolutely necessary to conduct business. Patching and upgrades should be prioritized on these systems and customers should move to transition these systems to Windows 10, following the guidance from Microsoft on securing those systems. Additional guidance for network security baselining is available from Cisco as well. Network IPS should be deployed on connections between international organizations and their Ukrainian branches and endpoint protection should be installed immediately on all Ukrainian systems.
Talos places this attack in the supply-chain category. Rather than targeting organizations directly, an actor compromises trusted hardware and software vendors to deliver compromised assets to a high-priority environment. We believe that these types of malicious capabilities are highly desired by sophisticated actors. All vendors, regardless of size or geographic region, must be increasingly vigilant. Find out more about how Cisco assures the integrity of their products here.
Indicators of Compromise
M.E.Doc ZvitPublishedObjects.dll files with backdoor: