Vulnerabilities > CVE-2017-16344 - Classic Buffer Overflow vulnerability in Insteon HUB Firmware 1012

047910
CVSS 9.9 - CRITICAL
Attack vector
NETWORK
Attack complexity
LOW
Privileges required
LOW
Confidentiality impact
HIGH
Integrity impact
HIGH
Availability impact
HIGH
network
low complexity
insteon
CWE-120
critical

Summary

An attacker could send an authenticated HTTP request to trigger this vulnerability in Insteon Hub running firmware version 1012. At 0x9d01c2c8 the value for the s_url key is copied using strcpy to the buffer at 0xa0001a0c. This buffer is 16 bytes large, sending anything longer will cause a buffer overflow. The destination can also be shifted by using an sn_speaker parameter between "0" and "3".

Vulnerable Configurations

Part Description Count
OS
Insteon
1
Hardware
Insteon
1

Common Attack Pattern Enumeration and Classification (CAPEC)

  • Buffer Overflow via Environment Variables
    This attack pattern involves causing a buffer overflow through manipulation of environment variables. Once the attacker finds that they can modify an environment variable, they may try to overflow associated buffers. This attack leverages implicit trust often placed in environment variables.
  • Overflow Buffers
    Buffer Overflow attacks target improper or missing bounds checking on buffer operations, typically triggered by input injected by an attacker. As a consequence, an attacker is able to write past the boundaries of allocated buffer regions in memory, causing a program crash or potentially redirection of execution as per the attackers' choice.
  • Client-side Injection-induced Buffer Overflow
    This type of attack exploits a buffer overflow vulnerability in targeted client software through injection of malicious content from a custom-built hostile service.
  • Filter Failure through Buffer Overflow
    In this attack, the idea is to cause an active filter to fail by causing an oversized transaction. An attacker may try to feed overly long input strings to the program in an attempt to overwhelm the filter (by causing a buffer overflow) and hoping that the filter does not fail securely (i.e. the user input is let into the system unfiltered).
  • MIME Conversion
    An attacker exploits a weakness in the MIME conversion routine to cause a buffer overflow and gain control over the mail server machine. The MIME system is designed to allow various different information formats to be interpreted and sent via e-mail. Attack points exist when data are converted to MIME compatible format and back.

Seebug

bulletinFamilyexploit
description### Summary Multiple exploitable buffer overflow vulnerabilities exist in the PubNub message handler for the "cc" channel of Insteon Hub running firmware version 1012. Specially crafted commands sent through the PubNub service can cause a buffer overflow on a global section overwriting arbitrary data. An attacker should send an authenticated HTTP request to trigger this vulnerability. ### Tested Versions Insteon Hub 2245-222 - Firmware version 1012 ### Product URLs http://www.insteon.com/insteon-hub ### CVSSv3 Score 8.5 - CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H ### CWE CWE-120: Buffer Copy without Checking Size of Input ('Classic Buffer Overflow') ### Details Insteon produces a series of devices aimed at controlling and monitoring a home: wall switches, led bulbs, thermostats, cameras, etc. One of those is Insteon Hub, a central controller which allows an end-user to use his smartphone to connect to his own house remotely and manage any other device through it. The Insteon Hub board utilizes several MCUs, the firmware in question is executed by a Microchip PIC32MX MCU, which has a MIPS32 architecture. The firmware uses Microchip's "Libraries for Applications" as core for the application code. Its functionality resides on a co-operative multitasking loop, which continuously executes all the existing tasks: the library already defines several tasks, e.g. for reading and sending network packets and calling the relative callbacks. Custom applications building on this library simply need to add new functions at the end of the loop, taking care of executing tasks as quickly as possible, or splitting them in several loop cycles, in order to let other tasks running smoothly. To enable remote interaction via the Internet, Insteon Hub uses an online service called PubNub (https://www.pubnub.com/). End-users install the "Insteon for Hub" application on their smartphone. Both the smartphone application and Insteon Hub include the PubNub SDK, which allows for a bi-directional communication using PubNub's REST API. The interaction with PubNub happens by means of publish/subscribe methods. Each device has a series of channels it can subscribe to, in order to receive published messages. To subscribe to a specific channel it's enough to call the function pubnub_subscribe (defined in the PubNub SDK), passing as parameter the channel name and a callback function that will be called when a message is received on the specified channel. The device defines a function which parses messages received from PubNub on channel "cc": sub_9d014b1c. The function uses the cJSON library for parsing "JSON" messages and receives a cJSON object as parameter, which corresponds to the message sent from an authenticated smartphone application. As an example, this is a valid JSON message which is used to set the volume on "sonos" speakers connected to Insteon Hub: ``` { "ser": "", "cmd": "s_sonos", "sn_sonos_cmd": "volume", "s_vol": "3" } ``` The function initially checks the cmd parameter, and depending on that it proceeds to extract other expected parameters, in this case sn_sonos_cmd and volume. The information is then either cached to be handled on the next multitasking loop, or immediately applied from within the current function. The vulnerable code exists while parsing any JSON element, the example below follows the disassembly of the path for the "s_sonos" command: ``` seg000:9D014B1C sub_9d014b1c: seg000:9D014B1C seg000:9D014B1C var_418 = -0x418 seg000:9D014B1C var_414 = -0x414 seg000:9D014B1C var_410 = -0x410 ... seg000:9D014B1C var_14 = -0x14 seg000:9D014B1C var_10 = -0x10 seg000:9D014B1C var_C = -0xC seg000:9D014B1C var_8 = -8 seg000:9D014B1C var_4 = -4 seg000:9D014B1C seg000:9D014B1C 000 D8 FB BD 27 addiu $sp, -0x428 seg000:9D014B20 428 24 04 BF AF sw $ra, 0x428+var_4($sp) seg000:9D014B24 428 20 04 BE AF sw $fp, 0x428+var_8($sp) seg000:9D014B28 428 1C 04 B7 AF sw $s7, 0x428+var_C($sp) seg000:9D014B2C 428 18 04 B6 AF sw $s6, 0x428+var_10($sp) seg000:9D014B30 428 14 04 B5 AF sw $s5, 0x428+var_14($sp) seg000:9D014B34 428 10 04 B4 AF sw $s4, 0x428+var_18($sp) seg000:9D014B38 428 0C 04 B3 AF sw $s3, 0x428+var_1C($sp) seg000:9D014B3C 428 08 04 B2 AF sw $s2, 0x428+var_20($sp) seg000:9D014B40 428 04 04 B1 AF sw $s1, 0x428+var_24($sp) seg000:9D014B44 428 00 04 B0 AF sw $s0, 0x428+var_28($sp) seg000:9D014B48 428 21 90 80 00 move $s2, $a0 # ptr to cJSON object seg000:9D014B4C 428 21 98 A0 00 move $s3, $a1 ... seg000:9D014C60 428 21 20 40 02 move $a0, $s2 seg000:9D014C64 428 06 9D 05 3C lui $a1, 0x9D06 seg000:9D014C68 428 F3 43 41 0F jal cJSON_GetObjectItem seg000:9D014C6C 428 24 28 A5 24 la $a1, aCmd # "cmd" seg000:9D014C70 428 0F 00 40 54 bnezl $v0, loc_9D014CB0 ... seg000:9D014CB0 loc_9D014CB0: seg000:9D014CB0 428 06 9D 05 3C lui $a1, 0x9D06 seg000:9D014CB4 428 F3 43 41 0F jal cJSON_GetObjectItem seg000:9D014CB8 428 24 28 A5 24 la $a1, aCmd # "cmd" seg000:9D014CBC 428 1C 01 A4 27 addiu $a0, $sp, 0x428+var_30C # value of "cmd" seg000:9D014CC0 428 1F DF 41 0F jal strcpy seg000:9D014CC4 428 10 00 45 8C lw $a1, 0x10($v0) ... seg000:9D01BE28 428 06 9D 05 3C lui $a1, 0x9D06 seg000:9D01BE2C 428 87 E7 41 0F jal strcmp seg000:9D01BE30 428 5C 2E A5 24 la $a1, aT_db # "t_db" seg000:9D01BE34 428 37 00 40 54 bnezl $v0, loc_9D01BF14 seg000:9D01BE38 428 1C 01 A4 27 addiu $a0, $sp, 0x428+var_30C ... seg000:9D01BF14 loc_9D01BF14: seg000:9D01BF14 428 06 9D 05 3C lui $a1, 0x9D06 seg000:9D01BF18 428 87 E7 41 0F jal strcmp seg000:9D01BF1C 428 64 2E A5 24 la $a1, aS_sonos # "s_sonos" ... seg000:9D01E5C8 428 06 9D 05 3C lui $a1, 0x9D06 seg000:9D01E5CC 428 F3 43 41 0F jal cJSON_GetObjectItem seg000:9D01E5D0 428 08 31 A5 24 la $a1, aSn_sonos_cmd # "sn_sonos_cmd" seg000:9D01E5D4 428 DD 00 40 10 beqz $v0, loc_9D01E94C # goto next param seg000:9D01E5D8 428 00 A0 02 3C lui $v0, 0xA000 seg000:9D01E5DC 428 00 17 40 A0 sb $zero, byte_A0001700 seg000:9D01E5E0 428 21 20 40 02 move $a0, $s2 seg000:9D01E5E4 428 06 9D 05 3C lui $a1, 0x9D06 seg000:9D01E5E8 428 F3 43 41 0F jal cJSON_GetObjectItem seg000:9D01E5EC 428 08 31 A5 24 la $a1, aSn_sonos_cmd # "sn_sonos_cmd" seg000:9D01E5F0 428 B0 02 A4 27 addiu $a0, $sp, 0x428+var_178 seg000:9D01E5F4 428 1F DF 41 0F jal strcpy seg000:9D01E5F8 428 10 00 45 8C lw $a1, 0x10($v0) # valuestring of "sn_sonos_cmd" ... seg000:9D01E790 428 B0 02 A4 27 addiu $a0, $sp, 0x428+var_178 seg000:9D01E794 428 06 9D 05 3C lui $a1, 0x9D06 seg000:9D01E798 428 87 E7 41 0F jal strcmp seg000:9D01E79C 428 5C 30 A5 24 la $a1, aVolume # "volume" seg000:9D01E7A0 428 24 00 40 14 bnez $v0, loc_9D01E834 # goto next param seg000:9D01E7A4 428 15 00 02 2A slti $v0, $s0, 0x15 seg000:9D01E7A8 428 21 20 40 02 move $a0, $s2 seg000:9D01E7AC 428 06 9D 05 3C lui $a1, 0x9D06 seg000:9D01E7B0 428 F3 43 41 0F jal cJSON_GetObjectItem seg000:9D01E7B4 428 18 31 A5 24 la $a1, aS_vol # "s_vol" seg000:9D01E7B8 428 1D 00 40 10 beqz $v0, loc_9D01E830 # goto next param seg000:9D01E7BC 428 06 9D 05 3C lui $a1, 0x9D06 seg000:9D01E7C0 428 21 20 40 02 move $a0, $s2 seg000:9D01E7C4 428 F3 43 41 0F jal cJSON_GetObjectItem seg000:9D01E7C8 428 18 31 A5 24 la $a1, aS_vol # "s_vol" seg000:9D01E7CC 428 00 A0 04 3C+ la $a0, byte_A0001700 # [2] seg000:9D01E7D4 428 1F DF 41 0F jal strcpy # [1] seg000:9D01E7D8 428 10 00 45 8C lw $a1, 0x10($v0) ``` Looking at the pseudocode: ``` if (cJSON_GetObjectItem(obj, "cmd")) { strcpy(buf_cmd, cJSON_GetObjectItem(obj, "cmd")->valuestring); if (!strcmp(buf_cmd, "...")) ... else if (!strcmp(buf_cmd, "...")) ... else if (!strcmp(buf_cmd, "s_sonos")) { if (cJSON_GetObjectItem(obj, "sn_sonos_cmd")) { strcpy(buf_sonoscmd, cJSON_GetObjectItem(obj, "sn_sonos_cmd")->valuestring); if (!strcmp(buf_sonoscmd, "volume")) { if (cJSON_GetObjectItem(obj, "s_vol")) strcpy(global_s_vol, cJSON_GetObjectItem(obj, "s_vol")->valuestring); # [1] } ... } ... } ... } ``` The src parameter for strcpy at [1] is unconstrained, and can lead to a buffer overflow on the global section in RAM. In the example above the overflow happens on the global_s_vol variable which is at 0xa0001700 [2]. This same sequence of vulnerable instructions is present for every supported keyword in the message handler. To send a message, an HTTP GET should be used which embeds the JSON string in the "path" portion of the URL: ``` $ curl https://pubsub.pubnub.com/publish/<pub>/<sub>/<callback>/<channel>/<payload>?auth=<auth-key> <pub>: PubNub's publishKey. The device uses pub-c-a415cc66-b0ca-4d1d-8d9e-947390b35df3 <sub>: PubNub's subscribeKey. The device uses sub-c-e1c54032-1685-11e4-b69f-02ee2ddab7fe <callback>: can be set to 0 <channel>: composed by "<insteon-id>-<channel-suffix>". <insteon-id> corresponds to the lower 3 octets of the MAC address and <channel-suffix> is the actual channel name, in this case "cc" (example of full channel name: 112233-cc) <payload>: contains the JSON message string, the minimal JSON for Insteon is {"ser":""} <auth-key>: key for access control, 16 bytes hex-encoded ``` Example: ``` $ curl 'https://pubsub.pubnub.com/publish/pub-c-a415cc66-b0ca-4d1d-8d9e-947390b35df3/sub-c-e1c54032-1685-11e4-b69f-02ee2ddab7fe/0/112233-cc/0/\{"ser":"","cmd":"s_sonos","sn_sonos_cmd":"volume","s_vol":"3"\}?auth=00112233445566778899AABBCCDDEEFF' ``` The following is a list of vulnerable strcpy calls and their Proof-of-Concept. Each PoC shows only the payload portion of the request and uses the placeholder "OVERFLOW" to highlight the vulnerable parameter, which can be replaced with "A"*0x400 to make the device crash. All buffer overflows happen on a global section in RAM, defined from 0xa0000000 to 0xa001ffff, so they allow for overwriting global objects used both by custom and Microchip's library code. A key with value "x" means that its value is irrelevant. #### CVE-2017-16338 - cmd UpdateCheck, host key At 0x9d01bad0 the value for the host key is copied using strcpy to the buffer at 0xa00016e0. This buffer is 32 bytes large, sending anything longer will cause a buffer overflow. ``` {"cmd": "UpdateCheck", "host": "OVERFLOW"} ``` In this case the device won't crash right away since the overwritten global structures are not normally used. Some of the structures are related to TCP networking functionality. To trigger the crash it is thus enough to connect to the device on any TCP port. #### CVE-2017-16339 - cmd UpdateCheck, uri key At 0x9d01bb1c the value for the uri key is copied using strcpy to the buffer at 0xa00016a0. This buffer is 64 bytes large, sending anything longer will cause a buffer overflow. ``` {"cmd": "UpdateCheck", "host": "x", "uri": "OVERFLOW"} ``` #### CVE-2017-16340 - cmd ssonos, sdport key At 0x9d01c0e8 the value for the s_dport key is copied using strcpy to the buffer at 0xa000180c. This buffer is 6 bytes large, sending anything longer will cause a buffer overflow. ``` {"cmd": "s_sonos", "sn_discover": "0", "s_dport": "OVERFLOW"} ``` Note: In place of the cmd s_sonos, it's also possible to use g_sonos_players, g_sonos_preset, g_sonos_metadata, g_sonos_groups, g_sonos_bindex, g_sonos_vol. Note: sn_discover needs to be a hex number lower than 0x100. #### CVE-2017-16341 - cmd ssonos, svol_play key At 0x9d01c224 the value for the s_vol_play key is copied using strcpy to the buffer at 0xa0000418. This buffer is maximum 8 bytes large (this is the maximum size it could be, it is possible other global variables are stored between this variable and the next one that we could identify), sending anything longer will cause a buffer overflow. ``` {"cmd": "s_sonos", "s_vol_play": "OVERFLOW"} ``` Note: In place of the cmd s_sonos, it's also possible to use g_sonos_players, g_sonos_preset, g_sonos_metadata, g_sonos_groups, g_sonos_bindex, g_sonos_vol. #### CVE-2017-16342 - cmd ssonos, svoldimdelta key At 0x9d01c254 the value for the s_vol_dim_delta key is copied using strcpy to the buffer at 0xa0000514. This buffer is 4 bytes large, sending anything longer will cause a buffer overflow. ``` {"cmd": "s_sonos", "s_vol_dim_delta": "OVERFLOW"} ``` Note: In place of the cmd s_sonos, it's also possible to use g_sonos_players, g_sonos_preset, g_sonos_metadata, g_sonos_groups, g_sonos_bindex, g_sonos_vol. #### CVE-2017-16343 - cmd ssonos, svolbrtdelta key At 0x9d01c284 the value for the s_vol_brt_delta key is copied using strcpy to the buffer at 0xa0000510. This buffer is 4 bytes large, sending anything longer will cause a buffer overflow. ``` {"cmd": "s_sonos", "s_vol_brt_delta": "OVERFLOW"} ``` Note: In place of the cmd s_sonos, it's also possible to use g_sonos_players, g_sonos_preset, g_sonos_metadata, g_sonos_groups, g_sonos_bindex, g_sonos_vol. #### CVE-2017-16344 - cmd ssonos, surl key At 0x9d01c2c8 the value for the s_url key is copied using strcpy to the buffer at 0xa0001a0c. This buffer is 16 bytes large, sending anything longer will cause a buffer overflow. The destination can also be shifted by using an sn_speaker parameter between "0" and "3". ``` {"cmd": "s_sonos", "s_url": "OVERFLOW"} ``` Note: In place of the cmd s_sonos, it's also possible to use g_sonos_players, g_sonos_preset, g_sonos_metadata, g_sonos_groups, g_sonos_bindex, g_sonos_vol. #### CVE-2017-16345 - cmd ssonos, sport key At 0x9d01c318 the value for the s_port key is copied using strcpy to the buffer at 0xa00017f4. This buffer is 6 bytes large, sending anything longer will cause a buffer overflow. The destination can also be shifted by using an sn_speaker parameter between "0" and "3". ``` {"cmd": "s_sonos", "s_port": "OVERFLOW"} ``` Note: In place of the cmd s_sonos, it's also possible to use g_sonos_players, g_sonos_preset, g_sonos_metadata, g_sonos_groups, g_sonos_bindex, g_sonos_vol. #### CVE-2017-16346 - cmd ssonos, smac key At 0x9d01c368 the value for the s_mac key is copied using strcpy to the buffer at 0xa000170c. This buffer is 25 bytes large, sending anything longer will cause a buffer overflow. The destination can also be shifted by using an sn_speaker parameter between "0" and "3". ``` {"cmd": "s_sonos", "s_mac": "OVERFLOW"} ``` Note: In place of the cmd s_sonos, it's also possible to use g_sonos_players, g_sonos_preset, g_sonos_metadata, g_sonos_groups, g_sonos_bindex, g_sonos_vol. #### CVE-2017-16347 - cmd ssonos, svol key At 0x9d01e7d4 the value for the s_vol key is copied using strcpy to the buffer at 0xa0001700. This buffer is maximum 12 bytes large (this is the maximum size it could be, it is possible other global variables are stored between this variable and the next one that we could identify), sending anything longer will cause a buffer overflow. ``` {"cmd": "s_sonos", "sn_sonos_cmd": "volume", "s_vol": "OVERFLOW"} ``` Note: In place of the cmd s_sonos, it's also possible to use g_sonos_players, g_sonos_preset, g_sonos_metadata, g_sonos_groups, g_sonos_bindex, g_sonos_vol. ### Timeline * 2017-11-27 - Vendor Disclosure * 2017-11-28 - Vendor Acknowledged * 2018-01-02 - 30 day follow up with vendor for status * 2018-01-18 - Vendor advised issues under evaluation * 2018-02-12 - 60 day follow up with vendor * 2018-03-09 - Vendor advised working on course of action * 2018-04-06 - Follow up with vendor on fix/timeline status * 2018-04-12- Vendor advised issues addressed & plan for beta testing * 2018-06-19 - Public disclosure
idSSV:97364
last seen2018-06-26
modified2018-06-22
published2018-06-22
reporterMy Seebug
titleInsteon Hub PubNub "cc" Channel Message Handler Multiple Global Overflow Code Execution Vulnerabilities(CVE-2017-16338 ~CVE-2017-16347)

Talos

idTALOS-2017-0484
last seen2019-05-29
published2018-06-19
reporterTalos Intelligence
sourcehttp://www.talosintelligence.com/vulnerability_reports/TALOS-2017-0484
titleInsteon Hub PubNub "cc" Channel Message Handler Multiple Global Overflow Code Execution Vulnerabilities