def list(self, pattern=""): ''' Display the list of module, filtered by the string provided as ``pattern``. :param pattern: filter :type pattern: str ''' displayDict = {} for module in self.modulesList: info = self.modulesList[module]().info() technology = (info["technology"][:1]).upper() + ( info["technology"][1:]).lower() if (pattern in info["description"] or pattern in info["name"] or pattern in info["technology"] or pattern in info["type"]): if not technology in displayDict: displayDict[technology] = [] displayDict[technology].append( [info["name"], info["type"], info["description"]]) for module in sorted(displayDict): if displayDict[module]: io.chart(["Name", "Type", "Description"], sorted(displayDict[module]), "{} Modules".format(module))
def pairing( self, active: ["active", "passive"] = "active", parameters: "!method:_autocompletePairingParameters" = "inputOutput=yesno|authentication=bonding|ltk=112233445566778899aabbccddeeff|rand=1122334455667788|ediv=12" ): self.receiver.removeCallbacks() self.initializeCallbacks() parameters = { param.split("=")[0]: param.split("=")[1] for param in parameters.split("|") } pairModule = utils.loadModule("ble_pair") pairModule["INTERFACE"] = self.args["INTERFACE"] pairModule["MODE"] = "slave" pairModule["ACTIVE"] = "yes" if active == "active" else "no" pairModule["KEYBOARD"] = "yes" if ( "inputOutput" in parameters and "keyboard" in parameters["inputOutput"]) else "no" pairModule["YESNO"] = "yes" if ("inputOutput" in parameters and "yesno" in parameters["inputOutput"]) else "no" pairModule["DISPLAY"] = "yes" if ( "inputOutput" in parameters and "display" in parameters["inputOutput"]) else "no" pairModule["CT2"] = "yes" if ( "authentication" in parameters and "ct2" in parameters["authentication"]) else "no" pairModule["MITM"] = "yes" if ( "authentication" in parameters and "mitm" in parameters["authentication"]) else "no" pairModule["BONDING"] = "yes" if ( "authentication" in parameters and "bonding" in parameters["authentication"]) else "no" pairModule["SECURE_CONNECTIONS"] = "yes" if ( "authentication" in parameters and "secureConnections" in parameters["authentication"]) else "no" pairModule["KEYPRESS"] = "yes" if ( "authentication" in parameters and "keypress" in parameters["authentication"]) else "no" pairModule["LTK"] = parameters["ltk"] if "ltk" in parameters else "" pairModule["EDIV"] = parameters["ediv"] if "ediv" in parameters else "" pairModule["RAND"] = parameters["rand"] if "rand" in parameters else "" pairModule["IRK"] = parameters["irk"] if "irk" in parameters else "" pairModule["ADDR"] = parameters["addr"] if "addr" in parameters else "" pairModule["ADDR_TYPE"] = parameters[ "addrType"] if "addrType" in parameters else "" pairModule["CSRK"] = parameters["csrk"] if "csrk" in parameters else "" pairModule["PIN"] = parameters["pin"] if "pin" in parameters else "" io.chart(["Name", "Value"], [[k, v] for k, v in pairModule.args.items()], "Input parameters") output = pairModule.execute() if output["success"]: if active == "active": io.success("Active pairing enabled !") else: io.success("Passive pairing enabled !") else: io.fail("An error occured during pairing !")
def displayDevices(self): displayMode = utils.listArg(self.args["DISPLAY"]) devices = [] for address,device in self.devices.items(): currentLine = [] adv_data=device["ADV_IND_data"]+" (ADV_IND)" if device["ADV_IND_data"]!="" else "" if device["ADV_IND_data"]!="" and device["SCAN_RSP_data"]!="": adv_data+="\n" adv_data+=device["SCAN_RSP_data"]+" (SCAN_RSP)" if device["SCAN_RSP_data"]!="" else "" if "address" in displayMode: currentLine.append(address) if "name" in displayMode: currentLine.append(device["name"]) if "company" in displayMode: currentLine.append(device["company"]) if "flags" in displayMode: currentLine.append(",".join(device["flags"])) if "data" in displayMode: currentLine.append(adv_data) devices.append(currentLine) headLine = [] if "address" in displayMode: headLine.append("BD Address") if "name" in displayMode: headLine.append("Name") if "company" in displayMode: headLine.append("Company") if "flags" in displayMode: headLine.append("Flags") if "data" in displayMode: headLine.append("Advertising data") io.chart(headLine, devices, "Devices found")
def run(self): self.emitter = self.getEmitter(interface=self.args["INTERFACE"]) if utils.booleanArg(self.args["SHOW_CAPABILITIES"]): self.displayCapabilities() if "rfstorm" in self.args["INTERFACE"]: interface = self.args["INTERFACE"] mode = self.emitter.getMode() index = str(self.emitter.getDeviceIndex()) io.chart(["Interface","Device Index","Mode"],[[interface,"#"+index,mode]]) return self.ok({"INTERFACE":interface, "INDEX":index, "MODE":mode }) elif ".pcap" in self.args["INTERFACE"]: interface = self.args["INTERFACE"] mode = self.emitter.getMode() io.chart(["Interface","Mode"],[[interface,mode]]) return self.ok({"INTERFACE":interface, "MODE":mode }) return self.nok()
def displayConnection(self,index=0): aa = "0x{:8x}".format(self.receivers[index].getAccessAddress()) crcInit = "0x{:6x}".format(self.receivers[index].getCrcInit()) channelMap = "0x{:10x}".format(self.receivers[index].getChannelMap()) hopInterval = int(self.receivers[index].getHopInterval()) hopIncrement = int(self.receivers[index].getHopIncrement()) io.chart(["Access Address", "CRCInit", "Channel Map", "Hop Interval", "Hop Increment"],[[aa,crcInit,channelMap,hopInterval,hopIncrement]],"Sniffed Connection")
def showCharacteristics(self,startHandle,endHandle,title="Characteristics"): ''' This method displays the GATT characteristics described as attributes included in the Database and provide a mechanism to only select the characteristics between two handles (it is mainly used in order to print the characteristics included in a Service). :param startHandle: first ATT handle :type startHandle: int :param endHandle: last ATT handle :type endHandle: int :param title: Title of the chart :type title: str ''' formattedCharacteristics = [] for i in range(startHandle,endHandle): if i < len(self.attributes): att = self.attributes[i] if att.type == UUID(name="Characteristic Declaration"): declarationHandle = "0x{:04x}".format(att.handle) characteristic = CharacteristicDeclaration(data=att.value[::-1]) uuid16 = ("0x{:04x}".format(characteristic.UUID.UUID16) if characteristic.UUID.UUID16 is not None else "" ) uuid128 = (characteristic.UUID.UUID128.hex() if characteristic.UUID.UUID128 is not None else "" ) name = (characteristic.UUID.name if characteristic.UUID.name is not None else "" ) valueHandle = "0x{:04x}".format(characteristic.valueHandle) value = self.attributes[characteristic.valueHandle].value value = (value.replace(b"\x00",b"").decode("ascii") if utils.isPrintable(value) else value.hex() ) permissions = ",".join(characteristic.permissionsFlag.permissions) startDescriptor = characteristic.valueHandle + 1 descriptors = "" while (startDescriptor < len(self.attributes) and self.attributes[startDescriptor] is not None and (self.attributes[startDescriptor].type != UUID(name="Characteristic Declaration") and self.attributes[startDescriptor].type != UUID(name="Primary Service") and self.attributes[startDescriptor].type != UUID(name="Secondary Service"))): descriptor = self.attributes[startDescriptor] namedesc = CharacteristicDescriptor(UUID=descriptor.type).UUID.name valuedesc = (descriptor.value.replace(b"\x00",b"").decode("ascii") if utils.isPrintable(descriptor.value) else descriptor.value.hex() ) startSymbol = "" if descriptors == "" else "\n" descriptors += startSymbol + namedesc +" : "+ valuedesc startDescriptor += 1 formattedCharacteristics.append([declarationHandle, valueHandle, uuid16, uuid128, name,permissions,value,descriptors]) io.chart(["Declaration Handle","Value Handle","UUID16","UUID128","Name","Permissions", "Value","Descriptors"] ,formattedCharacteristics, io.colorize(title, "yellow") )
def displayAccessPoints(self): devices = [] for ap in self.accessPoints: address = ap SSID = self.accessPoints[ap]["ssid"] channels = ",".join([str(c) for c in self.accessPoints[ap]["channels"]]) devices.append([address,SSID,channels]) io.chart(["MAC Address","SSID","Channel"],devices,"Access Point Found")
def tasks(self,pattern=""): ''' This method allows to display the existing background tasks. A string pattern can be provided as a filter. :param pattern: Filter :type pattern: str ''' io.chart(["PID","Name","State","Output"], self.taskManager.getTasksList(pattern),"Background Tasks")
def info(self): ''' This method displays informations about the loaded module, such as the name, technology used, etc. ''' for module in self.modules: if module["module"] is not None: infos = module["module"].info() content = [infos["name"],infos["technology"], infos["type"], infos["description"]] io.chart(["Name", "Technology", "Type","Description"], [content], module["name"])
def displayStations(self): devices = [] for sta in self.stations: if sta != "FF:FF:FF:FF:FF:FF": address = sta channels = ",".join([str(c) for c in self.stations[sta]["channels"]]) devices.append([address,channels]) if devices!=[]: io.chart(["MAC Address","Channel"],devices,"Stations Found")
def displayCapabilities(self): capabilitiesList = [] for capability in self.capabilities: capabilitiesList.append([ capability, (io.colorize("yes", "green") if self.emitter.hasCapabilities(capability) else io.colorize( "no", "red")) ]) io.chart(["Capability", "Available"], capabilitiesList)
def displayDevices(self): sys.stdout.write(" " * 100 + "\r") if self.changes != 0: devices = [] for k, v in self.devices.items(): devices.append([ str(k), ",".join(str(i) for i in v["channels"]), v["type"] ]) io.chart(["Address", "Channels", "Device type"], devices) self.changes = 0
def connections(self): counter = 1 connectionsList = [] for connection in self.emitter.getConnections(): connectionsList.append([str(counter),connection["address"], connection["handle"]]) counter += 1 if connectionsList == []: io.fail("No active connections !") else: io.chart(["Identifier", "Address", "Handle"],connectionsList,io.colorize("Active connections","yellow"))
def showargs(self): ''' This method displays a chart describing the available input parameters for the loaded module. ''' for module in self.modules: currentArgs = [] for argument in module["module"].args: argName = (module["name"]+"."+argument) if len(self.modules)>1 else argument argValue = module["module"].args[argument] currentArgs.append([argName, argValue]) io.chart(["Name","Value"],currentArgs,io.colorize(module["name"],"yellow"))
def displayDevices(self): devices = [] for address in self.devices: devices.append([ address, hex(self.devices[address]['classOfDevice']), self.devices[address]['rssi'], self.devices[address]['data'][:26].hex() + "[...]" ]) io.chart(["Address", "Class Of Device", "RSSI", "Data"], devices, "Devices found")
def info(self): ''' This method displays informations about the loaded module, such as the name, technology used, etc. ''' for module in self.modules: if "module" in module and module["module"] is not None: infos = module["module"].info() content = [infos["name"],infos["technology"], infos["type"], infos["description"]] io.chart(["Name", "Technology", "Type","Description"], [content], module["name"]) elif "shortcut" in module and module["shortcut"] is not None: name = module["name"].strip("0123456789") description = self.loadedShortcuts[name]["description"] modules = self.loadedShortcuts[name]["modules"] io.chart(["Name","Modules","Description"],[[name,modules,description]],module["name"]+" (shortcut)")
def printServices(self, services, title="Services"): formattedServices = [] for service in services: startHandle = "0x{:04x}".format(service["startHandle"]) endHandle = "0x{:04x}".format(service["endHandle"]) uuid16 = (hex(service["uuid"].UUID16) if service["uuid"].UUID16 is not None else "") uuid128 = (service["uuid"].UUID128.hex() if service["uuid"].UUID128 is not None else "") name = (service["uuid"].name if service["uuid"].name is not None else "") formattedServices.append( [startHandle, endHandle, uuid16, uuid128, name]) io.chart(["Start Handle", "End Handle", "UUID16", "UUID128", "Name"], formattedServices, io.colorize(title, "yellow"))
def displayDetails(self): ''' This method displays a chart indicating the session keys' diversifier, the initializations vectors and the session key. If some values have not been provided or calculated, it displays an error message. ''' if self.ready: io.chart(["Name", "Value"], [["Master SKD", self.masterSkd.hex()], ["Master IV", self.masterIv.hex()], ["Slave SKD", self.masterSkd.hex()], ["Slave IV", self.masterIv.hex()], ["SKD", self.skd.hex()], ["IV", self.iv.hex()], ["Session Key", self.sessionKey.hex()]], "Encryption information") else: io.fail("Missing informations, encryption disabled")
def run(self): self.emitter = self.getEmitter(interface=self.args["INTERFACE"]) if utils.booleanArg(self.args["SHOW_CAPABILITIES"]): self.displayCapabilities() interface = self.args["INTERFACE"] address = self.emitter.getAddress() mode = self.emitter.getMode() channel = self.emitter.getChannel() io.chart(["Interface", "MAC Address", "Mode", "Channel"], [[interface, address, mode, channel]]) return self.ok({ "INTERFACE": interface, "ADDRESS": address, "MODE": mode, "CHANNEL": channel })
def run(self): self.emitter = bt.BluetoothEmitter(interface=self.args["INTERFACE"]) interface = self.args["INTERFACE"] address = self.emitter.getAddress() localName = self.emitter.getLocalName() manufacturer = self.emitter.getManufacturer() changeableAddress = "yes" if self.emitter.isAddressChangeable() else "no" io.chart(["Interface","BD Address","Local Name","Manufacturer","Changeable Address"], [[interface, address,localName,manufacturer,changeableAddress]]) return self.ok({ "INTERFACE":interface, "ADDRESS":address, "LOCAL_NAME":localName, "MANUFACTURER":manufacturer, "CHANGEABLE_ADDRESS":changeableAddress })
def list(self,pattern=""): ''' Display the list of module, filtered by the string provided as ``pattern``. :param pattern: filter :type pattern: str ''' displayList = [] for module in self.modulesList: info = self.modulesList[module]().info() if ( pattern in info["description"] or pattern in info["name"] or pattern in info["technology"] or pattern in info["type"] ): displayList.append([info["name"], info["type"], info["description"]]) io.chart(["Name", "Type","Description"], displayList, "Modules")
def display(self, data): devices = self.devices if len(devices): deviceHdr = list(next(iter( devices.values())).keys()) if len(devices) else [] deviceContent = [ list(device.values()) for device in devices.values() ] io.chart(deviceHdr, deviceContent, "Devices found") connections = self.connections if len(connections): connHdr = list(next(iter( connections.values())).keys()) if len(connections) else [] connContent = [ list(connection.values()) for connection in connections.values() ] io.chart(connHdr, connContent, "Connections found")
def displayDevices(self): if utils.integerArg(self.args["START_CHANNEL"]) != utils.integerArg( self.args["END_CHANNEL"]): sys.stdout.write(" " * 100 + "\r") columnsNames = ["Pan ID", "Channel", "Association permitted", "Nodes"] networks = [] nodes = "" for panID, network in self.devices.items(): for node, role in network["nodes"].items(): nodes += zigbee.addressToString(node) + "(" + role + ")" + "\n" networks.append([ hex(panID), str(network["channel"]), "yes" if network["associationPermitted"] else ("unknown" if network["associationPermitted"] is None else "no"), nodes[:-1] ]) io.chart(columnsNames, networks)
def printAttributes(self, attributes): formattedAttributes = [] for attribute in attributes: aType = ble.UUID(data=attribute["type"]) if aType.name is not None: attributeType = aType.name elif aType.UUID16 is not None: attributeType = hex(aType.UUID16) else: attributeType = aType.UUID128.hex() attributeValue = attribute["value"].replace( b"\x00", b"").decode("ascii") if utils.isPrintable( attribute["value"]) else attribute["value"].hex() attributeHandle = "0x{:04x}".format(attribute["handle"]) formattedAttributes.append( [attributeHandle, attributeType, attributeValue]) io.chart(["Attribute Handle", "Attribute Type", "Attribute Value"], formattedAttributes, io.colorize("Attributes", "yellow"))
def shortcuts(self,pattern=""): ''' This method allows to list the different shortcuts available in the framework. A string pattern can be provided as a filter. :param pattern: Filter :type pattern: str ''' shortcuts = [] for shortcutName,shortcut in self.loadedShortcuts.items(): if (pattern == "" or pattern in shortcutName or pattern in shortcut["description"] or pattern in shortcut["modules"]): shortcuts.append([shortcutName,shortcut["modules"],shortcut["description"]]) if shortcuts != []: io.chart(["Name","Modules","Description"],shortcuts,"Shortcuts") else: io.fail("No shortcut found !")
def showServices(self): ''' This method displays the GATT services described as attributes included in the Database. ''' formattedServices = [] for att in self.attributes: if att is not None and (att.type == UUID(name="Primary Service") or att.type == UUID(name="Secondary Service")): startHandle = "0x{:04x}".format(att.handle) service = Service(data=att.value[::-1]) serviceName = service.UUID.name if service.UUID.name is not None else "" serviceUUID16 = "0x{:04x}".format(service.UUID.UUID16) if service.UUID.UUID16 is not None else "" serviceUUID128 = service.UUID.UUID128.hex() if service.UUID.UUID128 is not None else "" if len(formattedServices) > 0: formattedServices[-1][1] = "0x{:04x}".format(att.handle - 1) formattedServices.append([startHandle,"0x{:04x}".format(0xFFFF),serviceUUID16, serviceUUID128,serviceName]) io.chart(["Start Handle","End Handle", "UUID16", "UUID128", "Name"], formattedServices, io.colorize("Services", "yellow") ) return formattedServices
def showargs(self): ''' This method displays a chart describing the available input parameters for the loaded module. ''' for module in self.modules: currentArgs = [] if "shortcut" not in module: for argument in module["module"].args: argName = (module["name"]+"."+argument) if len(self.modules)>1 else argument argValue = module["module"].args[argument] currentArgs.append([argName, argValue]) io.chart(["Name","Value"],currentArgs,io.colorize(module["name"],"yellow")) else: for argument in module["mapping"]: argName = (module["name"]+"."+argument) if len(self.modules)>1 else argument if module["mapping"][argument]["value"] is not None: argValue = module["mapping"][argument]["value"] else: argValue = "<auto>" currentArgs.append([argName, argValue]) io.chart(["Name", "Value"], currentArgs,io.colorize(module["name"],"green"))
def run(self): self.emitter = self.getEmitter(interface=self.args["INTERFACE"]) if utils.booleanArg(self.args["SHOW_CAPABILITIES"]): self.displayCapabilities() if "irma" in self.args["INTERFACE"]: interface = self.args["INTERFACE"] index = str(self.emitter.getDeviceIndex()) port = self.emitter.getSerialPort() frequency = str(self.emitter.getFrequency()) io.chart(["Interface", "Device Index", "Serial Port", "Frequency"], [[interface, "#" + index, port, frequency + " kHz"]]) return self.ok({ "INTERFACE": interface, "INDEX": index, "PORT": port, "FREQUENCY": frequency }) return self.nok()
def show(self): ''' This method displays a chart to present the ATT level vision of the attributes included in the Database. ''' formattedAttributes = [] for att in self.attributes: if att is not None: aType = att.type if aType.name is not None: attributeType = aType.name elif aType.UUID16 is not None: attributeType = hex(aType.UUID16) else: attributeType = aType.UUID128.hex() attributeValue = att.value.replace(b"\x00",b"").decode("ascii") if utils.isPrintable(att.value) else att.value.hex() attributeHandle = "0x{:04x}".format(att.handle) formattedAttributes.append([attributeHandle, attributeType,attributeValue]) io.chart(["Attribute Handle", "Attribute Type", "Attribute Value"], formattedAttributes, io.colorize("Attributes","yellow") )
def printCharacteristics(self, characteristics, title="Characteristics"): formattedCharacteristics = [] for characteristic in characteristics: declarationHandle = "0x{:04x}".format( characteristic["declarationHandle"]) valueHandle = "0x{:04x}".format(characteristic["valueHandle"]) permissionsFlag = ",".join(characteristic["permissionsFlag"]) uuid16 = (hex(characteristic["uuid"].UUID16) if characteristic["uuid"].UUID16 is not None else "") uuid128 = (characteristic["uuid"].UUID128.hex() if characteristic["uuid"].UUID128 is not None else "") name = (characteristic["uuid"].name if characteristic["uuid"].name is not None else "") value = (characteristic["value"].replace(b"\x00", b"").decode("ascii") if utils.isPrintable(characteristic["value"]) else characteristic["value"].hex()) descriptors = "" if "descriptors" in characteristic: for desc in characteristic["descriptors"]: namedesc = ble.CharacteristicDescriptor( data=desc["type"]).UUID.name valuedesc = ( desc["value"].replace(b"\x00", b"").decode("ascii") if utils.isPrintable(desc["value"]) and len(desc["value"]) > 0 else desc["value"].hex()) endSymbol = "\n" if characteristic["descriptors"][ -1] != desc else "" descriptors += namedesc + " : " + valuedesc + endSymbol formattedCharacteristics.append([ declarationHandle, valueHandle, uuid16, uuid128, name, permissionsFlag, value, descriptors ]) io.chart([ "Declaration Handle", "Value Handle", "UUID16", "UUID128", "Name", "Permissions", "Value", "Descriptors" ], formattedCharacteristics, io.colorize(title, "yellow"))