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
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)
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)
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