An exploitable denial-of-service vulnerability exists in the Weave daemon of the Nest Cam IQ Indoor, version 4620002. A set of TCP connections can cause unrestricted resource allocation, resulting in a denial of service. An attacker can connect multiple times to trigger this vulnerability.
Nest Labs Nest Cam IQ Indoor version 4620002
5.3 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
CWE-400: Uncontrolled Resource Consumption
The Nest Cam IQ Indoor is one of Nest Labs’ most expensive and advanced devices, integrating Google Assistant, facial recognition and even the ability to act as an 6lowpan hub for other, less powerful internet-of-things devices. The main protocol that is used for setup and initial communications of Nest devices is Weave, a protocol designed strictly for IoT devices, which can run over TCP, UDP, Bluetooth and 6lowpan.
Due to the fact that Weave devices can inherently handle so many different device types, shared object pools were implemented to keep track of all the connection types: TCP, UDP, Tunnel, Raw, AsyncDNS, and also BLE. For instance, inside of the
/src/inet/ directory, we can see a static allocation of a pre-set amount of different endpoints:
DNSResolver.h: static Weave::System::ObjectPool<DNSResolver, INET_CONFIG_NUM_DNS_RESOLVERS> sPool; RawEndPoint.h: static Weave::System::ObjectPool<RawEndPoint, INET_CONFIG_NUM_RAW_ENDPOINTS> sPool; TCPEndPoint.h: static Weave::System::ObjectPool<TCPEndPoint, INET_CONFIG_NUM_TCP_ENDPOINTS> sPool; TunEndPoint.h: static Weave::System::ObjectPool<TunEndPoint, INET_CONFIG_NUM_TUN_ENDPOINTS> sPool; UDPEndPoint.h: static Weave::System::ObjectPool<UDPEndPoint, INET_CONFIG_NUM_UDP_ENDPOINTS> sPool;
The default configuration of Weave allocates endpoints with 0x40 endpoints, but in the actual Nest Cam IQ Indoor, there’s only 0x8 TCP endpoints. As one might expect, as someone connects to the Weave daemon over TCP, a given TCP endpoint is allocated, but interestingly, the TCPEndpoints are never set to have an idle timeout. The
nl::Inet::TCPEndPoint::SetIdleTimeout(unsigned int) function is called with a parameter of 0x0, causing all TCP endpoint connections to never expire. When someone tries to connect after all TCP endpoints are gone, the connection is closed and the following log messages are given:
WEAVE:IN: ERROR: TCP endpoint pool FULL WEAVE:EM: ERROR: Accept FAILED, err = Inet Error -1979: No more TCP endpoints
Thus, if an attacker trivially connects eight different TCP sockets, then all other devices are denied connectivity to the given Weave daemon. While the timeout issue causes this to be trivial to trigger, the core issue is that there’s a small and static number of connections that can be allocated.
Some other things worth noting: If someone connects over any other Transport layer (BLE, UDP, 6lowpan), then the connection gets through. It is thought that BLE would be just as simple to DOS, but UDP would not be possible to prevent. It does seem however that nothing by default will do authenticated PASE or CASE sessions over UDP, so authenticated sessions can still be denied for now. Also worth noting is that if someone wants to deny Weave service to the Nest Cam IQ Indoor, there seems to be a persistent Weave connection to Nest Lab’s servers (most likely
nexus.dropcam.com), and one would have to either deny access to the camera on boot in order to prevent this communication, or be able to sever this remote connection.
2019-04-18 - Vendor Disclosure
2019-05-20 - Vendor completed analysis
2019-06-18 - Follow up with vendor
2019-07-02 - 90 day notice; Vendor advised updates scheduled for release mid-July
2019-07-18 - Vendor advised fix will release end of July and be tested in the field
2019-07-26 - Extended disclosure date to 2019-08-15
2019-08-19 - Public Release
Discovered by Lilith Wyatt and Claudio Bozzato of Cisco Talos.