Author: Larryxi@360GearTeam
0x00 Environment setup
Bluetooth Low Energy is a wireless communication technology. Its design goals and implementation are quite different from classical Bluetooth technology. For an overview and technical details, please refer to the links and works at the end of this article. This paper will make remarks on the protocol packets based on book knowledge, so as to deepen the understanding of the interaction process between master and slave devices and further explore the attack mode against a CERTAIN BLE application.
The selection of master and slave devices in the environment is based on the simulation environment provided by BLUETOOTH SMART HACKMELOCK. Nodejs is used to build a virtual BLE lock in raspberry PI, and an Android app is specially written to operate the lock. There are some security problems left at both ends for our further exploration and learning.
UnicornTeam has mentioned that wireless communication attacks can be divided into listening, replay, spoofing and hijacking attacks. Personally, I feel that only by understanding and analyzing relevant traffic sniffs can I know myself and the other. I brazenly borrowed a nRF51422 from the big team to sniff BLE, and its document NRF-Sniffer-UG-v2 is also clearly written. So the final environment is as shown in the picture (and thanks to Tesi1a for sponsoring raspberry PI) :
0x01 Process Exploration
In the virtual environment built above, when the APP clicks relevant functions, the server responds with a certain log output on the console, which is convenient for us to understand the protocol interaction. Next, I will explain the captured traffic, and the packet traffic has also been backed up to Github. The architecture of Bluetooth low Power is as follows:
Broadcast connection establishment and discovery service features
After setting up the virtual door lock from the device, it is constantly broadcasting. There are seven types of broadcast packets. The most widely used type is ADV_IND. The general structure of broadcast packets is as follows:
You can also see many raspberry PI broadcast packets in the packet:
After passively scanning and receiving the required broadcast packets, the mobile App initiates a connection request:
After the master and slave devices enter the connected state, they send data packets for communication. The format of data packets is slightly different from that of broadcast packets.
The logical link IDENTIFIER LLID in the data packets divides the data packets into three types. The link layer control packet (11) is used to manage the connection. The following data packets are version switching in the management connection:
Not only the link-layer packets, but also the upper-layer services of both devices pass through the L2CAP channel (packet sequence), which is structured as follows:
Low power Bluetooth uses three channels in total. The following L2CAP data packets are low power signaling channels and are used for host layer signaling:
The attribute layer and the generic attribute specification layer are the core concepts of BLE, one is abstract protocol and the other is generic configuration file. An attribute is simply a labeled piece of addressable data. Its structure is as follows:
In Bluetooth Low power, features consist of one or more properties, and services consist of one or more features. Services are grouped by service declarations, and features are grouped by feature declarations. The discovery of services and features is defined by the generic property specification, which manifests itself in different types of property protocols. The following packet reads the primary service declaration by group type read request:
The response is the property handle of all primary service declarations, the last property in the primary service, and the value of the primary service declaration:
Similarly, there are requests and responses for discovery features for each service:
It may not be convenient to see the requested services and features separately in the packet, but bleah can be used to enumerate all the attributes on the device directly:
Door lock initialization configuration
The initial configuration of the door lock output in the server console is as follows:
After receiving the response value, a series of write requests are made to the 0x000C handler. A total of 24 sequences are written to complete the initialization phase:
Switch lock operation
The operation of the switch lock appears to have an internal authentication process on the server console output:
Handler reads a random challenge and writes the response to the 0x000C handler. If the handler is authenticated, the lock can be switched on or off, and the value that the lock writes to the handler is fixed:
The authentication credentials are reset
This function, called Data Transfer on the server, is triggered by receiving a command and regenerating into 24 sequences to inform the client:
We can also see a write request to 0x0010 handler and a retransmission command to 0x000C:
0x02 Attack Mode
The process to explore
What is more interesting in the process is the authentication and data retransmission part of the internal implementation. Firstly, it is speculated whether the lock can be reset by directly writing the data retransmission instruction without authentication. Here, GATttool is used for BLE connection and request:
It is a pity that authentication is required, so we need to analyze the server or client program, reverse the specific process of authentication. Decompile APK on JEB and locate to authentication related logic according to auth string. Know after receiving the Challenge, and v7 together into hackmelockDevice. CalculateResponse method, normal unlock process can make v7 to 1, with qr code share lock processes can make 2 v7 to:
Select * from keyID; select * from keyID; select * from keyID;
The keys array consists of 23 sequences passed in the initial initialization of the lock:
For keyID = 0, tohex = 12 bytes, followed by 16 bytes with null characters, AES encryption is performed twice, which is easy to implement with Python code:
import sys
from Crypto.Cipher import AES
from binascii import a2b_hex, b2a_hex
def calc(key, challenge):
plaint_1 = a2b_hex(challenge)
key_1 = a2b_hex(key)
aes_1 = AES.new(key_1, AES.MODE_ECB)
cipher_1 = aes_1.encrypt(plaint_1)
print b2a_hex(cipher_1)
plaint_2 = a2b_hex("DDAAFF03040506070809101112131415")
key_2 = cipher_1
aes_2 = AES.new(key_2, AES.MODE_ECB)
cipher_2 = aes_2.encrypt(plaint_2)
print b2a_hex(cipher_2)
if __name__ == '__main__':
if len(sys.argv) > 2:
calc(sys.argv[1], sys.argv[2])Copy the code
Server Back door
The server code is written in NodeJS, which looks much easier than android reverse, leaving a back door on the server that allows direct authentication using a specific password:
if ( (authResponse === fin_16.toString('hex')) || (authResponse === '4861636b6d654c6f636b4d6173746572')) { console.log('AUTHENTICATION OK! '.green); this.authenticated = true; this.status = statusAuthenticated; }Copy the code
Authentication code defect
At first, according to normal encryption logic, response written to 0x000C handler always fails authentication. Compared with the console output operated on app, it was found that a 00 was added after the calculated response, and it suddenly woke up to the fact that the last character written was used to indicate keyID. In the server code, it not only loads the 23 keys passed at initialization, but also expands with 00 to 128:
Hackmelock.prototype.loadConfig = function(configFile) {
this.config = fs.readFileSync(configFile).toString().split("\n");
//pop last empty line
this.config.pop();
for (i=this.config.length; i<128; i++) {
this.config.push('000000000000000000000000')
}Copy the code
If we make keyID too large, then the key for the first round of AES encryption has already been determined, and the corresponding authentication measures are invalidated:
Leakage of TWO-DIMENSIONAL code information
There is also a Share feature in the App designed to provide others with temporary access to the lock:
According to the reverse result of App, the qr code will save the sequence of keyID 1. With any key, there is no limit on permissions and time. As a result of above 2 d sweep out 576 c0603:4 ce495e48d0bf00bf1bc85f3:1:15 42885650:1542902400, consistent with the record of before data transmission:
other
- Math.random() is used in the server code to generate random numbers, but this method is not cryptographically secure and may be predicted but I personally have not yet come up with a suitable attack scenario.
- I don’t know much about NodeJS and Android. If you are interested, you can explore it.
0x03 Summary reference
conclusion
- Android can also capture bluetooth packets, but the HCI channel packets on the main device may not look too direct.
- The virtual door lock above uses the default security level, and the link does not have encryption and authentication pairing operations. If you further explore, you can use tools to try the middle man and replay attack. The training handout provided by smartLockpicking team is worth learning.
- From another perspective, students who like to do exercises can try BLE CTF. Of course, it is also possible to dig holes related to BLE.
reference
- The definitive guide to Low Power Bluetooth development
- BLUETOOTH SMART HACKMELOCK
- Internet of Things security extraction “teeth” actual combat — Low power Bluetooth (BLE) exploration
- BLE Security Introduction and Practice (1)
- Hardwear2018BLESecurityEssentials