Threat Research

Python-Based Malware Uses NSA Exploit to Propagate Monero (XMR) Miner

By Jasper Manuel | April 24, 2018

In 2016, a group calling themselves the Shadow Brokers leaked a number of hacking tools and zero-day exploits attributed to the threat actors known as the Equation Group, a group which has has been tied to the National Security Agency’s (NSA) Tailored Access Operations unit. Then, on April 14, 2017, they released a set of weaponized exploits, including ETERNALBLUE and ETERNALROMANCE, that targeted versions of Windows XP/Vista/8.1/7/10 and Windows Server 2003/2008/2012/2016. These exploits took advantage of CVE-2017-0144 and CVE-2017-0145, which have been patched with the MS17-010 security bulletin released by Microsoft.

The ETERNALBLUE and ETERNALROMANCE exploits are remote code execution (RCE) exploits that abuse the legacy SMBv1 file sharing protocol. File sharing over SMB is normally used only within the local network, but many organizations had SMBv1 exposed to the internet, which worsened the resulting WannaCry and NotPetya attacks that leveraged those exploits.

Today, with cryptocurrencies in high demand, researchers have discovered malware authors using the ETERNALBLUE exploit in cryptocurrency mining malware, such as Adylkuzz, Smominru, and WannaMine.

Recently, FortiGuard Labs uncovered a new python-based cryptocurrency mining malware that uses the ETERNALROMANCE exploit, that we have dubbed “PyRoMine.” In this article, I provide an analysis of this malware and show how it leverages the ETERNALROMANCE exploit to spread to vulnerable Windows machines.


I originally came upon the malicious URL hxxp:// where this malware can be downloaded as a zip file. This file contains an executable file compiled with PyInstaller, which is a program that packages programs written in Python into stand-alone executables. This means that there is no need to install Python on the machine in order to execute the Python program.

In order to extract and analyze the python script and the packages it uses, I used a tool in PyInstaller named pyi-archive_viewer. With pyi-archive_viewer I was able to extract the main file, which in this case is named “controller.”

Figure 1. pyi-archive_viewer showing files contained in the package

I then dumped the “controller” file using the command “X”.

Figure 2. Using X command to dump the specified file

The extracted file is a .PYC file, which is a compiled python code. When a Python script (.PY) is run, Python compiles the script to a compiled byte code (.PYC) before running it. In order to decompile the code, I installed a tool called uncompyle6. However, executing the uncompyle6 with the malware file as parameter gave me the “ImportError: Unknown magic number 99 in controller.pyc” error message. 

Figure 3. Unknown magic number error

This is because the extracted file is missing the magic value from its header. A Python 2.7 compiled code begins with the bytes 03 F3 0D 0A followed by a four-byte time stamp. I fixed this error by inserting these 8 bytes at the beginning of the file. After adding the 8 bytes, I could now decompile the file properly.

Figure 4. Successfully decompiled file

Looking at the script, I realized that the code was copied from the ETERNALROMANCE implementation found on the exploit database website, with a few modifications to fit its need. This malware gets the local IP addresses to find the local subnet(s), then iterates through all the IPs of these subnets to execute the payload. 

Figure 5. Targeting available IP addresses of the same hostname

While ETERNALROMANCE requires authentication, but even for a Guest account the exploit gives the attacker SYSTEM privileges. In the samples analyzed (Figure 5, above), the exploit function is called with an “internal” type parameter. In Figure 6, the exploit function doesn’t check for “internal” type and only checks if the type is not “Anonymous.” If the type is not “Anonymous,” it tries to login to the target machine using the hardcoded username “Default” and the password “P@ssw0rdf0rme” to execute the payload. If unsuccessful, it then just tries to login as anonymous with an empty username and password. Since “internal” is not “Anonymous,” it attempts to log-in with the said hardcoded credential, and then with empty username and password if not successful.

Figure 6. Logging into target machine with hardcoded username and password

While a list of credentials could also be seen, it looks like it was not used in this version, though it might be in the future. As seen in Figure 6 above, the “user” and “password” variables were not used when the  conn.login() function was called.

Figure 7. Other credentials

As you may have already considered, the chance of a machine using the username “Default” and password “P@ssw0rdf0rme” might be very small, so why was this credential used for non-anonymous login? Well, it’s because one of this malware’s components sets up a “Default” account using the password “P@ssw0rdf0rme,” which I will discuss later in the article. I think the true purpose for adding this account is for re-infection and further attacks. However, for a first time infection even without the new “Default” account, it can still use the “Anonymous” login.

The payload of the exploit then downloads and executes a VBScript from the URL hxxp://

Figure 8. VBScript downloaded and executee from malicious URL

The Downloaded VBScript

The file agent.vbs is responsible for downloading and starting the miner files and setting up the system. 

The malicious vbs file sets-up a Default account with password “P@ssw0rdf0rme” and adds this account to the local groups “Administrators,” “Remote Desktop Users,” and “Users.” It then enables RDP and adds a firewall rule to allow traffic on RDP port 3389. It also stops the Windows Update Service and starts the Remote Access Connection Manager service. It then configures the Windows Remote Management Service to enable basic authentication and to allow the transfer of unencrypted data. This also opens the machine for possible future attacks.

Figure 9. Setting up the machine for further attacks

It then downloads a miner file, either or depending on the processor architecture, from the URL hxxp://

Figure 10. Downloading a miner file depending on the processor architecture
Figure 11. The downloaded archive contains several files

The file shcm.exe contains a VBScript that stops, disables, and deletes services, deletes net users, deletes files, and kills processes, as seen in the images below:    

Figure 12. shcm.exe stops, disables, and deletes services

Figure 13. shcm.exe deletes net users

Figure 14. shcm.exe deletes files

Figure 15. shcm.exe kills processes

The files rmsg.exe and svcm.exe also contain VBScripts that act as watchdogs to ensure that all its files are running.

Figure 16. Watchdogs ensure all files are running

The file WinSvcMan.exe is the real miner file, which is registered as a service named “SmbAgentService” by the file “svchost.exe.” The file svchost.exe is actually an NSSM (Non-Sucking Service Manager) executable.

Figure 17. Miner file registered as “SmbAgentService” service

In fact, the miner file is actually XMRig, which is a high performance Monero (XMR) CPU miner.

Figure 18. XMRig 2.5.2

As of this writing, one of the pool addresses used by this malware had already been paid approximately 2.4 Monero, as shown in Figure 19, which is currently valued at about $650 USD. However, this is just one example, and we are unsure how much profit the threat actor may have made overall. The hash rate displays the relative speed with which the related infected machine/instance of the malware is mining Monero.

Figure 19. Income associated with the Monero address used by PyRoMine

We first started to see this malware in April 2018, and it looks like it is still being improved, which might be the reason why its earnings are not very high at the moment.

Autostart Mechanism

This malware also creates a BAT file named help.bat that runs the file schm.exe. It then creates a scheduled task to run the BAT file “ONSTART.” Running schm.exe file results in running all of the files, including the miner file.

Figure 20. Autostart mechanism

Why Monero?

As discussed in our previous articles Group Behind VenusLocker Switches From Ransomware to Monero Mining and Cryptojacking: Digging for your own Treasure, there might be two main reasons why the malware authors chose Monero over other cryptocurrencies like Bitcoin.

The first is that Monero’s mining algorithm is designed for ordinary computers with no high-end GPUs, which are the majority of most potential targets. And the second is Monero’s promise of transaction anonymity.


PyRoMine is not the first cryptominer that uses previously leaked NSA exploits to help them spread. Those Windows machines that have not installed the patch from Microsoft remain vulnerable to this attack and similar attacks. This malware is a real threat as it not only uses the machine for cryptocurrency mining, but it also opens the machine for possible future attacks since it starts RDP services and disables security services.

FortiguardLabs is expecting that commodity malware will continue to use the NSA exploits to accelerate its ability to target vulnerable systems and to earn more profit.


Fortinet detects all the PyRoMine samples as Python/MS17_010.B!tr, Riskware/CoinMiner, VBS/Miner.PY!tr, VBS/Runner.NFO!tr, and the ETERNALBLUE exploit as MS.SMB.Server.SMB1.Trans2.Secondary.Handling.Code.Execution and the ETERNALROMANCE exploit as MS.SMB.Server.SMB1.WriteAndx.Trans2.Secondary.Code.Execution. Malicious URLs related to this malware are also blocked by Fortinet’s Web Filter service. Users are recommended to apply the patch released by Microsoft for CVE-2017-0144 and CVE-2017-0145.

A special thanks to my colleagues Rommel Joven for creating the signatures for the samples and David Maciejak for additional analysis and insights.



Check out our latest Quarterly Threat Landscape Report for more details about recent threats.

Sign up for our weekly FortiGuard intel briefs or for our FortiGuard Threat Intelligence Service.