Team82 is publishing some details on two serious vulnerabilities in two Red Lion Sixnet remote terminal unit (RTU) products, and in the Sixnet Universal protocol
Both of the vulnerabilities were assessed a CVSS v3 score of 10.0, and users are urged to apply patches provided by Red Lion; Team82 delayed publication of these details in order to allow asset owners to patch and protect their devices
The vulnerabilities affect Red Lion SixTRAK and VersaTRAK RTUs, and allow an unauthenticated attacker to execute commands with root privileges
Users are also advised to block access over TCP to the affected RTUs
Red Lion has published separate advisories with patch information and instructions.
CISA also published an advisory with version and mitigation information
Red Lion’s Sixnet remote terminal units (RTUs) offer advanced automation, control, and data acquisition capabilities. These devices are designed for industrial automation and control systems, particularly in sectors like energy, water & wastewater treatment, transportation, utilities, manufacturing and more.
In order to configure and visualize the Sixnet devices, Red Lion created software named Sixnet IO Tool Kit, a Windows utility that designs, configures, and monitors Sixnet I/O systems, including the RTU. It communicates with its devices using the proprietary Sixnet Universal protocol over UDP port 1594. This software is then used by other vendors, for example Honeywell with Honeywell IO Tool Kit.
To add a layer of security, Red Lion implemented a user-permission system over the UDP protocol. Using the program one can create users, delete users, and edit the user's password and permissions. The mechanism works as follows:
When the program initiates a connection with the Sixnet RTU it first tries to access it with an anonymous user and sends only the selected action without authentication. If an anonymous user is not allowed or does not have sufficient permissions for the requested command, the RTU sends a challenge. The program then prompts for proper authentication and creates a response from the given data. The flow in which the response is created:
A MD5 hash is created where the input is:
[prompted_username] : RTU : [prompted_password]
Let's call the result: hash1
.
Another MD5 hash is then created with the input:
[hash1] : [rtu_given_challenge] : [index] : [random_4_bytes] : 1
Let's call the result: response_hash
.
The program then sends the action again and appends response_hash
to the end. If authentication was successful and the user has permission to perform the requested action, the flow continues. Each time the program sends a UDP packet, the response hash will be calculated again with an incremented index and sent to the RTU. If an error occurred, then a new challenge will be sent and the program will prompt for a new user and password.
The Sixnet Universal protocol supports many functions, including: File management (read, create, write, etc.), set station number, get station information, get Linux kernel, boot version, and more.
The protocol structure is as follows:
Lets explain each of these four parts of the packet we’ve marked in different colors:
Packet Header: The first six bytes in every packet are the header.
The first byte is the cyclic redundancy check (CRC) method for the packet. 0x7D is a Fixed CRC, 0x5D is hex format, 0x29 is binary format.
The second byte is the packet length without the first two bytes.
The third byte is the destination station number, in this case 0xFF means broadcast so every device receiving this packet will execute the command. The destination can be two bytes if certain conditions are met.
The fourth byte is the source station number and it’s built like the third.
The fifth byte is the session number, and for this function code should be 0xC0
The sixth byte is the sequence number for the session.
Command: Represents the function code, in this case to run a privileged command.
Message Content: The actual message data with a null terminator; this text will be executed.
CRC: For the Fixed CRC method stated in the beginning there will always be 0x1D0F at the end.
The response packet structure is almost the same:
Packet Header: same structure as the request.
Command: response function code.
Shell Output Length: the length of the command output, this only exists in the code execution function.
Message Content: the command output.
CRC: Same as in the request
Since the Sixnet Universal protocol implements many sensitive functions including code execution, an authentication layer was added to protect the system. We discovered that the software running on the RTU that’s listening to the UDP port also listens for the same port in TCP and by using the TCP port, we could bypass authentication.
The engineering workstation software doesn’t seem to be using the TCP flavor of the protocol, rather just UDP. The only difference between how the software handles the data from UDP and TCP is the authentication check. In the UDP flavor, each packet is validated for permissions and authentication, and only if the authentication is valid is the packet processed. We’ve seen that when data is sent over TCP, the packet is processed immediately without the extra layer of authentication.
If we follow the UDP flow, below, we can see in the sxether_client
binary at offset 0x10003078
usage of the function get_message_authenticated
that parses the packet and its authentication suffix. Then, at offset 0x100030D8
we can see the use of a function that checks and validates the authentication and only if valid continues to handle the request.
On the other hand, in the TCP flow, below, can see right after receiving the data from client the function get_message
is called at offset 0x100026D0
instead of get_message_authenticated
so the auth suffix is not parsed, and the request is processed without an authentication check.
Therefore, by using Sixnet Universal protocol over the TCP port 1594, an attacker could bypass all authentication checks to run commands and achieve remote code execution.
One of the commands that the Sixnet protocol supports is linux shell command execution. The command is used with 0xd0
0x1e
and it enables clients to send linux shell commands to be executed. Upon running the linux binary id we found out that the commands are being executed with the highest privileges, using the root user:
Here's an example for a command the program sends to the RTU. The explanation on the packet structure is above.
Red Lion has provided patches for both vulnerabilities in its SixTRAK and VersaTRAK remote terminal units, addressing vulnerabilities that enable authentication bypass and the execution of code with root privileges.
It’s crucial that organizations apply the updates provided by the vendor in order to address these vulnerabilities. Red Lion’s RTUs are prominent in many industrial automation settings, and an attacker with access to the devices and the ability to run commands at root presents significant possibilities for process disruption or damage.
Team82 has shared some details on the vulnerabilities and our research demonstrates that these issues are exploitable and should be addressed. Red Lion has published separate advisories with patch information and instructions. CISA also published an advisory with version and mitigation information
CWE-749 Exposed Dangerous Method or Function
When user authentication is not enabled the shell can execute commands with the highest privileges. Red Lion SixTRAK and VersaTRAK Series RTUs with authenticated users enabled (UDR-A) any Sixnet UDR message will meet an authentication challenge over UDP/IP. When the same message comes over TCP/IP the RTU will simply accept the message with no authentication challenge.
CVSS v3: 10
CWE-288: Authentication Bypass Using an Alternative Path or Channel
Red Lion SixTRAK and VersaTRAK Series RTUs with authenticated users enabled (UDR-A) any Sixnet UDR message will meet an authentication challenge over UDP/IP. When the same message is received over TCP/IP the RTU will simply accept the message with no authentication challenge.
CVSS v3: 10