Power monitors play a crucial role in modern industries, measuring and analyzing electrical parameters like voltage, current, power factor, frequency, and energy consumption. These devices provide real-time insights that help businesses optimize energy use, improve efficiency, and detect anomalies before they cause costly failures.
For example, within factories and other industrial enterprises, power monitors may be connected to power supply lines to perform grid capacity planning and stability analysis, monitor power quality compliance, supply agreements, and regulatory requirements.
With their widespread presence in critical industries, power monitors present an attractive target for attackers. If vulnerabilities in these devices were exploited, an attacker could disrupt operations, manipulate critical data, or cause physical damage to infrastructure. Since it is attractive to the attackers, it is also an interesting research target.
We looked at the attack surface of the popular Allen-Bradley (Rockwell Automation) PowerMonitor 1000 device. In this blog, we’ll explain our research methodology and what’s running under the covers of the power monitor, as well as how we uncovered three vulnerabilities that could allow an attacker to take over control of the device, crash it, or in some situations, remotely run code of their choice.
All three vulnerabilities were assessed a CVSS v3 score of 9.8 by the Cybersecurity & Infrastructure Security Agency (CISA). Rockwell Automation has addressed each vulnerability and urges users to upgrade firmware in the devices to firmware revision 4.020.
CISA and Rockwell Automation have published security advisories with additional details. We would like to thank Rockwell Automation for their dedication to their product’s security, and for addressing the vulnerabilities described below.
Our research focused on the Rockwell Automation PowerMonitor 1000, a widely used power monitor in industrial settings. This device measures voltage and current to calculate energy and power consumption.
Our interest as security researchers is not in its primary function, but in its potential vulnerabilities. We are specifically interested in remotely exploitable vulnerabilities.
Before searching for problems, we must first understand the system. Since our primary interest is software bugs—because they are the most likely source of remotely exploitable vulnerabilities—we will focus on analyzing the software applications rather than the hardware. Therefore, If we can obtain the firmware, we can often conduct the research without physical access to the device—which is especially useful when dealing with expensive (and not that easy to obtain) equipment.
The PowerMonitor 1000 runs on a real-time operating system (RTOS), making vulnerability research more complex compared to Linux-based systems. Unlike Linux (or any other general purpose OS), RTOS-based firmware is often a single binary blob that includes the operating system, file system components, networking stack, and the power and energy calculation application.
The firmware is available on Rockwell Automation website:
Fortunately the firmware is not encrypted so we can jump straight to research and start to untangle this system. At this stage, our primary focus is to determine:
What RTOS the device is running
How the networking stack is implemented
Where the core functionality of the PowerMonitor is executed
Figuring this out will help us navigate the firmware’s code, especially the parts of the code that deal with network communication and user-provided input processing.
Since the product manuals don’t specify what operating system the device uses, we have to dig into the firmware binary for clues—and luckily, we found a few:
After some head-scratching—and a little help from the internet—the pieces fell into place:
The device runs NET+WORKS (based on NET+OS) Version 6.0, an RTOS developed by Digi, built on top of the ThreadX kernel and integrated with the Green Hills framework. The Treck TCP/IP stack handles networking along with network services like FTP and Web applications.
The PowerMonitor 1000's functional data is stored in Data Tables, which are two-dimensional arrays of 2-byte numeric values. Users can access these Data Tables through READ and WRITE operations, which can be invoked using a variety of protocols, including HTTP, CIP, and MODBUS.
To modify a table’s value, the user constructs a string with following structure:
TABLE_NAME|TABLE_PASSWORD|Arguments
All configured tables along with possible values are elaborated in the product manual.
For example, to change the device date via WEB interface, a request would look something like this:
HTTP POST
IP/Configuration_Options/cgi-bin/DateTime|TABLE_PASS|2024|01|01|10|00|00|00
The following request will set the date and time of the device to 01.01.2024 10:00:00:0000
.
Now that we have a basic understanding of the system internals, the next step is to identify an attack surface to focus on. From the documentation, we know that the device offers a web interface for management and configuration. The web interface is an excellent target for vulnerability research, because it’s easily accessible to potential attackers.
There are several ways in which the device can be configured, one of the ways is the web interface:
Lets cover the authentication procedure to the system. PowerMonitor 1000 has four user types:
PolicyHolder, Admin, User, and Application
When the web interface is accessed for the first time, a special firstrunWeb
page is displayed.
During this initial setup, the user is prompted to create a PolicyHolder
account and set its password. If the password is ever lost, a factory reset will be required to regain access.
After this initial step a user can configure credentials for other users.
The text strings found in the snapshot of the web interface documentation can be used to search the firmware to locate the code running the web server:
Now that we have an anchor within the firmware code, we can start to explore it.
And we have a surprise: the debug logs contain function names (only Treck’s code).
These debug logs are like candy for the researchers. With just a simple Python script, we were able to extract function names for almost all the functions within Treck’s code:
With a basic understanding of the underlying system, some Treck’s web interface documentation, and a few random resources from GitHub, we can start navigating the code and making sense of how things work.
The web server uses CGI (common gateway interface) to serve web content, enabling dynamic interactions between the web interface and the device’s internal systems.
Web requests are handled through a registered callback that receives the request URI along the arguments and acts accordingly.
For example, in the snippet below, we see an example of a request handler that checks whether the configuration is locked:
It's here where we reached the point where we could hunt for vulnerabilities.
As mentioned before PowerMonitor 1000 has four user types: PolicyHolder, Admin, User and Application
When the web interface is used for the first time, a special firstrunWeb
page is displayed. Using this page, the user must configure a PolicyHolder
user before proceeding. After the PolicyHolder
configuration, the web interface is switched to “normalWeb
” mode. Any request to the server at “normalWeb
” mode that performs READ/WRITE
operation from/to Data Table
is authenticated.
The following code is responsible to decide whether to load the web server in firstrunWeb
or normalWeb
mode:
The device first checks is_first_login
variable and then responds accordingly.
The important thing to note here is that no matter whether the request is a “first login” or not, the callback that will treat the request is the same for both options.
Now, let's see how authentication is performed:
We see here the following behavior:
If the requested URL is /Security/cgi-bin/security
then an authentication procedure will be performed.
If the requested URL is /firstrun/cgi-bin/security
then a Policy Holder user will be created.
The authentication bypass vulnerability here is easy to spot:
This code is executed in both scenarios: the initial setup and the normal web workflow.
Prior to calling cgi_first_time
, there's no validation that confirms that the request is actually coming from the first-time setup process.
This means an unauthenticated attacker can bypass authentication by sending an HTTP request to the /firstrun/cgi-bin/security
route. Since there’s no check enforcing that this function only runs during the initial setup, cgi_first_time
will be executed, creating a PolicyHolder account (overwriting any existing configuration) with, specified in the request arguments, password.
After reviewing the authentication logic, the next step is to hunt for memory corruption vulnerabilities, ideally in code that executes before or during authorization—potentially enabling exploitation without authentication.
As with many RTOS-based embedded systems, memory layout is not randomized, making memory corruption vulnerabilities significantly more dangerous. A well-crafted exploit could lead to denial of service, information disclosure, or even full device takeover.
Recall the example of changing the date and time within the power monitor via the web interface:
HTTP POST
IP/Configuration_Options/cgi-bin/DateTime|TABLE_PASS|2024|01|01|10|00|00|00
Lets review the code executed when the above request is made:
The code above performs two distinct memory writes:
Writing to buffer_0x100_2
: This buffer stores the user-supplied parameters after they are converted into integers or floats.
Writing to copied_from_cgi
: Once the data is written to buffer_0x100_2
, it is then copied into this second buffer, which the CGI handler later uses when actually updating the Data Tables.
Notice the key difference between these two memory writes:
First buffer write (buffer_0x100_2
): No size check is performed, meaning the device blindly writes user-supplied parameters into memory without verifying if they exceed the buffer’s boundaries.
Second buffer write (copied_from_cgi
): The server checks that the data does not exceed the buffer size (0x100 bytes).
Therefore, by supplying more than 0x50 arguments (since each argument takes two bytes), we can overflow buffer_0x100_2
and overwrite arbitrary memory, potentially leading to memory corruption or code execution.
In the firmware version we analyzed, the global variable that determines whether the PolicyHolder
is logged-in is stored immediately after buffer_0x100_2
in memory.
This means that by overflowing buffer_0x100_2
, we can potentially overwrite the authentication flag, effectively bypassing authentication and gaining unauthorized access to the system:
The vulnerability is found in the HTTP request endpoint parsing process, which occurs prior to authorization checks. Therefore, this vulnerability is exploitable without authentication.
The PowerMonitor 1000 supports RFC 2617 HTTP Authentication. That is, both basic and digest authentication are supported.
Lets elaborate a bit about the digest authentication because it is relevant to the vulnerability:
Client requests a protected resource for example
Server responds with 401 Unauthorized
Status code and includes WWW-Authenticate
header:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest realm="REALM",
nonce="NONCE",
qop="auth",
algorithm=MD5,
opaque="OPAQUE"
The client responses with Authorization
header:
The response
directive is the important one. It includes the username and the password along with other information that enhances security.
Authorization: Digest username="USER",
realm="REALM",
nonce="NONCE",
uri="URI",
response="MD5(MD5(username:realm:psswd):nonce:nc:cnonce:qop:MD5(method:uri))",
qop=auth,
nc=00000001,
cnonce="CNONCE"
The server performs the same procedure to generate the “response” as the client and compares the results (MD5 Hash). If the values are the same, the access is granted.
A heap buffer overflow vulnerability was found during execution of the fourth step of Digest Authorization
procedure:
In the code above, we see that the server constructs a string using the format method:URI
, which is later hashed and included in the final authentication hash for comparison with the client’s response
.
Now, let’s take a closer look. This string is assembled using the sprintf
function without specifying a maximum buffer size (in contrast to snprintf
). If the developer fails to ensure that the combined length of the method and URI stays within 254 bytes, the buffer will overflow.
Since no such validation is present, this results in a straightforward heap buffer overflow vulnerability.
To exploit this vulnerability an attacker will issue an HTTP request with Authorization header that will include a URI larger than 256 bytes. When the server will treat the Authorization header the heap memory will be overridden with values provided by the attacker:
HTTP POST
IP/Security/cgi-bin/security/|3|Authorization:Digest username=|username|realm=|realm|nonce=|nonce|uri=|URI|qop=|qop|nc=|nc|cnonce=|cnonce|response=|response|opaque=|opaque|
Since this is an authorization request, meaning this request inherently does not require authentication.
The three vulnerabilities uncovered by Team82 in Rockwell Automation’s PowerMonitor 1000, can put factories and other organizations at risk if exploited. An attacker could take over or crash these devices, which are important in the overall function of an industrial company. Power monitors are used to monitor power consumption and the data produced by these devices is important for optimization and analysis.
Our research into PowerMonitor 1000 included an analysis of the device’s firmware and the real-time operating system and web interface underneath the covers. We found authentication bypass and memory corruption vulnerabilities that could allow an attacker to remotely execute code in some situations, crash the device, and take over its operation.
We privately disclosed these vulnerabilities to Rockwell Automation and CISA. Rockwell Automation published firmware updates late last year that address these vulnerabilities and urges users to upgrade to firmware revision 4.020. Read more about that in the advisory released by Rockwell Automation.
This research serves as a reminder that even seemingly innocuous devices like power monitors can become targets for malicious actors. As industries increasingly rely on interconnected technologies, securing these devices is paramount. Organizations must prioritize security assessments, regular firmware updates, and strong authentication mechanisms to mitigate potential risks.
CWE-420 UNPROTECTED ALTERNATE CHANNEL:
A device takeover vulnerability exists in the affected product. This vulnerability allows configuration of a new Policyholder user without any authentication via API. Policyholder user is the most privileged user that can perform edit operations, creating admin users and performing factory reset.
Rockwell Automation has corrected these problems in firmware revision 4.020 and recommends users upgrade to the latest version available.
CVSS v3: 9.8
CWE-122 HEAP-BASED BUFFER OVERFLOW:
A denial-of-service and possible remote code execution vulnerability exists in the affected product. The vulnerability results in the corruption of the heap memory, which may compromise the integrity of the system, potentially allowing for remote code execution or a denial-of-service attack.
Rockwell Automation has corrected these problems in firmware revision 4.020 and recommends users upgrade to the latest version available.
CVSS v3: 9.8
CWE-120 BUFFER COPY WITHOUT CHECKING SIZE OF INPUT ('CLASSIC BUFFER OVERFLOW'):
A denial-of-service vulnerability exists in the affected product. The vulnerability results in a buffer overflow, potentially causing denial-of-service condition.
Rockwell Automation has corrected these problems in firmware revision 4.020 and recommends users upgrade to the latest version available.
CVSS v3: 9.8