Remotely Cracking Bluetooth Enabled Gun Safes

Share this…


In this blog post, we will detail BlueSteal, or the ability to exploit multiple security failures in the Vaultek VT20i. These vulnerabilities highlight the need to include security audits early in the product manufacturing process. These vulnerabilities include CVE-2017-17435 and CVE-2017-17436. The VT20i is a very popular product designed for the safe storage of firearms and is one of Amazon’s top sellers in several categories. Along with this post we detail a redacted proof of concept which can unlock Vaultek VT20i Gun Safes that we own through transmission of specially formatted Bluetooth messages.

Disclosure Timeline

The vendor was initially contacted about this vulnerability on 10/6/2017. On 11/7/17 the manufacturer notified us that they had time to review our findings and that they have updated models with “improved Bluetooth security with the option for disabling the Bluetooth unlock or the entire connection altogether.  There is also a time out feature designed for brute force attacks and additional encryption for the communication between the app and safe.” We released this blogpost following a 60-day disclosure period.

The Vulnerabilities

  • The Fun Vulnerability – The manufacturer’s Android application allows for unlimited pairing attempts with the safe.  The pairing pin code is the same as the unlocking pin code. This allows for an attacker to identify the shared pincode by repeated brute force pairing attempts to the safe.
  • The Really Fun Vulnerability- CVE-2017-17436 – There is no encryption between the Android phone app and the safe. The application transmits the safe’s pin code in clear text after successfully pairing. The website and marketing materials advertise that this communication channel is encrypted with “Highest Level Bluetooth Encryption” and “Data transmissions are secure via AES256 bit encryption”. However these claims are not true. AES256 bit encryption is not supported in the Bluetooth LE standard and we have not seen evidence of its usage in higher layers.  AES-128 is supported in Bluetooth LE, but the manufacturer is not using that either. This lack of encryption allows an individual to learn the passcode by eavesdropping on the communications between the application and the safe.
  • The ‘How Does This Even Happen?’ Vulnerability- CVE-2017-17435 – An attacker can remotely unlock any safe in this product line through specially formatted Bluetooth messages, even with no knowledge of the pin code. The phone application requires the valid pin to operate the safe, and there is a field to supply the pin code in an authorization request. However the safe does not verify the pin code, so an attacker can obtain authorization and unlock the safe using any arbitrary value as the pin code.

We will dig into the details of all of these vulnerabilities and how we found them below.

Breaking In The Easy Way

The first step was to acquire the Android APK for interacting with the safe. This APK can be found here: The version we utilized was v2.0.1. The authors of the APK seem to be a Chinese company named Youhone. Upon opening the app, there is initially a view to connect to the safe and pair it using a pincode.

It just so happens that this is the same pincode that is used to unlock the safe. After successfully pairing, we can then use the app to perform commands such as unlocking the safe.

We immediately checked to see if we could successfully mount a brute force attack. The pin is only 4-8 digits in length with numeric values 1-5 available. Due to this relatively small keyspace we can easily script a brute force attack that utilizes ADB to manipulate the manufacturer’s application.  In the attacker’s best case scenario of a 4 character pin code, the search space is a reasonable  5⁴. This would require around 72 minutes at conservative 7 seconds per try.

Below we have a quick and dirty Python script that was written to interact with the phone over ADB and input sequential key combinations. When the script iterates to the correct pin/key, the safe will pop open.

This vulnerability could have been prevented or mitigated if the application or safe had timeouts for incorrect retries, or enforced some maximum retry limit.

We had a good chuckle with this, however we wanted to access this safe without relying on brute force.

Reverse Engineering

The Vaultek APK is responsible for pairing with and unlocking the safe. There are two approaches to understanding its functionality:

  • Static analysis through identifying code in the APK responsible for generating the unlock commands.
  • Dynamic analysis through packet captures of transmitted commands and logging output.

The protocol used to communicate between the safe and the application is Bluetooth Low Energy, here is a link to some extra reading.

Packet Capture


We initially used an Ubertooth to sniff the traffic going between the phone and the safe, logging the capture to disk.

After examining the packet capture, it was clear that AES 256 encryption was not being utilized. Write commands were being conducted in clear text.

Since this is the case, it is actually much simpler to just use the Android built in Bluetooth HCI log. Here is a good article on how to utilize this feature.

Here is a link to an Android capture that showcases the conversation.

In the packet capture we can clearly see where the Bluetooth Low Energy GATT conversation starts. It appears that the APK issues a single write request to the 0xB handle. This is to enable notifications. This is then followed by a lengthy exchange with the 0xA handle.

For now, let’s go back to the APK to see what those data payloads represent.

APK Code Analysis

On a parallel path, we used apktool and dex2jar to extract class files from the APK. Luyten, a GUI for the Procyon decompiler, was used to inspect decompiled code.

One class that seemed particularly interesting was OrderUtilsVT20. Among other thingsThis class contain formatting code for command payloads. There are also “magic” constants that are associated with various types of commands.

Unfortunately these values do not show up directly in the packet capture. Upon more investigation we discovered that this was because the application and safe were performing an odd encoding routine to pack and morph the payload data. The APK also breaks up the encoded payload into 20 byte length chunks. This matches the format observed in the packet capture.

The encoding function is below:

After discovering this, it was relatively trivial to reverse the encoding process, our decoding function is below.

After applying this decoding function to the captured payloads, it becomes easy to identify the commands the app was transmitting to the safe. Here is the conversation we observed.

The two most interesting commands out of this conversation are getAuthor and openDoor.

Here is the code responsible for formatting the getAuthor command.

We can see that there is a call to setPassWord, this places the padded pin code at the end of the getAuthorpacket.

The structure of the getAuthor command then is as follows:

This is troublesome since the APK transmits the programmed pin code without encryption during the unlocking process. Which reveals our second vulnerability, transmission of the pin code in plaintext.

It also hit us that getAuthor is short for getAuthorization. Delving into this message, we get the structure shown in the table above. Of note the pin code at the end of the structure is actually transmitted in the plain text in the getAuthor command. Which brings us to our final vulnerability, the safe does not check the pin code transmitted in the getAuthor packet, and will reply with a proper authorization token no matter what is in the field.

The safe’s response to the getAuthor command contains an authorization code or token located in the first 4 bytes. It took us a bit of time to figure out that this return message was a necessary component of theopenDoor message. Thus, all we need to do is obtain an authorization code for the openDoor command in order for it to unlock the safe.

We can see this occurring in com.youhone.vaultek.utils.ReceiveStatusVT20.ReceiveStatusVT20.

The openDoor command has the following format after filling in the first 4 bytes with the auth code. 

In the end the minimum necessary conversation to open the safe is just:

Proof of Concept (Redacted)

Here is a redacted proof of concept code used to open the safe. The below script will not in and of itself be able to open a safe without a bit of work.

The steps this script performs are:

  • Define two template payloads for getAuthor and openDoor.
  • Scan for the safe, locate the service and characteristic that we want to interact with by UUID.
  • Write a 0x01 value into the Client Characteristic Configuration Descriptor in order to enable notifications.
  • Send our getAuthor encoded template payload in 20 byte chunks as a write command. We then wait for a handle value notification and retrieve the response.
  • Decode the response, and take the first 4 bytes as the authorization token. We plop these authorization bytes into our openDoor command template.
  • After transmitting the openDoor command, the safe should open.

We later learned the only fields in the getAuthor command that matter are the hardcoded magic bytes and the CRC value.

This means a getAuthor command with any pincode value can return back an authorization code that can open up the safe.

Even better, the openDoor command only checks that the authorization code, magic values, and CRC.

We have tested and verified this functionality on multiple Vaultek VT20i safes.

Summing It Up

The vulnerabilities found in this safe allow an unauthorized user to access it’s contents.

This is particularly troubling because:

  • These safes are advertised to hold firearms
  • They have regulatory approval to be used to transport firearms through TSA
  • Are advertised to use security technologies such as encryption

This should serve as a stark reminder to manufacturers of smart products that security audits can be extremely beneficial, particularly if coding or design work is being outsourced. In this case an audit before the product came to market would have revealed all of these vulnerabilities, which then could have been fixed in production. It is next to impossible for a manufacturer to fix these sorts of issues after sales begin. Thus, care needs to be taken to carefully engineer the security of the platform and its update mechanisms.