FritzFrog: A New Generation of Peer-to-Peer Botnets
Executive Summary
Guardicore has discovered FritzFrog, a sophisticated peer-to-peer (P2P) botnet that has been actively breaching SSH servers since January 2020.
Golang-based malware: FritzFrog executes a worm malware that is written in Golang, and is modular, multithreaded, and fileless, leaving no trace on the infected machine’s disk.
Actively targeting government, education, finance, and more: FritzFrog has attempted to brute force and propagate to tens of millions of IP addresses of government offices, educational institutions, medical centers, banks, and telecom companies. Among those, it has successfully breached more than 500 servers, infecting well-known universities in the United States and Europe, and a railway company.
Sophistication: FritzFrog is completely proprietary; its P2P implementation was written from scratch, reminding us that the attackers are highly professional software developers.
Interception: Guardicore Labs has developed a client program in Golang that is capable of intercepting FritzFrog’s P2P communication, as well as joining as a network peer.
Attribution: Although we are unable to attribute the FritzFrog botnet to a specific group, we have found some resemblance to a previously seen P2P botnet named Rakos.
Introduction
FritzFrog is a highly sophisticated P2P botnet that has been actively breaching SSH servers worldwide. With its decentralized infrastructure, it distributes control among all its nodes. In this network with no single point of failure, peers constantly communicate with one another to keep the network alive, resilient, and up-to-date. P2P communication is done over an encrypted channel, using AES for symmetric encryption and the Diffie–Hellman protocol for key exchange.
Unlike other P2P botnets, FritzFrog combines a set of properties that makes it unique: It is fileless; it assembles and executes payloads in-memory. It is more aggressive in its brute-force attempts, yet stays efficient by distributing targets evenly within the network. Finally, FritzFrog’s P2P protocol is proprietary and is not based on any existing implementation.
The malware, which is written in Golang, is completely volatile and leaves no traces on the disk. It creates a backdoor in the form of an SSH public key, giving the attackers ongoing access to victim machines. Since the beginning of the campaign, we identified 20 different versions of the malware.
In this report, we will describe how the FritzFrog campaign was discovered, the nature of its P2P network, and the malware’s inner workings — including the infection process, command encryption, and volatile behavior.
Guardicore Labs provides a GitHub repository containing a detection script and a list of indicators of compromise for this campaign.
Exploring FritzFrog
Guardicore Labs first noticed this campaign as part of its ongoing Botnet Encyclopedia research. On January 9, 2020, new attack incidents appeared where malicious processes named ifconfig and nginx were executed. We started monitoring the campaign’s activity, which rose steadily and significantly with time, reaching 13,000 attacks on the Guardicore Global Sensors Network. Since its first appearance, we’ve identified 20 different versions of the FritzFrog binary.
What was intriguing about this campaign was that, at first sight, there was no apparent command and control (C2) server being connected to. It was shortly after the beginning of the research when we understood no such C2 existed in the first place.
To intercept the FritzFrog network, Guardicore Labs has developed a client program in Golang, which performs the key-exchange process with the malware and is capable of sending commands and receiving their outputs. This program, which we named frogger, allowed us to investigate the nature and scope of the network. Using frogger, we were also able to join the network by “injecting” our own nodes and participating in the ongoing P2P traffic.
FritzFrog was found to brute force millions of IP addresses, among which were government offices, educational institutions, medical centers, banks, and telecom companies. It has successfully breached more than 500 SSH servers, including those of well-known higher-education institutions in the United States and Europe, and a railway company.
New-generation P2P
FritzFrog has a special combination of properties that make it unique in the threat landscape. It is:
Fileless. FritzFrog operates with no working directory, and file transfers are done in-memory using blobs.
Constantly updating. Databases of targets and breached machines are exchanged seamlessly.
Aggressive. Brute-force is based on an extensive dictionary — by comparison, DDG, another P2P botnet, used only the username “root.”
Efficient. Targets are evenly distributed among nodes.
Proprietary. The P2P protocol is completely proprietary, relying on no known P2P protocols, such as μTP.
Once a victim is successfully breached, it starts running the UPX-packed malware, which immediately erases itself. The malware process runs under the names ifconfig and nginx to minimize suspicion. As part of its start-up process, the malware begins listening on port 1234, waiting for commands. The first commands a new victim receives are responsible for syncing the victim with the database of network peers and brute-force targets.
Traffic on a nonstandard port, such as 1234, can be easily detected and blocked by firewalls and other security products. Thus, FritzFrog’s author employed a creative technique to evade detection and stay under the radar. Instead of sending commands directly over port 1234, commands are sent to the victim in the following manner: The attacker connects to the victim over SSH and runs a netcat client on the victim’s machine, which in turn connects to the malware’s server. From this point on, any command sent over SSH will be used as netcat’s input, thus transmitted to the malware.
The FritzFrog attackers implemented an encrypted command channel with more than 30 different commands. Command parameters and responses are transferred in designated data structures and serialized (“marshaled”) to JSON format. Prior to sending, the data is encrypted using AES symmetric encryption and encoded in Base64. To agree upon the encryption key, the involved nodes use the Diffie–Hellman key exchange protocol.
Nodes in the FritzFrog network keep in close contact with one another. They constantly ping one another to verify connectivity, exchange peers and targets, and keep each other synced. The nodes participate in a clever vote-casting process, which appears to affect the distribution of brute-force targets across the network. Guardicore Labs observed that targets are evenly distributed, such that no two nodes in the network attempt to “crack” the same target machine.
Delving into the malware
FritzFrog’s binary is an advanced piece of malware written in Golang. It operates completely in-memory; each node running the malware stores in its memory the entire database of targets and peers. The malware spawns multiple threads to perform various tasks simultaneously, as detailed in the table below.
FritzFrog defines the following states with regard to the management of victim and target machines:
Target – a machine found in the target queue will next be fed to the Cracker module, which in turn will scan and try to brute force it
Deploy – a machine that was successfully breached is queued for malware infection by the DeployMgmt module
Owned – a machine which was successfully infected will be added to the P2P network by the Owned module
Each node that runs the malware has a worker thread that is responsible for receiving commands, parsing them, and dispatching them to the appropriate function in the code.
The malware is transient — it does attempt to survive system reboots. However, a backdoor is left to enable future access to the breached victim, whose login credentials are saved by the network peers. The malware adds a public SSH-RSA key to the authorized_keys file. This simple backdoor allows the attackers — who own the secret private key — passwordless authentication, in case the original password was modified. FritzFrog has used only a single public key, given in the box below.
The malware file runs various shell commands on the local machine, some of them periodically, to monitor the system state. For example, it runs free -m to check for available RAM; uptime, journalctl -S @0 -u sshd to monitor SSH logins; and other commands that output the CPU usage statistics. These statistics are available for other nodes in the network to consume and are used, for example, to determine whether to run a cryptominer.
The malware runs a separate process — named libexec — to mine the Monero coin. The miner is based on the popular XMRig miner and connects to the public pool web.xmrpool.eu over port 5555.
An evil torrent-like network
FritzFrog relies on the ability to share files over the network, both to infect new machines and run malicious payloads, such as the Monero cryptominer.
To share and exchange files between nodes, FritzFrog uses a stealthy, fileless approach. Files are split into blobs — bulks of binary data — that are kept in memory. The malware keeps track of the available blobs by storing them in a map together with each blob’s hash value.
When a node A wishes to receive a file from its peer, node B, it can ask node B which blobs it owns using the command getblobstats. Then, node A can get a specific blob by its hash, either by the P2P command getbin or over HTTP, with the URL https://:1234/. When node A has all the needed blobs, it assembles the file using a special module named Assemble and runs it.
Attribution
Tracking the operators of a P2P botnet is a complicated task; because of its distributed nature, commands can be sent to and from any node in the network. Still, we’ve attempted to compare it with previous P2P botnets seen in the threat landscape.
Even when compared with past P2P botnets, FritzFrog appears unique; it does not use IRC like IRCflu, it operates in-memory unlike DDG, and runs on Unix-based machines — as opposed to the InterPlanetary Storm botnet. If any, it bears some resemblance — especially with regard to function naming and version numbers – to Rakos, a P2P botnet written in Golang and analyzed by ESET back in 2016.
Detection and mitigation
Guardicore Labs provides a FritzFrog detection script to run on SSH servers. It looks for the following FritzFrog indicators:
Running processes nginx, ifconfig, or libexec whose executable file no longer exists on the file system (as seen below)
Listening port 1234
In addition, TCP traffic over port 5555 can indicate network traffic to the Monero pool.
FritzFrog takes advantage of the fact that many network security solutions enforce traffic only by the port and protocol. To overcome this stealth technique, process-based segmentation rules can easily prevent such threats.
Weak passwords are the immediate enabler of FritzFrog’s attacks. We recommend choosing strong passwords and using public key authentication, which is much safer. In addition, it is crucial to remove FritzFrog’s public key from the authorized_keys file, preventing the attackers from accessing the machine. Routers and IoT devices often expose SSH and are thus vulnerable to FritzFrog; consider changing their SSH port or completely disabling SSH access to them if the service is not in use.