Ejemplo n.º 1
0
def hciKnobCallback(record):
    """
    Adds a new callback function so that we do not need to call Wireshark.
    """
    hcipkt = record[0]
    if not issubclass(hcipkt.__class__, hci.HCI_Event):
        return

    if hcipkt.event_code == 0x0e:
        if u16(hcipkt.data[1:3]) == 0x1408:  # Read Encryption Key Size
            if hcipkt.data[3] == 0x12:  # Error
                log.info(
                    "No key size available.\n"
                    " - Did you already negotiate an encrypted connection?\n"
                    " - Did you choose the correct connection handle?\n")
            else:
                log.info(
                    "HCI_Read_Encryption_Key_Size result for handle 0x%x: %x" %
                    (u16(hcipkt.data[4:6]), hcipkt.data[6]))

    return
    def from_connection_buffer(connection):

        # Possible TODO: Convert this to a Katai Struct parser with a proper .ksy grammar.
        return ConnectionInformation(
            u32(connection[:4]),
            connection[0x28:0x2E][::-1],
            u32(connection[0x4C:0x50]),
            u32(connection[0x1C:0x20]) & 1 << 15 == 0,
            u16(connection[0x64:0x66]),
            connection[0x78:0x88],
            u8(connection[0xA7:0xA8]),
            connection[0x68:0x68 + u8(connection[0xA7:0xA8])],
            u8(connection[0x9C:0x9D]) - 127,
            connection[0x30:0x38],
            connection[0x38:0x40],
            connection[0x0C:0x0D],
        )
Ejemplo n.º 3
0
def lereceiveStatusCallback(record):
    """
    RXDN Callback Function

    Depends on the raspi3_rxdn.py or eval_rxdn.py script,
    which patches the _connTaskRxDone() function and copies
    info from the LE connection struct to HCI.
    """

    hcipkt = record[0]  # get HCI Event packet

    if not issubclass(hcipkt.__class__, hci.HCI_Event):
        return

    if hcipkt.data[0:4] == "RXDN":
        data = hcipkt.data[4:]

        # Raspi 3 gets errors
        if len(data) < 239:
            return

        #if raspi or s8:
        packet_curr_nesn_sn = u8(data[0xa0])

        #elif eval:
        #    packet_curr_nesn_sn = u8(data[0xa4])

        packet_channel_map = data[0x54:0x7b]
        packet_channel = data[0x83]
        packet_event_ctr = u16(data[0x8e:0x90])
        packet_rssi = data[0]

        if internalblue.last_nesn_sn and ((internalblue.last_nesn_sn ^ packet_curr_nesn_sn) & 0b1100) != 0b1100:
            log.info("             ^----------------------------- ERROR --------------------------------")

        # currently only supported by eval board: check if we also went into the process payload routine,
        # which probably corresponds to a correct CRC
        # if self.last_success_event and (self.last_success_event + 1) != packet_event_ctr:
        #    log.debug("             ^----------------------------- MISSED -------------------------------")

        # TODO example for setting the channel map
        # timeout needs to be zero, because we are already in an event reception routine!
        # self.sendHciCommand(0x2014, '\x00\x00\xff\x00\x00', timeout=0)

        internalblue.last_nesn_sn = packet_curr_nesn_sn

        # draw channel with rssi color
        color = '\033[92m'  # green
        if 0xc8 > packet_rssi >= 0xc0:
            color = '\033[93m'  # yellow
        elif packet_rssi < 0xc0:
            color = '\033[91m'  # red

        channels_total = packet_channel_map[37]
        channel_map = 0x0000000000
        if channels_total <= 37:  # raspi 3 messes up with this during blacklisting
            for channel in range(0, channels_total):
                channel_map |= (0b1 << 39) >> packet_channel_map[channel]

        log.info("LE event %5d, map %10x, RSSI %d: %s%s*\033[0m " % (packet_event_ctr, channel_map,
                                                                      (packet_rssi & 0x7f) - (128 * (packet_rssi >> 7)),
                                                                      color, ' ' * packet_channel))
Ejemplo n.º 4
0
 def from_data(data):
     handle = u16(unbits(bits_str(data[0:2])[0:12].rjust(16, "0")))
     ps = u8(unbits(bits_str(data[1:2])[4:6].rjust(8, "0")))
     return HCI_Sco(handle, ps, u8(data[2]), data[3:])
Ejemplo n.º 5
0
 def from_data(data):
     handle = u16(unbits(bits_str(data[0:2])[0:12].rjust(16, "0")))
     bp = u8(unbits(bits_str(data[1:2])[4:6].rjust(8, "0")))
     bc = u8(unbits(bits_str(data[1:2])[6:8].rjust(8, "0")))
     return HCI_Acl(handle, bp, bc, u16(data[2:4]), data[4:])
Ejemplo n.º 6
0
 def from_data(data):
     return HCI_Cmd(u16(data[0:2]), data[2], data[3:])
Ejemplo n.º 7
0
    def getHciDeviceList(self):
        # type: () -> List[Device]
        """
        Get a list of available HCI devices. The list is obtained by executing
        ioctl syscalls HCIGETDEVLIST and HCIGETDEVINFO. The returned list 
        contains dictionaries with the following fields:
            dev_id          : Internal ID of the device (e.g. 0)
            dev_name        : Name of the device (e.g. "hci0")
            dev_bdaddr      : MAC address (e.g. "00:11:22:33:44:55")
            dev_flags       : Device flags as decimal number
            dev_flags_str   : Device flags as String (e.g. "UP RUNNING" or "DOWN")
        """

        # Open Bluetooth socket to execute ioctl's:
        try:
            s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
                              socket.BTPROTO_HCI)
        # Ticket 6: does not run on Windows with Kali subsystem
        except socket.error:
            log.warn(
                "Opening a local Bluetooth socket failed. Not running on native Linux?"
            )
            return []

        # Do ioctl(s,HCIGETDEVLIST,arg) to get the number of available devices:
        # arg is struct hci_dev_list_req (/usr/include/bluetooth/hci.h)
        arg = p32(16)  # dl->dev_num = HCI_MAX_DEV which is 16 (little endian)
        arg += b"\x00" * (8 * 16)
        devices_raw = fcntl.ioctl(s.fileno(), HCIGETDEVLIST, arg)
        num_devices = u16(devices_raw[:2])
        log.debug("Found %d HCI devices via ioctl(HCIGETDEVLIST)!" %
                  num_devices)

        device_list = []
        for dev_nr in range(num_devices):
            dev_struct_start = 4 + 8 * dev_nr
            dev_id = u16(devices_raw[dev_struct_start:dev_struct_start + 2])
            # arg is struct hci_dev_info (/usr/include/bluetooth/hci.h)
            arg = p16(dev_id)  # di->dev_id = <device_id>
            arg += b"\x00" * 20  # Enough space for name, bdaddr and flags
            dev_info_raw = bytearray(
                fcntl.ioctl(s.fileno(), HCIGETDEVINFO, arg))
            dev_name = dev_info_raw[2:10].replace(b"\x00", b"").decode()
            dev_bdaddr = ":".join(
                ["%02X" % x for x in dev_info_raw[10:16][::-1]])
            dev_flags = u32(dev_info_raw[16:20])
            if dev_flags == 0:
                dev_flags_str = "DOWN"
            else:
                dev_flags_str = " ".join([
                    name for flag, name in zip(
                        bin(dev_flags)[2:][::-1],
                        [
                            "UP",
                            "INIT",
                            "RUNNING",
                            "PSCAN",
                            "ISCAN",
                            "AUTH",
                            "ENCRYPT",
                            "INQUIRY",
                            "RAW",
                            "RESET",
                        ],
                    ) if flag == "1"
                ])

            device_list.append({
                "dev_id": dev_id,
                "dev_name": dev_name,
                "dev_bdaddr": dev_bdaddr,
                "dev_flags": dev_flags,
                "dev_flags_str": dev_flags_str,
            })
        s.close()
        return cast("List[Device]", device_list)