The development of cross-platform malware is not new, however, we continue to observe a number of malware that were previously documented only targeting Windows now targeting the Linux platform. One of these threats is IPStorm.
In May 2019, researchers from Anomali discovered a new Golang malware targeting Windows, which they dubbed IPStorm (InterPlanetary Storm). IPStorm is a botnet that abuses a legitimate Peer-to-peer (p2p) network called InterPlanetary File System (IPFS) as a means to obscure malicious traffic. It was found the malware eventually allowed attackers to execute arbitrary PowerShell commands on the victim’s Windows machine.
Our research team recently identified new Linux variants of IPStorm targeting various Linux architectures (ARM, AMD64, Intel 80386) and platforms (servers, Android, IoT). We have also detected a macOS variant. The macOS variant and most of the Linux samples are fully undetected in VirusTotal at the time of this publication. IPStorm is written in Golang, which enabled Intezer Analyze to detect cross-platform code connections between the Linux samples and the Windows malware first reported by Anomali.
The Linux variant has additional features over the documented Windows version, such as using SSH brute-force as a means to spread to additional victims and fraudulent network activity abusing Steam gaming and advertising platforms. The Linux variant has adjusted some features in order to account for the fundamental differences that exist between this operating system and Windows.
In this post, we will present a code relations graph between the IPStorm Windows and Linux samples, analyze one of the Linux variant’s behavior, and compare its features and capabilities to the old Windows samples to track its evolution. Following we will take a deeper dive into some notable features and explain how to respond to this threat.
Most of the IPStorm Linux samples were fully undetected before we submitted them for genetic analysis in Intezer Analyze.
In this post, we will focus on the 658638c6bef52e03e6aea4b6c1b2b3b8d81ad40144b56b2122d96e6957c33117 Linux sample.
658638c6bef52e03e6aea4b6c1b2b3b8d81ad40144b56b2122d96e6957c33117 sample undetected in VirusTotal.
Because IPStorm is written in Golang, not only can we observe strong code connections between the different Linux variants, we can also identify connections to IPStorm’s Windows samples uploaded to our system in 2019.
The following map emphasizes code similarities between the different versions and operating systems. The nodes represent the individual samples and the lines are the code relations between them. All samples are linked to each other in some way:
- IPStorm PE files from 2019
- IPStorm ELF files from 2020
The graph depicts three main clusters, with each cluster containing samples that have strong code connections between them:
- PE, intel 80386 architecture
- ELF, intel 80386 architecture
- ELF, amd x86-64 architecture
You will also notice shared code exists between the ELF clusters and the ELF and PE intel 80386 architecture clusters.
You can use the cluster_directory.py API script in this GitHub repository to create a cluster graph of your own.
Linux Variant Behavior Flow
The Linux variant symbols are stripped. Using the plugin IDAGolangHelper we retrieved the file’s symbols and saw exactly which packages the malware contains. A package in Go is a bundle of Go source files which make up a specific functionality. Every Go source file belongs to a package.
The Linux malware’s main logic is implemented in a package called storm_starter, a new package that was not in the Windows version. All logic was implemented via the main function in the Windows version.
Both versions have similarities in the way the main flow is implemented, however, the Linux instances have additional features and adjusted some logic due to the differences that exist between the two operating systems.
The Linux iteration starts by disabling the out-of-memory (OOM) killer in order to prevent it from terminating the malware. It then proceeds to check for any processes related to Antiviruses or other security tools that may prevent further execution of the malware. Next the malware generates and saves pubkeys in a file called strom.key. The location of where this key is saved is based on privileges that the malware was executed with. If the malware was executed with root privileges, the key will be stored at /etc/storm.key. Otherwise, it will be saved at /tmp/storm.key. The malware then tries to establish connections with other nodes in the peer to peer network.
The malware sends HTTP requests to different services such as diagnostic[.]opendns[.]com/myip, ifconfig[.]io/ip, and myip[.]dnsomatic[.]com to receive the external IP address of the victim server. If the malware is running as root, it will create a service under systemd to achieve persistence and copy itself to /usr/bin/storm. Otherwise, it will be copied to /tmp/storm. The malware will then relaunch itself from the new installation path.
This new process is responsible for executing the main features of the IPStorm malware, including reverse shell, which was previously seen in the Windows variant—maintaining connection with other peers in the P2P network and a new feature for spreading the malware to other victims.
IPStorm Linux output non-privileged user.
Linux vs. Windows Comparison
Comparing IPStorm Linux version 0.2.05a to Windows version 0.0.2m, it became clear the developer added features and altered existing ones to attack Linux platforms.
The malware is composed of different Golang packages with each package providing a different feature. The following table categorizes package comparisons between the two versions:
|Golang Package||Functionality||Linux Version
Version 0.2.05a (2020)
|scan_tools||Scans for potential victims||+||–|
|web_api_client||Handles HTTP requests and responses||+||–|
|p2p (part of the web API)||HTTP over P2P||+||–|
|reque_client||Handles the communication of peers in the network||+||–|
|commander||Handles HTTP requests||+||–|
|starter||Implements the main logic of the malware (basically the “main function”)||+||–|
|backshell||In charge of the reverse shell||+||+|
|filetransfer||Persistence and managing file transfering to other peers||+||+|
|node||Responsible for advertising the node, getting the external IP, and maintaining connection with other nodes.||+||+|
|powershell||In Windows, in charge of the powershell artifact in the backdoor. In the Linux variant, the package has only one function copied from the Windows version and is used for achieving reverse shell.||+|
|proxy||Implements Socks5 Proxy||+||+|
Note: We compared Linux version 0.2.05a to Windows version 0.0.2m which was analyzed in Anomali’s report. However, the malware is frequently being updated and we have observed multiple different versions since, so functionalities may differ between them.
Scanning tools – Android and SSH brute-force
The Linux variant attempts to spread and infect other victims on the internet by using SSH brute-force. Once a connection is established, the malware will check if the victim server is a honeypot by comparing the hostname of the attacked server to the string “svr04”, which is the default hostname of Cowrie SSH honeypot. If the malware identifies a honeypot it will close the connection, otherwise it will proceed to download the payload and infect the server.
Validation of whether the server is a honeypot or not.
Another spreading method that is unique to the Linux version is searching for potential Android victims. The malware checks for devices connected with ADB (Android Debug Bridge) to the victim node. Once identified, it will upload an Android version of IPStorm to the device, which was previously downloaded from the P2P network.
Screen capture from the log of the storm service showing the downloaded file.
Both IPStorm Windows and Linux versions implement features related to detection evasion and each variant uses a different technique. In the Linux version, the package in charge of this logic is called storm_malware_guard. The file iterates through all current running processes in order to find and terminate ones that might detect the malware’s activity.
The function under the storm_malware_guard package that implements this technique is called KillSuspiciousProcesses. Other functions in this package are responsible for obtaining information about the CPU and memory usage, number of I/O ports, and functions that return information about processes and threads.
In the Windows version, the AV evasion logic is implemented in a package called avbypass.
This technique is based on random sleep times and multiple function calls. The purpose of this method is to make tracing the original process harder for Antivirus solutions.
It appears that due to the different operating systems, each IPStorm version has its own way to evade detection.
Both IPStorm versions use the name backshell to refer to the feature of reverse shell.
The backshell functions of the Linux variant are identical to those of the Windows variant.
The Windows variant has a package called powershell which contains functions for achieving reverse shell. The same package is present in the Linux variant but it contains only one function: storm_powershell__ptr_Backend_StartProcess. The function is used to get a reverse shell on the infected system.
The implementation of the reverse shell is a clear example of the code reuse connections between the two IPStorm variants. The screengrabs below demonstrate changes in the file names and the identical function names found in the two versions:
The Linux version will attempt to gain persistence only if it was executed with root privileges. The Windows version, on the other hand, will always look to gain persistence. It is evident that each variant of the malware, Linux and Windows, uses a different technique to gain persistence since the operating systems they target are fundamentally different.
The Windows variant achieves persistence by copying itself to a random location and adding the program to the: HKCU:SoftwareMicrosoftWindowsCurrentVersionRunregistry key.
The Linux version achieves persistence by creating a systemd service under /etc/systemd/system/storm.service.
The function that archives persistence in the Linux variant.
Another difference is the location to which the file is copied. The Windows variant uses random file paths while the Linux version uses fixed paths.
On top of creating a reverse shell, we have detected that IPStorm’s Linux variant takes advantage of its being widespread to perform different fraudulent activity in the background, abusing gaming and ads monetization. Because it’s a botnet, the malware utilizes the large amount of requests from different trusted sources, thus not being blocked nor traceable. This activity was not observed in the Windows variant.
Steam Gaming Fraud
Steam is a popular gaming service from Valve Corporation and is used by hundreds of millions users worldwide. It also provides an API for developers who want to use Steam data on their own websites.
As part of the monetization process for game developers, Steam users can buy and sell different items such as equipment, skins, and other in-game elements. This platform is so popular that it has become a hot target for cybercriminals. A known method used by attackers is creating phishing websites to lure users to submit their Steam login credentials. With access to a user’s credentials the attacker has full access to the the account, API key included.
We noticed IPStorm generates a large amount of traffic to Steam’s API, querying data pertaining to various Steam users and using multiple valid API keys.
We suspect these are stolen accounts that are being monitored as part of a fake trade scam. Browse here for more information about this scam.
The malware generates requests which imitate fake advertisements clicks. All the ads we have traced are related to pornographic websites. The malware crawls through different predefined sites, searches for advertisement iframes, and imitates a user “click” by browsing through the iframes.
Example of a request the malware generates to an ad platform.
Websites the malware crawls through.
IPStorm Detection and Response
Compromised System Detection
You can take the following steps to check if your system has been attacked by the IPStorm malware.
- Check if the process of IPStorm is running on your system.
Run: pstree | grep storm
IPStorm will usually run with multiple threads.
- Check the services that run on your system, since if the malware was executed with root privileges it would create a service for persistence.
Run: sudo systemctl status strom.service
- Check if IPStorm’s files exist in your system.
Run: sudo find / -name “storm*” -type f
- In case of a non-root execution the output will look similar to the screen capture below:
- If the malware was executed with root privileges, the output will look similar to the screen capture below:
- Check the open ports on your system and the processes that are associated with them. Run: sudo ss -tulpn
In the screen capture below a number of processes that belong to the IPStorm malware listen on specific ports.
- Use freely the Intezer Protect community beta to identify which process is running on your system. The screen capture below is taken from the alert of IPStorm executed on a server. The info provided by the system includes the malware family name, full path of the executable, the process ID, execution time, and a link to Intezer Analyze where you can observe code reuse prevalent in this malware.
How to Terminate IPStorm on a Compromised System
- If the malware runs as a service you should stop the service by executing the command:
sudo systemctl stop storm.service
- Delete all the files that are related to the IPStorm malware. The file paths are mentioned in the previous section.
- Kill the process by running: sudo pkill -9 storm
We are providing a YARA rule intended to be run against in-memory artifacts in order to be able to detect these implants.
System Security Hardening
- Make sure your SSH connection is secured. Use a key instead of a password or use multi-factor authentication. Browse here for more tips about SSH hardening.
- Make sure your system is updated to the latest software and aligned with most recent security best practices.
- Use a runtime cloud workload protection solution such as Intezer Protect. Protect provides full runtime visibility over the code in your system and alerts on any suspicious or unauthorized code that deviates from the secure baseline.
IPStorm now with Linux malware is the latest example of a cross-platform malware developed in Golang. Platforms that are compromised by IPStorm are not only exposed to a backdoor to their services but are also added to the IPStorm Botnet which attempts to spread to other victims. The attackers behind IPStorm are very active evidenced by the frequent release of updated versions with new features and improvements, as well as the expansion to several different platforms and architectures.
IPStorm is part of a growing list of Golang ELF malware that have been spotted attacking live servers in the past six months alone, together with Kaiji, Kinsing, and FritzFrog.
We want to give a special thanks to Paul Litvak and Michael Kajiloti for their help contributing to this analysis.
Both IPStorm Linux and Windows samples are indexed in Intezer Analyze and you can detect this and other cross-platform malware with the code reuse feature for Golang, just by uploading a file or hash to the system. Below is the analysis of one of the Linux samples.
Subscribe to our weekly threat feed to receive the latest low-detected Linux threat hashes.