Blog: Vulnerability Advisory
The not so ultra lock
This post couldn’t have been written without @evstykas and @cybergibbons.
I became aware of the Ultraloq from U-tec a few months ago. For a room door lock it has a range of what look like really good features:
Ultraloq UL3 smart lever lock is designed to be “Real Keyless”. You are free to use fingerprint, code or key to unlock. You have full control of all guests’ access and you can simply share a code to let visitors in when you are not there.
…but can it deter or even repel a determined attacker?
TL;DR
From the mobile app API we can recover personal data from the users account, often enough to locate the house and lock.
From the API we can reset the lock PIN, locking the user out, or allowing us to unlock their door.
We can physically visit a lock and trivially unlock it over Bluetooth.
The physical lock is easy to pick as well.
BTW this isn’t all my own work, @cybergibbons and @evstykas contributed too.
Obtainable BLE encryption key
The BLE packet is encrypted to prevent easy sniffing and replay of a control packet.
The key is constructed of two parts:
- A token obtained from the lock
- A static salt
These parts are concatenated together to produce a 16 octet byte array, the appropriate size for an AES key.
The static salt can be obtained from the app and is equivalent to the string;
Anviz.ut
The token can be obtained by querying the BLE characteristic with a UUID of 00007220-0000-1000-8000-00805f9b34fb and a handle of 0x22. This can be obtained by just reading the characteristic:
As the code for the lock is a 6 digit integer, this makes it possible to attempt a brute force attack against the lock through the BLE interface.
API auth? Nope
API has no authentication at all. The data is obfuscated by being base64 twice but decoding it exposes that the server side has no authentication or authorization logic. This leads to an attacker being able to get data and impersonate all the users. This leads to a full compromise of all the locks that are connected to the cloud service.
This attack affects all endpoints of the “ultraloq” mobile app.
Example requests and responses:
GET USER INFO
POST /index.php/user/get_userinfo_ex HTTP/1.1 Content-Length: 107 Content-Type: application/x-www-form-urlencoded Host: app.service.u-tec.com Connection: close User-Agent: thinkandroid/1.1 (http://www.thinkandroid.cn) Accept-Encoding: gzip, deflate data=ZXlKd1lYSmhiWE1pT25zaWRYTmxjbWxrSWphMDRiNGIxZGJlZjI3Mzhlb2lNelkyTWpJaWZYMD0K%0A&token=8453661149ac73b2
We can decode the data parameter with the double base64 way too:
ZXlKd1lYSmhiWE1pT25zaWRYTmxjbWxrSWphMDRiNGIxZGJlZjI3Mzhlb2lNelkyTWpJaWZYMD0K%0A -> {"params":{"userid"36622"}}
We can see that the userid is an integer that we can enumerate on.
GET USER LOCKS
POST /index.php/user/get_userinfo_ex HTTP/1.1 Content-Length: 107 Content-Type: application/x-www-form-urlencoded Host: app.service.u-tec.com Connection: close User-Agent: thinkandroid/1.1 (http://www.thinkandroid.cn) Accept-Encoding: gzip, deflate data=ZXlKd1lYSmhiWE1pT25zaWRYTmxjbWxrSWphMDRiNGIxZGJlZjI3Mzhlb2lNelkyTWpJaWZYMD0K%0A&token=8453661149ac73b2
We can decode the data parameter with the double base64 way too:
ZXlKd1lYSmhiWE1pT25zaWRYTmxjbWxrSWphMDRiNGIxZGJlZjI3Mzhlb2lNelkyTWpJaWZYMD0K%0A -> {"params":{"userid"36622"}}
This means that we can potentially enumerate all locks of all users. In the response body of this request we can retrieve the BLE encryption key and potentially all the users pins. We can also change those values. The easiest way to a full compromise is intercept the login process and change the userid of the logged in user. After that the app will function as the user with the userId that we have provided has logged in , providing full control over all of their locks.
Can I pick it? Yes you can
The device allows for a thin pick to be inserted in to the body and used to shim the internal mechanism to open the lock manually.
Figure 1- picking the lock
The Ultraloq has a back-up key lock in the base of the device – in case the electronic side fails. And that lock is not a good one – an amateur can reliably open them quickly and easily, both with single pin picking and raking. It’s certainly not up to the standards we would expect to see on an external door.
It’s also possible to insert a thin tool (a modified lock pick) down the side of this lock and manually actuate the latch. A simple bypass that should be protected against.
Good luck fixing these with a firmware update.
Unencrypted storage
If access can be gained to the back (“secure side”) of the device, then it can be taken apart in a matter of minutes and access can be gained to an external SPI flash chip. This chip can be read fully in less than a minute using a simple Raspberry Pi and a SOIC-8 clip.
Figure 2- SPI Flash chip (ignore the wires)
Once dump, the flash memory was found to mostly be blank (set to a default value of 0xff), but some data areas were found:
Address | Data Contained |
0x10000 | User data and their PINs |
0x20000 | User data and their raw fingerprint data |
The data at 0x10000 follows a similar format to that used in the BLE packet. Each entry consists of 16 bytes:
00 00 00 F0 | User number, stored as a 4 octet little endian value (in this case 240) |
3F 42 0F | PIN, stored as a 3 octet little endian value (in this case 999999) |
60 00 00 00 00 | Unknown (appears to be user’s role) |
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | Blank data |
D9 DF C1 21 | Unknown (likely to be a checksum) |
The data at 0x20000 is unknown, but follows an obvious pattern with three chunks of data occupying 0x400 octets of data.
Conclusion
While U-tec did eventually fix the API, they have still not addressed the BLE issue to prevent brute forcing, and nor have they warned customers of the risk of bypassing the mechanical back up lock.
Not great U-tec, not great.
Disclosure timeline
2019-04-09 – First contact with U-tec to report vulnerabilities
2019-04-09 – Quick reply from U-tec requesting clarification
2019-04-10 – PTP supply clarification
2019-04-12 – PTP supply further clarification on request
2019-04-15 – Email from U-tec saying “…we will fix that issue quickly”
2019-04-16 – PTP ask again that the API be taken down
2019-04-22 – Reply to say that U-tec will have the issue fixed by w/c 29th April, and a request for extension to disclosure
2019-04-24 – Request for clarification of the location issue
2019-04-29 – PTP ask for an update
2019-05-01 – API flaw fixed, PTP ask when BLE issues will be fixed
2019-05-13 – PTP again ask when BLE issues will be fixed
2019-05-28 – U-tec request another month to fix BLE issue
2019-06-18 – PTP request an update and for U-tec to provide a comment for the disclosure blog post. No reply to date