Skip to content
This repository has been archived by the owner on Feb 21, 2022. It is now read-only.

Protocol CoAP

Alexander Thoukydides edited this page Oct 2, 2020 · 9 revisions

SkyBell HD Doorbell ↔ Cloud CoAP Usage

⚠️ The following description is based on sniffing the (encrypted) packets sent and received by a SkyBell HD doorbell. There may be significant errors and omissions.

When originally launched the SkyBell HD exchanged CoAP (Constrained Application Protocol) messages with its cloud services without any encryption, authentication or integrity checking (as reported at Purdue University's The 2017 Annual CERIAS Information Security Symposium). This made it easy to sniff exchanges and identify interesting events such as button presses and motion detection.

A subsequent firmware update added encryption, presumably utilising DTLS (Datagram Transport Layer Security). However, this is insufficient to provide complete confidentiality. It is still possible to identify interesting events (button/motion and on-demand video) just by passively monitoring the packet lengths. These events can be detected far quicker by this method than is possible via polling the cloud services.

Refer to the protocol overview for the wider context of these packet exchanges.

Note:

  • The (encrypted) CoAP packets are all carried in UDP datagrams with the source and destination port set to 5683.
  • Lengths specified below are the size of the UDP data (payload), i.e. 8 bytes less than the length field in the UDP header.
  • Due to the use of UDP the precise sequencing of these packets may vary, and some of the datagrams may also be dropped.

Idle

When the doorbell is idle the following sequence repeats continuously.

    ┌────────────┐                                               ┌─────┐
    │ SkyBell HD │                                               │ AWS │
    └─────┬──────┘                                               └──┬──┘
          │                                                         │
          │321 bytes                                                │
          ├────────────────────────────────────────────────────────►│
          │                                                 97 bytes│ 
  ─────── │◄────────────────────────────────────────────────────────┤ 
     ▲    │                                                         │ 
 ~30 secs │                                                         │ 
     ▼    │113 bytes                                                │ 
  ─────── ├────────────────────────────────────────────────────────►│
          │                                                 97 bytes│ 
  ─────── │◄────────────────────────────────────────────────────────┤
     ▲    │                                                         │
 ~30 secs │                                                         │ 
     ▼    │321 bytes                                                │ 
  ─────── ├────────────────────────────────────────────────────────►│
          │                                                 97 bytes│ 
  ─────── │◄────────────────────────────────────────────────────────┤ 
     ▲    │                                                         │ 
 ~30 secs │                                                         │ 
     ▼    │113 bytes                                                │ 
  ─────── ├────────────────────────────────────────────────────────►│
          │                                                 97 bytes│ 
  ─────── │◄────────────────────────────────────────────────────────┤
     ▲    │                                                         │
 ~30 secs │                                                         │ 
     ▼    │                           ...                           │ 

The 97-byte packet appears to be some form of acknowledgement that is also used in other message exchanges. If it is not received then the initiator (the doorbell in this case) retransmits its packet.

During a Call

While the doorbell is streaming live video to an app (via a cloud services proxy) the repeating idle sequence changes to:

          │                                                         │
          │113 bytes                                                │ 
          ├────────────────────────────────────────────────────────►│
          │                                                 97 bytes│ 
  ─────── │◄────────────────────────────────────────────────────────┤ 
     ▲    │                                                         │ 
 ~30 secs │                                                         │ 
     ▼    │113 bytes                                                │ 
  ─────── ├────────────────────────────────────────────────────────►│
          │                                                 97 bytes│ 
  ─────── │◄────────────────────────────────────────────────────────┤
     ▲    │                                                         │
 ~30 secs │                                                         │ 
     ▼    │                           ...                           │ 

Button Press or Motion Event

When the doorbell starts recording video it sends a notification to the cloud services:

    ┌────────────┐                                               ┌─────┐
    │ SkyBell HD │                                               │ AWS │
    └─────┬──────┘                                               └──┬──┘
          │                                                         │
   <Button pressed>                                                 │
          │                                                         │
          │465 bytes                                                │
          ├────────────────────────────────────────────────────────►│
          │                                                 49 bytes│ 
          │◄────────────────────────────────────────────────────────┤ 
          │                                                         │ 

This notification is sent regardless of the cause (button pressed, motion detected, or call from the app). Presumably the content of the CoAP message specifies the type of event, but this cannot be determined purely from the packet length.

Answered Event

If the app initiates a call while the doorbell is recording video for a button press or motion event then the cloud services sends a call request to the doorbell:

          │                                                         │
          │                                               <Answer Button/Motion>
          │                                                         │
          │                                               ~900 bytes│ 
          │◄────────────────────────────────────────────────────────┤ 
          │49 bytes                                                 │
          ├────────────────────────────────────────────────────────►│
          │                                                         │

The precise length of the packet from the cloud services varies (lengths of 897 and 913 bytes have been seen).

Watch Live

If Watch Live is requested from the app then the cloud services sends a call request to the doorbell (with the same length as for an answered button/motion event). However, in this case the doorbell responds with a notification that it has started recording on-demand video (again the same length as for a button/motion event):

    ┌────────────┐                                               ┌─────┐
    │ SkyBell HD │                                               │ AWS │
    └─────┬──────┘                                               └──┬──┘
          │                                                         │
          │                                                    <Watch Live>
          │                                                         │
          │                                               ~900 bytes│ 
          │◄────────────────────────────────────────────────────────┤ 
          │49 bytes                                                 │
          ├────────────────────────────────────────────────────────►│
          │                                                         │
          │465 bytes                                                │
          ├────────────────────────────────────────────────────────►│
          │                                                 49 bytes│ 
          │◄────────────────────────────────────────────────────────┤ 
          │                                                         │

The ordering of the message exchanges, i.e. whether the 465-byte notification from the doorbell is preceded by a ~900-byte call request, can be used to distinguish between button/motion events and Watch Live.

Call Termination

Call Termination by App

If the app ends the call then it sends two requests:

    ┌────────────┐                                               ┌─────┐
    │ SkyBell HD │                                               │ AWS │
    └─────┬──────┘                                               └──┬──┘
          │                                                         │
          │                                                     <End call>
          │                                                         │
          │                                                289 bytes│ 
          │◄────────────────────────────────────────────────────────┤ 
          │49 bytes                                                 │
          ├────────────────────────────────────────────────────────►│
          │                                                 33 bytes│ 
          │◄────────────────────────────────────────────────────────┤ 
          │49 bytes                                                 │
          ├────────────────────────────────────────────────────────►│
          │                                                         │

Call Termination by Doorbell

Alternatively, if the doorbell ends the call (after approximately 5 minutes):

    ┌────────────┐                                               ┌─────┐
    │ SkyBell HD │                                               │ AWS │
    └─────┬──────┘                                               └──┬──┘
          │                                                         │
      <End call>                                                    │
          │                                                         │ 
          │449 bytes                                                │
          ├────────────────────────────────────────────────────────►│
          │289 bytes                                                │
          ├────────────────────────────────────────────────────────►│
          │                                                 33 bytes│ 
          │◄────────────────────────────────────────────────────────┤ 
          │                                                 33 bytes│
          │◄────────────────────────────────────────────────────────┤ ───────  
          │                                                         │    ▲    
          │                                                         │ ~2.5 secs
          │                                                 33 bytes│    ▼   
          │◄────────────────────────────────────────────────────────┤ ───────  
          │                                                 33 bytes│ 
          │◄────────────────────────────────────────────────────────┤ ───────  
          │                                                         │    ▲
          │                                                         │ ~2.5 secs
          │                                                 33 bytes│    ▼    
          │◄────────────────────────────────────────────────────────┤ ───────  
          │                                                 49 bytes│ 
  ─────── │◄────────────────────────────────────────────────────────┤
     ▲    │                                                         │ 
~1.5 secs │                                                         │ 
     ▼    │49 bytes                                                 │ 
  ─────── ├────────────────────────────────────────────────────────►│
          │449 bytes                                                │
          ├────────────────────────────────────────────────────────►│
          │289 bytes                                                │
          ├────────────────────────────────────────────────────────►│
          │449 bytes                                                │
          ├────────────────────────────────────────────────────────►│
          │289 bytes                                                │
          ├────────────────────────────────────────────────────────►│
          │49 bytes                                                 │
          ├────────────────────────────────────────────────────────►│
          │                                                 65 bytes│ 
          │◄────────────────────────────────────────────────────────┤ 
          │                                                 65 bytes│ 
          │◄────────────────────────────────────────────────────────┤ 
          │                                                 65 bytes│ 
          │◄────────────────────────────────────────────────────────┤ 
          │                                                 65 bytes│ 
          │◄────────────────────────────────────────────────────────┤ 

The precise details of this sequence (packet ordering and number of duplicates) can vary slightly, but the packet lengths appear to be consistent.

Other Exchanges

CoAP messages are also exchanged at other times, e.g. when the app is used to modify the doorbell's configuration. It is quite likely that these will sometimes use packets of the same lengths as those illustrated above.