Example #1
0
    def _setupSockets(self):

        self.s_snoop = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s_snoop.settimeout(2)
        self.s_snoop.connect((self.host, self.port))

        log.debug("_setupSockets: Bound socket.")

        # same socket for input and output (this is different from adb here!)
        self.s_inject = Injector(self.s_snoop)

        # Write Header to btsnoop file (if file is still empty):
        if self.write_btsnooplog and self.btsnooplog_file.tell() == 0:
            # BT Snoop Header: btsnoop\x00, version: 1, data link type: 1002
            btsnoop_hdr = (b"btsnoop\x00" + p32(1, endian="big") +
                           p32(1002, endian="big"))
            with self.btsnooplog_file_lock:
                self.btsnooplog_file.write(btsnoop_hdr)
                self.btsnooplog_file.flush()

        return True
Example #2
0
 def recvPacket(self, record):
     hcipkt = record[0]
     if not issubclass(hcipkt.__class__, HCI_Event):
         return
     if hcipkt.event_code != 0xFF:
         return
     # TODO Android 8 introduced special handling for 0x57 HCI_VSE_SUBCODE_DEBUG_INFO_SUB_EVT,
     # stackdumps might no longer work
     if hcipkt.data[0] == "\x57":
         self.handleNexus6pStackDump(hcipkt)
     if hcipkt.data[0:4] == p32(0x039200F7):
         self.handleNexus5StackDump(hcipkt)
     # same header for S10 and evaluation board...
     if hcipkt.data[0:2] == p16(
             0x031B):  # generated by bthci_event_vs_initializeCoredumpHdr()
         self.handleEvalStackDump(hcipkt)
         self.handleS10StackDump(hcipkt)
Example #3
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)
Example #4
0
    def _setupSockets(self):
        """
        Linux already allows to open HCI sockets to Bluetooth devices,
        they include H4 information, we simply use it.
        """

        # Check if hci device is in state "UP". If not, set it to "UP" (requires root)
        device = [
            dev for dev in self.getHciDeviceList()
            if dev["dev_name"] == self.interface
        ]
        if len(device) == 0:
            log.warn("Device not found: " + self.interface)
            return False
        device = device[0]

        if device["dev_flags"] == 0:
            log.warn("Device %s is DOWN!" % self.interface)
            log.info("Trying to set %s to state 'UP' (requires root)" %
                     self.interface)
            if not self.bringHciDeviceUp(device["dev_id"]):
                log.warn("Failed to bring up %s." % self.interface)
                return False

        # TODO unload btusb module and check error messages here to give the user some output if sth fails

        # Connect to HCI socket
        self.s_snoop = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
                                     socket.BTPROTO_HCI)
        self.s_snoop.setsockopt(socket.SOL_HCI, socket.HCI_DATA_DIR, 1)
        self.s_snoop.setsockopt(socket.SOL_HCI, socket.HCI_TIME_STAMP, 1)
        """
        struct hci_filter {
            uint32_t type_mask;     -> 4
            uint32_t event_mask[2]; -> 8
            uint16_t opcode;        -> 2
        };
        """
        # TODO still seems to only forward incoming events?!
        self.s_snoop.setsockopt(
            socket.SOL_HCI,
            socket.HCI_FILTER,
            b"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00",
        )  # type mask, event mask, event mask, opcode

        interface_num = device["dev_id"]
        log.debug("Socket interface number: %s" % interface_num)
        self.s_snoop.bind((interface_num, ))
        self.s_snoop.settimeout(2)
        log.debug("_setupSockets: Bound socket.")

        # same socket for input and output (this is different from adb here!)
        self.s_inject = self.s_snoop

        # Write Header to btsnoop file (if file is still empty):
        if self.write_btsnooplog and self.btsnooplog_file.tell() == 0:
            # BT Snoop Header: btsnoop\x00, version: 1, data link type: 1002
            btsnoop_hdr = (b"btsnoop\x00" + p32(1, endian="big") +
                           p32(1002, endian="big"))
            with self.btsnooplog_file_lock:
                self.btsnooplog_file.write(btsnoop_hdr)
                self.btsnooplog_file.flush()

        return True