FortiGuard Labs Threat Research

PyRoMineIoT: NSA Exploit, Monero(XMR) Miner, & IoT Device Scanner

By Jasper Manuel | June 12, 2018

In April 2018, FortiGuard Labs documented a Python-based malware we dubbed PyRoMine that takes advantage of the NSA exploit ETERNALROMANCE to distribute a Monero (XMR) miner. In that previous article, we explained that the malware was under development and predicted that new versions would arise in the future. Since then, we have been actively monitoring the PyRoMine malware activity, and we recently found a new version of this threat which now employs some obfuscation techniques.

We also predicted in the same article that there would be more malware authors that will use the NSA exploits to distribute their malware.

In this article, we will discuss the changes made to PyRoMine, as well as how the ETERNALROMANCE exploit was used to distribute yet another Monero miner we have dubbed PyRoMineIoT. Interestingly, this new malware variant downloads a component that scans for vulnerable IoT devices in Iran and Saudi Arabia by checking for a hardcoded username and password.

PyRoMine Update

As with the previous version of PyRoMine, this new version is hosted on the same IP address The downloaded file is an executable 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.

We will be using the same tools that we used during the first PyRoMine version analysis. In order to extract and analyze the python script and the packages it uses, we used a tool in PyInstaller named pyi-archive_viewer. With pyi-archive_viewer we were able to extract the main file, which in this case is named “ig7ttyujj9h”.

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

The extracted file is a compiled python code (.PYC). 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, we used the tool called uncompyle6.

The decompiled code shows that this is still the same ETERNALROMANCE implementation copied from the exploit database website. It still gets the local IP addresses to find the local subnet(s), then iterates through all the IPs of these subnets to execute the payload. 

Fig 2. Targeting available IP addresses in the subnets

ETERNALROMANCE requires authentication, but even for Guest accounts the exploit gives the attacker SYSTEM privileges. This malware tries to login as “Anonymous” using an empty username and password. Although, “Anonymous” is the hard-coded way to login to targeted machines, there’s a non-“Anonymous” way, which we also explained in the previous article, that uses the username ‘Default’ and password “P@ssw0rdf0rme”.

Fig 3. Non-“Anonymous” login credential

After a successful exploitation, it downloads a VBScript from hxxp:// or hxxp://

Fig 4. Payload

Unlike in the first version, the downloaded VBScript is obfuscated using string replacement and base64. The purpose is more likely to evade detection of AV programs rather than to avoid analysis.

Fig 5. Obfuscated script

The deobfuscated code reveals that it is still similar to the VBScript downloaded in the first version in terms of functionality. When compared to the VBScript downloaded in the first version, however, the code in this version looks more organized, separating the code by function. 

Fig 6. VBScript agent functions

Another noticeable change is the addition of the version number.

Fig 7. Version number

This latest version is still capable of setting-up a Default account with password “P@ssw0rdf0rme” and adds this account to the local groups “Administrators,” “Remote Desktop Users,” and “Users.” It still 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 to possible future attacks.  

Fig 8. Setting up the machine for further attacks

It downloads its components, including the Monero miner, from the following URLs depending on the processor architecture. 

Fig 9. Downloading its components depending on the processor architecture

In contrast to the early version, the component files now use randomly-generated looking file names.

Fig 10. The downloaded files use randomly-generated looking file names

The downloaded file named “ertf6t68yhy.exe” is an updater file that downloads the VBScript file agent.vbs.

The file “ojgytf6rdrdf.exe” is the real miner file, which is in fact XMRig, a high performance Monero (XMR) CPU miner. This file is registered as a service named “ijh8y77ghi” by the file “hgycr5rftgu.exe”, which is actually an NSSM (Non-Sucking Service Manager) executable.

The file “bhyc678gted.exe” ensures that the miner file is running.

These files contain embedded legitimate files in their resource section, which again is more likely to evade AV detection.

Interestingly, the author also added a function to remove what seems to be an old version of PyRoMine from the system.

Fig 11. Removing older running PyRoMine version

As of this writing, one of the pool addresses used by this malware had already been paid approximately 5 Monero, as shown in Figure 12, which is currently valued at about $854 USD. 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. 

Fig 12. Income associated with the Monero address used by PyRoMine

Its earnings are still not high at the moment, only doubling the amount since we discovered this threat two months ago. But it has infected considerably more machines than when we discovered it. The top 5 countries affected are Singapore, India, Taiwan, Côte d’Ivoire, and Australia based on the malicious server visit.

Fig 13. Top affected countries based on URL visit


In our first article about PyRoMine we also predicted that there would be more malware authors using the stolen NSA exploits to distribute their malware. We actively monitor the use of these exploits, and recently we found a similar threat to PyRoMine, which we have dubbed PyRoMineIoT.

Our investigation led us to an obviously malicious looking website that is disguised as a site that serves security updates for your internet browser.

Fig 14. Website visited using Chrome
Fig 15. Website visited using Firefox
Fig 16. Website visited using Internet Explorer

When the “Download Now” button is clicked, a zipped file name is downloaded.

Fig 17. Downloaded file

The .zip file downloaded from the website contains a downloader agent written in C# that downloads the miner file and other components. 

Fig 18. Downloads component files

One of the downloaded components is a Python-based malware that takes advantage of the NSA exploit ETERNALROMANCE to spread the agent to vulnerable machines in the network. Another component is a tool that steals user credentials from Chrome browser named ChromePass. Another component scans for vulnerable IoT devices in Iran and Saudi Arabia that use the login credentials “admin” for username and password.

Fig 19. Overview of PyRoMineIoT attack


The downloaded file WinSmb.exe is a Python-based malware that takes advantage of the NSA exploit ETERNALROMANCE, using the same code base as PyRoMine. Similar to PyRoMine, it collects local IP addresses to find the local subnet(s), then iterates through all the IPs of these subnets to execute the payload. It then uses the username ‘aa’ with an empty password string to login to the target system.

Fig 20. Credential used to login to target machine

The payload is downloaded from the URL hxxp://, which is the same downloader agent as in Figure 18. This component is used to spread the agent to vulnerable machines in the network.


The file ChromePassBackup.exe is part of a tool created by NirSoft named ChromePass. Its legitimate use is for users who need to recover their password. This tool allows a user to view the username and password stored by the Google Chrome Web Browser. However, it is also being used by cyber crooks to steal credentials from unsuspecting users.

Fig 21. ChromePass

When this tool is run by the malware, it saves the credentials in XML format in a file with a randomly generated filename. The file containing the stolen information is then uploaded to a cloud storage service offered for free by DriveHQ. When uploading, the malware uses the hardcoded username “nsiFtp” and the password “Nsi12345”.

Fig 22. Uploads the stolen information to DriveHQ

We confirmed that the account is active and files have only been uploaded since June 6, 2018. 

Fig 23. Uploaded files
Fig 24. Content of the uploaded file

We contacted DriveHQ and they were very responsive and immediately disabled the bad account.

IoT Device Scanner

One of the most interesting components of this malware is an IoT device scanner targeting Iran and Saudi Arabia. After it finds a vulnerable device, it uploads its IP information to the server. However, we are not exactly sure how the hacker will use the information, but it’s clearly for performing further attacks on the vulnerable IoT devices.

The downloaded component file, worker.exe, is a Python-based malware written in Python 3.6.4. Decompiling this malware’s .PYC file, extracted by pyi-archive_viewer, was a bit different from decompiling our previous .PYC files, since those were written in Python 2.7.

A Python 2.7 compiled code begins with the bytes 03 F3 0D 0A followed by a four-byte time stamp. However, a Python 3.6 compiled code begins with the bytes 33 0D 0D 0A followed by a four-byte time stamp. After the first two four-byte fields, there’s a new four-byte field that we needed to add which contained the size of the source file.

After adding the 3 four-byte fields, we were able to successfully decompile the code using uncompyle6.

The decompiled code first gets the target IP range from the URL hxxp:// 

Fig 25. Getting the target IP range from the server

Interestingly, so far it only targets IP ranges located in Iran and Saudi Arabia.

Fig 26. Iran and Saudi Arabia are the targets

It then gets a list of target IoT device models in JSON format from the URL hxxp://

Fig 27. Getting the list of the target IoT device models
Fig 28. List of IoT device models

To find a vulnerable IoT device in the IP range, it iterates through all IPs in the range by sending an HTTP GET request to each address. If a request fails, it continues to the next IP address in the range. If the reply is “401”, which means authorization is required to view the page, it sends another GET request adding the HTTP basic authentication header “auth=HTTPBasicAuth(‘admin’,’admin’)” to login using “admin” as the username and password. If the request is successful, it then checks if the response header WWW-Authenticate contains one of the target IoT device models in the list. However, it looks like it doesn’t do anything after the check and simply sends an HTTP GET to the server with the IP address being scanned, regardless of the result of the check. This led us to the conclusion that this is still a test script that is under development.

Fig 29. Scanner class

Currently, this script only uses the hardcoded username and password "admin" but considering past more sophisticated IoT attacks, we can expect that future versions will use a dictionary or open-source exploits to scan for vulnerable IoT devices.

The Monero (XMR) Miner

The downloaded file update.exe is also the XMRig miner file. It uses the configuration file config.json, which is also downloaded from the server. 

Fig 30. Contents of the configuration file config.json

Checking one of the pool addresses used by this malware indicated that it had not yet earned anything. This is no surprise considering that the malware is new, having only started only on June 6, 2018, and is clearly still under development. However, we are unsure how much profit the threat actor may have made overall considering all of the pool addresses, since the first pool address seems like a mining proxy. 

Fig 31. Income associated with the Monero address used by PyRoMineIoT

Based on the malicious URL visit, Kazakhstan seems to be the only country affected at the moment.


This development confirms yet again that malware authors are very interested in cryptocurrency mining, as well as in capturing a chunk of the IoT threat ecosystem. We predict that this trend will not fade away soon, but will continue as long as there are opportunities for the bad guys to easily earn money by targeting vulnerable machines and devices.

As always, FortiGuard Labs is always proactively monitoring the threat landscape for known threats and committed to discovering and reporting on new and emerging threats like PyRoMineIoT.


Fortinet detects all the PyRoMine samples as Python/MS17_010.B!tr, Riskware/CoinMiner, W32/PossibleThreat, Riskware/NSSM, and VBS/Runner.NFO!tr, and all the PyRoMineIoT samples as Python/MS17_010.B!tr, Riskware/PassView, Riskware/CoinMiner, and Python/IoTScanner.A!tr. The ETERNALBLUE exploit is detected 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 blocked by FortiGuard Web Filtering Service . Users are recommended to apply the patch released by Microsoft for CVE-2017-0144 and CVE-2017-0145.

-= FortiGuard Lion Team =-

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


Malicious servers:














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.