In July 2024, the operational technology (OT)-centric malware FrostyGoop/BUSTLEBERM became publicly known, after attackers used it to disrupt critical infrastructure. The outage occurred after the Cyber Security Situation Center (CSSC), affiliated with the Security Service of Ukraine, disclosed details [PDF] of an attack on a municipal energy company in Lviv in April 2024.
FrostyGoop is the ninth reported OT-centric malware, but the first that used Modbus TCP communications to impact the power supply to heating services for over 600 apartment buildings. FrostyGoop can be used both within a compromised perimeter and externally if the target device is accessible over the internet. FrostyGoop sends Modbus commands to read or modify data on industrial control systems (ICS) devices, causing damage to the environment where attackers installed it.
Based on this reporting, we conducted a deeper analysis and uncovered new samples of FrostyGoop and other related indicators. These new indicators include configuration files and libraries used by the malware, as well as artifacts associated with an infection. We also investigate network communications and provide new insights based on open-source intelligence (OSINT) data and our own telemetry.
OT malware is an increasing concern of security professionals across the globe, and FrostyGoop provides a notable case study of this growing threat.
Palo Alto Networks customers are better protected from the threats discussed in this article through our products and services such as the following:
If you think you might have been compromised or have an urgent matter, contact the Unit 42 Incident Response team.
Related Unit 42 Topics | JSON, IoT Security, Russia |
Attackers employed this malware associated with Russian actors in a cyberattack in January 2024. This incident caused a two-day heating system outage affecting over 600 apartment buildings in Lviv, Ukraine, during sub-zero temperatures.
According to an open-source report [PDF], attackers made the initial compromise through a vulnerability in a MikroTik router. However, we have not confirmed this delivery method and bad actors might instead have delivered the malware via OT devices exposed to the internet.
FrostyGoop makes use of the Modbus TCP protocol to interact directly with ICS/OT devices, and therefore it is considered an ICS-centric malware. This is the ninth known ICS-centric malware.
In addition, Modbus is one of the most common protocols used in critical infrastructure. During this attack, the adversaries dispatched Modbus commands to ENCO control devices, leading to inaccurate measurements and system malfunctions. Remediating these issues took nearly two days.
Although bad actors used the malware to attack ENCO control devices, the malware can attack any other type of device that speaks Modbus TCP. Our telemetry indicates that 1,088,175 Modbus TCP devices were exposed to the internet from Sept. 2-Oct. 2, 2024, and 6,211,623 devices were exposed overall.
The details needed by FrostyGoop to establish a Modbus TCP connection and send Modbus commands to a targeted ICS device can be provided as command-line arguments or included in a separate JSON configuration file.
FrostyGoop is compiled using the Go programming language, sometimes referred to as Golang. The malware uses a relatively obscure open-source Modbus implementation.
Further analysis of the Modbus library revealed this implementation does not natively support supplying arguments using a JSON file, making this a strong identifier for the malware. Moreover, the JSON object structure follows a specific format based on the commands this malware supports. FrostyGoop also contains capabilities for logging the output to a console or to a JSON file.
Attackers can supply two types of parameters to FrostyGoop:
Figure 1 shows an example of the first type of parameter for an operation using Tasks and Iplist under the register for main::main.TaskList___runtime.structtype_fields.
Figure 2 shows an example of an operation for Code, Address, Count, Value and State under the register for main::main.TaskList___runtime.structtype_fields.
Figure 3 shows the timing configuration for main.Cycle.getCycleConfig.
FrostyGoop also leverages Goccy’s go-json library, a faster JSON encoder and decoder compatible with the Go programming language standard encoding/json package. In addition, it incorporates a specific open-source execution controller named queues. The relative obscurity of this code means it can serve as another possible indicator of FrostyGoop.
Figure 4 shows our analysis of a Windows executable file for FrostyGoop within the tool Binary Ninja. This analysis reveals URLs from open-source libraries for modbus, go-json and queues.
Although not all FrostyGoop samples contain the strings shown in Figure 4, other strings contained within those libraries can serve as part of the detection for this malware.
FrostyGoop also implements a debugger evasion technique by checking the BeingDebugged value in Windows' Process Environment Block (PEB). Figure 5 shows this method in the disassembled code from a FrostyGoop sample. This method provides an alternative way to check the PEB's BeingDebugged flag without calling IsDebuggerPresent(). Attackers use this technique to detect and avoid debuggers used by malware analysts.
Our investigation revealed a Windows executable sample named go-encrypt.exe written in Go that was not FrostyGoop, but it originally appeared on the same approximate date that other indicators of FrostyGoop were reported. Command-line options for this software reveal the file is used to encrypt and decrypt JSON files as illustrated in Figure 6.
After executing go-encrypt.exe using the -encrypt argument, it creates two files:
Figure 7 shows the encryption, decryption and the generated key.
Figure 8 shows the content of an encrypted JSON file generated by go-encrypt.exe.
Figure 9 shows a filtered list of processes generated by go-encrypt.exe in Process Monitor. We have highlighted when go-encrypt.exe created the decryption file named key and the 32 character content of this key file.
Decompiling go-encrypt.exe revealed it uses the Cipher Feedback (CFB) mode of the AES encryption algorithm to create the encryption/decryption key in the key file as shown in Figures 10 and 11.
As shown previously for the key generated in Figure 7, the key value is in decimal format. The decimal value of the key from Figure 7 is:
We can decode these decimal numbers into the 32-byte value of the key through a variety of methods, like the Python script shown in Figure 12. This script will convert the binary values to hexadecimal.
The 32-byte value of the key in hexadecimal is:
According to Go’s documentation for aes.NewCipher, a byte stream of 32 bytes corresponds to a 256-bit AES encryption in CFBmode. We confirmed the 32-byte hexadecimal value of the key from our example matches the ASCII value in the key file using CyberChef as shown below in Figure 13.
Although we cannot confirm go-encrypt.exe was used for the FrostyGoop attack, two circumstances indicate the attackers might have used it during this activity:
Therefore, attackers could have used this piece of software to conceal target information in JSON files for later use to perpetrate attacks.
According to the Dragos report on FrostyGoop [PDF], they initially discovered this malware in April 2024. This report notes an example of a FrostyGoop configuration file named task_test.json.
Searching VirusTotal, we found one occurrence of task_test.json on Oct. 10, 2023. Pivoting on that file, we discovered Windows executable files that we subsequently identified as FrostyGoop and go-encrypt.exe.
Figure 14 shows the same first-seen date of Oct. 10, 2023, for task_test.json, go-encrypt.exe and the other Windows executable files.
The data structure of task_test.json and its key/values are the format we would expect to be used as a configuration file by a FrostyGoop executable file. Our analysis of FrostyGoop samples indicates the malware performs read, write and write-multiple Modbus operations. The content of the task_test.json sample depicted in Figure 15 only shows read operations (Code 3).
The IP address contained in this JSON file corresponds to an ENCO control device located in Romania as noted.
Widening our search for exposed ENCO devices, our telemetry revealed 32 IP addresses, all located in either Romania or Ukraine as noted in Figure 17.
The ENCO devices we discovered all have TCP port 23 exposed for Telnet. Telnet provides a communications and management interface that is considered obsolete because it has no built-in encryption.
Simply connecting to an exposed ENCO device over Telnet reveals an ENCO banner with a list of available commands as shown below in Figure 18. This provides a reportedly easy method to probe for and identify ENCO programmable logic controller (PLC) devices on the internet.
Figure 19 shows a portion of our Xpanse report covering details of the network services running on the server listed in task_test.json. This matches the exposed ports among the other ENCO exposed devices we discovered:
We can glean further information on the ENCO device by accessing it using a web browser and recording the traffic. Figure 20 shows a login screen shown when accessing the ENCO device from a web browser. By viewing the web traffic in Wireshark and examining the HTTP response headers, we find the router is being used as a web server and the name of the router is TL-LINK Wireless Lite N Router WR740N.
According to the NIST website, versions 1 and 2 of the WR740N router's firmware are susceptible to a command injection vulnerability. However, there is no hard evidence to indicate that the attackers exploited this vulnerability in the July 2024 FrostyGoop attack.
To analyze FrostyGoop traffic, we tested two samples using task_test.json as the configuration file. The two FrostyGoop samples have the following SHA256 hashes:
The task_test.json configuration file only has a function code value of 3, which represents a Modbus command to read the holding registers. Accordingly, the FrostyGoop samples only generated commands to read the holding registers of the targeted device at over TCP port 502.
Figure 21 shows an example of the Modbus traffic generated during our test of the FrostyGoop samples, filtered in Wireshark with a customized column display. It reveals Modbus traffic to over TCP port 502, as well as the four register values specified in the task_test.json configuration file:
Figure 22 shows an example of a Modbus function code 3 request to read values from the holding registers of the ENCO device, starting with the register number 53760 for the next 123 registries. The device responded with values from registry 53760-53882. These registry entries hold UINT16 values for unsigned integers that can range from 0-65535.
We reverse engineered the samples to track down their functions. Our analysis revealed that the taskWorker function selects actions performed through the following function parameters:
If the JSON configuration file contains the number 1 as a word count value, only one register is returned. If it does not contain the number 1 as a word count value, more than one register is returned.
Figure 23 shows a code snippet from a FrostyGoop sample with the logic to select Modbus operations depending on the value provided:
With cyberattacks against ICS/OT devices and critical infrastructure increasing in recent years, the cybersecurity landscape in these types of environments has become increasingly dangerous. Countries like Ukraine, Romania, Israel, China, Russia and the United States have all been affected by attacks targeting their critical infrastructure. Prior to these incidents, cybersecurity in OT was not considered an essential part of their defensive operations.
The past decade has seen an increase in CS-centric malware, with FrostyGoop being the most recent prominent example. During this time frame, the number of OT and internet of things (IoT) devices exposed to the internet has drastically increased.
An increasing number of OT networks have been connected with IT networks to facilitate facilities management. This has unleashed new ways to perform cyberattacks that can not only damage the cyberspace realm, but also the physical world. Malicious actors can send control commands to field devices easily disguised as regular operations within network traffic, making the activity more difficult to detect and prevent.
For these reasons, we must implement security measures to prevent and mitigate these attacks. Palo Alto Networks customers are better protected from the threats discussed in this blog through the following products:
If you think you may have been compromised or have an urgent matter, get in touch with the Unit 42 Incident Response team or call:
Palo Alto Networks has shared these findings with our fellow Cyber Threat Alliance (CTA) members. CTA members use this intelligence to rapidly deploy protections to their customers and to systematically disrupt malicious cyber actors. Learn more about the Cyber Threat Alliance.
SHA256 hash:
SHA256 hash:
SHA256 hash:
SHA256 hash:
SHA256 hash:
SHA256 hash:
SHA256 hash:
SHA256 hash: