Talos Vulnerability Report

TALOS-2018-0602

Yi Technology Home Camera 27US CRCDec denial-of-service vulnerability

October 31, 2018
CVE Number

CVE-2018-3935

Summary

An exploitable code execution vulnerability exists in the UDP network functionality of Yi Home Camera 27US 1.8.7.0D. A specially crafted set of UDP packets can allocate unlimited memory, resulting in denial of service. An attacker can send a set of packets to trigger this vulnerability.

Tested Versions

Yi Technology Home Camera 27US 1.8.7.0D

Product URLs

https://www.yitechnology.com

CVSSv3 Score

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

CWE

CWE-400: Uncontrolled Resource Consumption

Details

Yi Home Camera is an internet-of-things home camera sold globally. The 27US version is one of the newer models sold in the U.S., 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 such as the ability to view the video from anywhere, offline and subscription-based cloud storage, and ease of setup.

When the Yi Camera communicates with the ‘Yi Home’ phone app, in order to provide video feeds and status updates, the network daemon in charge is the p2p_tnp binary. This daemon provides network discovery, authorization, and also settings manipulation functionality, all over UDP. The custom protocol handling this is rather simple to start, and a basic overview is given below:

| Magic Byte |  Opcode Byte |  MsgLen Short |  Message (max 0x500)
|       \xF1      |    \x00-\xFF    |   <len of msg> |   <msg>

If the camera and the phone running the ‘Yi Home’ app are on the same subnet, a handshake occurs with the custom TNP protocol before any other operations can happen. The phone sends a MSG_LAN_SEARCH (\x30) packet to UDP port 31208, to which the phone will respond with an MSG_LAN_NOTIFY (\x31) packet from a new source port. It should be noted that this MSG_LAN_SEARCH can be sent to a broadcast address or a single IP address, and also that the MSG_LAN_SEARCH response contains the Device ID (DID) of the camera, which is needed to pass certain checks. A sample DID consists of a prefix, serial and suffix, for example: TNPUSAC-112233-NMEDP.

After the initial packet exchange, the thread controlling this socket enters the PPPP_thread_recv_Proto_device function, which contains a jumptable for dealing with a subset of the possible TNP opcodes. Of interest for this bug is the MSG_DEV_LGN_ACK_CRC opcode, which seems to validate a response from remote servers by utilizing a complex CRC algorithm. Throughout testing, this message has not been seen naturally on the wire, so the theory is that this is artifact code that has not been removed. The relevant disassembly follows below:

LDR      R3, =0xFFFFF6C0
ADD      R2, SP, #0x998+memcpy_base_ptr
LDRH    R1, [R2,R3]     //[1]
STR       R1, [SP,#0x998+size_of_inp]
ADD     R11, R1, #4
MOV     R0, R11         
BL         malloc
LDR      R1, [SP,#0x998+size_of_inp] 
MOV     R3, R11        
MOV     R9, R0
MOV     R2, R9          //[2]
MOV     R0, R10         
BL         tnp::PPPP_CRCDec //[3]

At [1], the size of the input buffer data is taken and added to 0x4 before using that as the size of the input malloc buffer, which is stored into R2 eventually [2]. At 3, a call to tnp::PPPP_CRCDec is made, with the following approximation of parameters:

tnp::PPPP_CRCDec(udpbuff, inp_malloc, inp_malloc_size, udpbuff_size, crc_IV)
// udpbuff => data of our packet
// udpbuff_size = inp_malloc_size + 0x4.
// crc_IV => Empty.

Once inside of CRCDec, a quick stub is called to load the CRC_IV, which doesn’t actually load anything, and then we step into the main body. To summarize the main functionality, it allocates a new buffer of size size_of_inp - 0x4, does a bunch of CRC operations on our input buffer, and throws that into the buffer that was just allocated. Interestingly, approximately only the first 0xD0 bytes are actually CRC’d, the rest are just copied over from the UDP buffer to the malloc’d buffer.

After this, the code walks backward from the end of the CRC’d bytes and replaces all “\x43”/”C” bytes with null bytes, until it hits the end of the buffer-4. If the function finds a byte that is not a “C”, the function returns an error, after freeing the inner buffer. If the function only finds “CCCC” however, the CRC’d data will be memcpy’d from the buffer malloc’d inside the CRCDec function to the buffer that was malloc’d and then passed in as the inp_malloc parameter. After this, the program will free the inner malloc buffer.

When the CRCDec function returns, if the CRC checksum “CCCC” was not found and CRCDec returned an error, PPPP_thread_recv_Proto_device will just free the buffer allocated before CRCDec, and return to processing new packets:

.text:00026EC4  MOV     R0, R9          ; ptr
.text:00026EC0  BL      free
.text:00026EC4  B       loc_25B0C       ; jumptable 00025BFC default case

Unfortunately, if there was no error, the login status is updated, and nothing else really occurs. The buffer malloc’d before CRCDec is never freed, allowing an arbitrary amount of memory to be allocated by the `p2p_tnp process, causing quite a few unintended consequences.

Depending on the amount of these packets sent, and also the size of the data allocated, different outcomes can be achieved by an unauthenticated attacker with network connectivity. For testing purposes, the following buffer was used: `”A”*0x4A0+”CCCC”.

If one sends approximately 0xC00 packets, the device’s LED will eventually start blinking and the camera’s owners will no longer be able to reach the device from their Yi Home phone apps, even though it maintains network connectivity. The camera must then be physically rebooted in order to regain functionality. It is theorized that only the tnp_p2p service is crashing at this point, rendering the UDP network comms disabled.

If one sends approximately 0x1000 packets, then the device LED also starts blinking, but this time, the cloud, p2p_tnp, wpa_supplicant and udhcp services all crash, causing a complete network disconnect. After a certain amount of time, the dispatch binary will realize that wpa_supplicant has crashed, and will promptly reboot the device. Thus, depending on the goals of the attacker, a camera reboot can also be propagated with this vulnerability.

Timeline

2018-06-13 - 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

Credit

Discovered by Lilith (>_>) of Cisco Talos.