Beispiel #1
0
    def get_ip_data(self, ip_address: str):
        """
        :param ip_address: the ip of which (packet-)data shall be returned
        :return: MSS, TTL and Window Size values of the given IP
        """
        # Set MSS (Maximum Segment Size) based on MSS distribution of IP address
        mss_dist = self.statistics.get_mss_distribution(ip_address)
        if len(mss_dist) > 0:
            mss_prob_dict = lea.Lea.fromValFreqsDict(mss_dist)
            mss_value = mss_prob_dict.random()
        else:
            mss_value = Util.handle_most_used_outputs(self.most_used_mss_value)

        # Set TTL based on TTL distribution of IP address
        ttl_dist = self.statistics.get_ttl_distribution(ip_address)
        if len(ttl_dist) > 0:
            ttl_prob_dict = lea.Lea.fromValFreqsDict(ttl_dist)
            ttl_value = ttl_prob_dict.random()
        else:
            ttl_value = Util.handle_most_used_outputs(self.most_used_ttl_value)

        # Set Window Size based on Window Size distribution of IP address
        win_dist = self.statistics.get_win_distribution(ip_address)
        if len(win_dist) > 0:
            win_prob_dict = lea.Lea.fromValFreqsDict(win_dist)
            win_value = win_prob_dict.random()
        else:
            win_value = Util.handle_most_used_outputs(self.most_used_win_size)

        return mss_value, ttl_value, win_value
Beispiel #2
0
    def init_params(self):
        """
        Initialize the parameters of this attack using the user supplied command line parameters.
        Use the provided statistics to calculate default parameters and to process user
        supplied queries.
        """
        # PARAMETERS: initialize with default values
        # (values are overwritten if user specifies them)
        self.add_param_value(atkParam.Parameter.INJECT_AFTER_PACKET, rnd.randint(0, self.statistics.get_packet_count()))
        # attacker configuration
        num_attackers = rnd.randint(1, 16)
        # The most used IP class in background traffic
        most_used_ip_class = Util.handle_most_used_outputs(self.statistics.get_most_used_ip_class())

        self.add_param_value(atkParam.Parameter.IP_SOURCE,
                             self.generate_random_ipv4_address(most_used_ip_class, num_attackers))
        self.add_param_value(atkParam.Parameter.MAC_SOURCE, self.generate_random_mac_address(num_attackers))
        self.default_port = int(inet.RandShort())
        self.add_param_value(atkParam.Parameter.PORT_SOURCE, self.default_port)
        self.add_param_value(atkParam.Parameter.PACKETS_PER_SECOND, 0)
        self.add_param_value(atkParam.Parameter.ATTACK_DURATION, rnd.randint(5, 30))

        # victim configuration
        random_ip_address = self.statistics.get_random_ip_address()
        self.add_param_value(atkParam.Parameter.IP_DESTINATION, random_ip_address)
        destination_mac = self.statistics.get_mac_address(random_ip_address)
        if isinstance(destination_mac, list) and len(destination_mac) == 0:
            destination_mac = self.generate_random_mac_address()
        self.add_param_value(atkParam.Parameter.MAC_DESTINATION, destination_mac)
        self.add_param_value(atkParam.Parameter.VICTIM_BUFFER, rnd.randint(1000, 10000))

        self.add_param_value(atkParam.Parameter.BANDWIDTH_MAX, 0)
        self.add_param_value(atkParam.Parameter.BANDWIDTH_MIN_LOCAL, 0)
        self.add_param_value(atkParam.Parameter.BANDWIDTH_MIN_PUBLIC, 0)
        self.add_param_value(atkParam.Parameter.LATENCY_MAX, 0)
Beispiel #3
0
    def init_params(self):
        """
        Initialize the parameters of this attack using the user supplied command line parameters.
        Use the provided statistics to calculate default parameters and to process user
        supplied queries.
        """

        # PARAMETERS: initialize with default values
        # (values are overwritten if user specifies them)
        most_used_ip_address = self.statistics.get_most_used_ip_address()

        # The most used IP class in background traffic
        most_used_ip_class = Util.handle_most_used_outputs(self.statistics.get_most_used_ip_class())
        num_attackers = rnd.randint(1, 16)
        source_ip = self.generate_random_ipv4_address(most_used_ip_class, num_attackers)

        self.add_param_value(atkParam.Parameter.IP_SOURCE, source_ip)
        self.add_param_value(atkParam.Parameter.MAC_SOURCE, self.generate_random_mac_address(num_attackers))

        random_ip_address = self.statistics.get_random_ip_address()
        # ip-dst should be valid and not equal to ip.src
        while not self.is_valid_ip_address(random_ip_address) or random_ip_address == source_ip:
            random_ip_address = self.statistics.get_random_ip_address()

        self.add_param_value(atkParam.Parameter.IP_DESTINATION, random_ip_address)
        destination_mac = self.statistics.get_mac_address(random_ip_address)
        if isinstance(destination_mac, list) and len(destination_mac) == 0:
            destination_mac = self.generate_random_mac_address()
        self.add_param_value(atkParam.Parameter.MAC_DESTINATION, destination_mac)
        self.add_param_value(atkParam.Parameter.PACKETS_PER_SECOND,
                             (self.statistics.get_pps_sent(most_used_ip_address) +
                              self.statistics.get_pps_received(most_used_ip_address)) / 2)
        self.add_param_value(atkParam.Parameter.INJECT_AFTER_PACKET, rnd.randint(0, self.statistics.get_packet_count()))
        self.add_param_value(atkParam.Parameter.ATTACK_DURATION, 30)
Beispiel #4
0
    def init_params(self):
        """
        Initialize the parameters of this attack using the user supplied command line parameters.
        Use the provided statistics to calculate default parameters and to process user
        supplied queries.

        """
        # PARAMETERS: initialize with default values
        # (values are overwritten if user specifies them)
        most_used_ip_address = self.statistics.get_most_used_ip_address()

        # The most used IP class in background traffic
        most_used_ip_class = Util.handle_most_used_outputs(
            self.statistics.get_most_used_ip_class())
        attacker_ip = self.generate_random_ipv4_address(most_used_ip_class)
        self.add_param_value(atkParam.Parameter.IP_DESTINATION, attacker_ip)
        self.add_param_value(atkParam.Parameter.MAC_DESTINATION,
                             self.generate_random_mac_address())

        random_ip_address = self.statistics.get_random_ip_address()
        # victim should be valid and not equal to attacker
        while not self.is_valid_ip_address(
                random_ip_address) or random_ip_address == attacker_ip:
            random_ip_address = self.statistics.get_random_ip_address()

        self.add_param_value(atkParam.Parameter.IP_SOURCE, random_ip_address)
        victim_mac = self.statistics.get_mac_address(random_ip_address)
        if isinstance(victim_mac, list) and len(victim_mac) == 0:
            victim_mac = self.generate_random_mac_address()
        self.add_param_value(atkParam.Parameter.MAC_SOURCE, victim_mac)
        self.add_param_value(
            atkParam.Parameter.PACKETS_PER_SECOND,
            (self.statistics.get_pps_sent(most_used_ip_address) +
             self.statistics.get_pps_received(most_used_ip_address)) / 2)
        self.add_param_value(
            atkParam.Parameter.INJECT_AFTER_PACKET,
            rnd.randint(0, self.statistics.get_packet_count()))
        self.add_param_value(atkParam.Parameter.IP_SOURCE_RANDOMIZE, 'False')
        self.add_param_value(atkParam.Parameter.CUSTOM_PAYLOAD, '')
        self.add_param_value(atkParam.Parameter.CUSTOM_PAYLOAD_FILE, '')
Beispiel #5
0
    def generate_attack_packets(self):
        """
        Creates the attack packets.
        """
        buffer_size = 1000

        # Determine source IP and MAC address
        num_attackers = self.get_param_value(
            atkParam.Parameter.NUMBER_ATTACKERS)
        if (num_attackers is not None) and (num_attackers is not 0):
            # user supplied atkParam.Parameter.NUMBER_ATTACKERS
            # The most used IP class in background traffic
            most_used_ip_class = Util.handle_most_used_outputs(
                self.statistics.get_most_used_ip_class())
            # Create random attackers based on user input atkParam.Parameter.NUMBER_ATTACKERS
            ip_source_list = self.generate_random_ipv4_address(
                most_used_ip_class, num_attackers)
            mac_source_list = self.generate_random_mac_address(num_attackers)
        else:  # user did not supply atkParam.Parameter.NUMBER_ATTACKS
            # use default values for IP_SOURCE/MAC_SOURCE or overwritten values
            # if user supplied any values for those params
            ip_source_list = self.get_param_value(atkParam.Parameter.IP_SOURCE)
            mac_source_list = self.get_param_value(
                atkParam.Parameter.MAC_SOURCE)

        # Make sure IPs and MACs are lists
        if not isinstance(ip_source_list, list):
            ip_source_list = [ip_source_list]

        if not isinstance(mac_source_list, list):
            mac_source_list = [mac_source_list]

        # Generate MACs for each IP that has no corresponding MAC yet
        if (num_attackers is None) or (num_attackers is 0):
            if len(ip_source_list) > len(mac_source_list):
                mac_source_list.extend(
                    self.generate_random_mac_address(
                        len(ip_source_list) - len(mac_source_list)))
            num_attackers = min(len(ip_source_list), len(mac_source_list))

        # Initialize parameters
        self.packets = col.deque(maxlen=buffer_size)

        port_source_list = self.get_param_value(atkParam.Parameter.PORT_SOURCE)
        if not isinstance(port_source_list, list):
            port_source_list = [port_source_list]
        mac_destination = self.get_param_value(
            atkParam.Parameter.MAC_DESTINATION)
        ip_destination = self.get_param_value(
            atkParam.Parameter.IP_DESTINATION)

        most_used_ip_address = self.statistics.get_most_used_ip_address()
        pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND)
        if pps == 0:
            result = self.statistics.process_db_query(
                "SELECT MAX(maxPktRate) FROM ip_statistics WHERE ipAddress='" +
                ip_destination + "';")
            if result is not None and not 0:
                pps = num_attackers * result
            else:
                result = self.statistics.process_db_query(
                    "SELECT MAX(maxPktRate) FROM ip_statistics WHERE ipAddress='"
                    + most_used_ip_address + "';")
                pps = num_attackers * result

        # Calculate complement packet rates of the background traffic for each interval
        attacker_pps = pps / num_attackers
        complement_interval_attacker_pps = self.statistics.calculate_complement_packet_rates(
            attacker_pps)

        # Check ip.src == ip.dst
        self.ip_src_dst_equal_check(ip_source_list, ip_destination)

        port_destination = self.get_param_value(
            atkParam.Parameter.PORT_DESTINATION)
        if not port_destination:  # user did not define port_dest
            port_destination = self.statistics.process_db_query(
                "SELECT portNumber FROM ip_ports WHERE portDirection='in' AND ipAddress='"
                + ip_destination +
                "' AND portCount==(SELECT MAX(portCount) FROM ip_ports WHERE portDirection='in' AND ipAddress='"
                + ip_destination + "');")
        if not port_destination:  # no port was retrieved
            port_destination = self.statistics.process_db_query(
                "SELECT portNumber FROM (SELECT portNumber, SUM(portCount) as occ FROM ip_ports WHERE "
                "portDirection='in' GROUP BY portNumber ORDER BY occ DESC) WHERE occ=(SELECT SUM(portCount) "
                "FROM ip_ports WHERE portDirection='in' GROUP BY portNumber ORDER BY SUM(portCount) DESC LIMIT 1);"
            )
        if not port_destination:
            port_destination = max(1, int(inet.RandShort()))

        port_destination = Util.handle_most_used_outputs(port_destination)

        self.path_attack_pcap = None

        min_delay, max_delay = self.get_reply_delay(ip_destination)
        victim_buffer = self.get_param_value(atkParam.Parameter.VICTIM_BUFFER)

        attack_duration = self.get_param_value(
            atkParam.Parameter.ATTACK_DURATION)
        pkts_num = int(pps * attack_duration)

        source_win_sizes = self.statistics.get_rnd_win_size(pkts_num)

        destination_win_dist = self.statistics.get_win_distribution(
            ip_destination)
        if len(destination_win_dist) > 0:
            destination_win_prob_dict = lea.Lea.fromValFreqsDict(
                destination_win_dist)
            destination_win_value = destination_win_prob_dict.random()
        else:
            destination_win_value = self.statistics.get_most_used_win_size()

        destination_win_value = Util.handle_most_used_outputs(
            destination_win_value)

        # MSS that was used by IP destination in background traffic
        mss_dst = self.statistics.get_most_used_mss(ip_destination)
        if mss_dst is None:
            mss_dst = self.statistics.get_most_used_mss_value()

        mss_dst = Util.handle_most_used_outputs(mss_dst)

        # Stores triples of (timestamp, source_id, destination_id) for each timestamp.
        # Victim has id=0. Attacker tuple does not need to specify the destination because it's always the victim.
        timestamps_tuples = []
        # For each attacker(id), stores the current source-ports of SYN-packets
        # which still have to be acknowledged by the victim, as a "FIFO" for each attacker
        previous_attacker_port = []
        replies_count = 0
        self.total_pkt_num = 0
        # For each attacker, generate his own packets, then merge all packets
        for attacker in range(num_attackers):
            # Initialize empty port "FIFO" for current attacker
            previous_attacker_port.append([])
            # Calculate timestamp of first SYN-packet of attacker
            timestamp_next_pkt = self.get_param_value(
                atkParam.Parameter.INJECT_AT_TIMESTAMP)
            attack_ends_time = timestamp_next_pkt + attack_duration
            timestamp_next_pkt = rnd.uniform(
                timestamp_next_pkt,
                Util.update_timestamp(timestamp_next_pkt, attacker_pps))
            attacker_pkts_num = int(pkts_num / num_attackers) + rnd.randint(
                0, 100)
            timestamp_prv_reply = 0
            for pkt_num in range(attacker_pkts_num):
                # Stop the attack when it exceeds the duration
                if timestamp_next_pkt > attack_ends_time:
                    break

                # Add timestamp of attacker SYN-packet. Attacker tuples do not need to specify destination
                timestamps_tuples.append((timestamp_next_pkt, attacker + 1))

                # Calculate timestamp of victim ACK-packet
                timestamp_reply = Util.update_timestamp(
                    timestamp_next_pkt, attacker_pps, min_delay)
                while timestamp_reply <= timestamp_prv_reply:
                    timestamp_reply = Util.update_timestamp(
                        timestamp_prv_reply, attacker_pps, min_delay)
                timestamp_prv_reply = timestamp_reply

                # Add timestamp of victim ACK-packet(victim always has id=0)
                timestamps_tuples.append((timestamp_reply, 0, attacker + 1))

                # Calculate timestamp for next attacker SYN-packet
                attacker_pps = max(
                    Util.get_interval_pps(complement_interval_attacker_pps,
                                          timestamp_next_pkt),
                    (pps / num_attackers) / 2)
                timestamp_next_pkt = Util.update_timestamp(
                    timestamp_next_pkt, attacker_pps)

        # Sort timestamp-triples according to their timestamps in ascending order
        timestamps_tuples.sort(key=lambda tmstmp: tmstmp[0])
        self.attack_start_utime = timestamps_tuples[0][0]

        # For each triple, generate packet
        for timestamp in timestamps_tuples:

            # If current current triple is an attacker
            if timestamp[1] != 0:

                attacker_id = timestamp[1] - 1
                # Build request package
                # Select one IP address and its corresponding MAC address
                ip_source = ip_source_list[attacker_id]
                mac_source = mac_source_list[attacker_id]

                # Determine source port
                (port_source,
                 ttl_value) = Util.get_attacker_config(ip_source_list,
                                                       ip_source)

                # If source ports were specified by the user, get random port from specified ports
                if port_source_list[0] != self.default_port:
                    port_source = rnd.choice(port_source_list)

                # Push port of current attacker SYN-packet into port "FIFO" of the current attacker
                # only if victim can still respond, otherwise, memory is wasted
                if replies_count <= victim_buffer:
                    previous_attacker_port[attacker_id].insert(0, port_source)

                request_ether = inet.Ether(dst=mac_destination, src=mac_source)
                request_ip = inet.IP(src=ip_source,
                                     dst=ip_destination,
                                     ttl=ttl_value)
                # Random win size for each packet
                source_win_size = rnd.choice(source_win_sizes)
                request_tcp = inet.TCP(sport=port_source,
                                       dport=port_destination,
                                       flags='S',
                                       ack=0,
                                       window=source_win_size)

                request = (request_ether / request_ip / request_tcp)
                request.time = timestamp[0]
                # Append request
                self.packets.append(request)
                self.total_pkt_num += 1

            # If current triple is the victim
            else:

                # Build reply package
                if replies_count <= victim_buffer:
                    attacker_id = timestamp[2] - 1

                    reply_ether = inet.Ether(src=mac_destination,
                                             dst=mac_source_list[attacker_id])
                    reply_ip = inet.IP(src=ip_destination,
                                       dst=ip_source_list[attacker_id],
                                       flags='DF')
                    # Pop port from attacker's port "FIFO" into destination port
                    reply_tcp = inet.TCP(
                        sport=port_destination,
                        dport=previous_attacker_port[attacker_id].pop(),
                        seq=0,
                        ack=1,
                        flags='SA',
                        window=destination_win_value,
                        options=[('MSS', mss_dst)])
                    reply = (reply_ether / reply_ip / reply_tcp)

                    reply.time = timestamp[0]
                    self.packets.append(reply)
                    replies_count += 1
                    self.total_pkt_num += 1

            # every 1000 packets write them to the pcap file (append)
            if (self.total_pkt_num > 0) and (self.total_pkt_num % buffer_size
                                             == 0) and (len(self.packets) > 0):
                self.last_packet = self.packets[-1]
                self.attack_end_utime = self.last_packet.time
                self.packets = sorted(self.packets, key=lambda pkt: pkt.time)
                self.path_attack_pcap = self.write_attack_pcap(
                    self.packets, True, self.path_attack_pcap)
                self.packets = []
Beispiel #6
0
    def generate_attack_packets(self):
        """
        Creates the attack packets.
        """
        mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE)
        mac_destination = self.get_param_value(
            atkParam.Parameter.MAC_DESTINATION)

        # Determine ports
        dest_ports = self.get_param_value(atkParam.Parameter.PORT_DESTINATION)
        if self.get_param_value(atkParam.Parameter.PORT_DEST_ORDER_DESC):
            dest_ports.reverse()
        elif self.get_param_value(atkParam.Parameter.PORT_DEST_SHUFFLE):
            rnd.shuffle(dest_ports)
        if self.get_param_value(atkParam.Parameter.PORT_SOURCE_RANDOMIZE):
            # FIXME: why is sport never used?
            sport = rnd.randint(1, 65535)
        else:
            sport = self.get_param_value(atkParam.Parameter.PORT_SOURCE)

        # Timestamp
        timestamp_next_pkt = self.get_param_value(
            atkParam.Parameter.INJECT_AT_TIMESTAMP)
        # store start time of attack
        self.attack_start_utime = timestamp_next_pkt

        # Initialize parameters
        self.packets = []
        ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE)
        if isinstance(ip_source, list):
            ip_source = ip_source[0]
        ip_destination = self.get_param_value(
            atkParam.Parameter.IP_DESTINATION)
        if not isinstance(ip_destination, list):
            ip_destination = [ip_destination]

        # Check ip.src == ip.dst
        self.ip_src_dst_catch_equal(ip_source, ip_destination)

        for ip in ip_destination:
            # Select open ports
            ports_open = self.get_param_value(atkParam.Parameter.PORT_OPEN)
            if ports_open == 1:  # user did not specify open ports
                # the ports that were already used by ip.dst (direction in) in the background traffic are open ports
                ports_used_by_ip_dst = self.statistics.process_db_query(
                    "SELECT portNumber FROM ip_ports WHERE portDirection='in' AND ipAddress='"
                    + ip + "'")
                if ports_used_by_ip_dst:
                    ports_open = ports_used_by_ip_dst
                else:  # if no ports were retrieved from database
                    # Take open ports from nmap-service file
                    # ports_temp = self.get_ports_from_nmap_service_dst(100)
                    # ports_open = ports_temp[0:rnd.randint(1,10)]
                    # OR take open ports from the most used ports in traffic statistics
                    ports_open = self.statistics.process_db_query(
                        "SELECT portNumber FROM ip_ports GROUP BY portNumber ORDER BY SUM(portCount) DESC LIMIT "
                        + str(rnd.randint(1, 10)))
            # in case of one open port, convert ports_open to array
            if not isinstance(ports_open, list):
                ports_open = [ports_open]

            # Set MSS (Maximum Segment Size) based on MSS distribution of IP address
            source_mss_dist = self.statistics.get_mss_distribution(ip_source)
            if len(source_mss_dist) > 0:
                source_mss_prob_dict = lea.Lea.fromValFreqsDict(
                    source_mss_dist)
                source_mss_value = source_mss_prob_dict.random()
            else:
                source_mss_value = Util.handle_most_used_outputs(
                    self.statistics.get_most_used_mss_value())
            destination_mss_dist = self.statistics.get_mss_distribution(ip)
            if len(destination_mss_dist) > 0:
                destination_mss_prob_dict = lea.Lea.fromValFreqsDict(
                    destination_mss_dist)
                destination_mss_value = destination_mss_prob_dict.random()
            else:
                destination_mss_value = Util.handle_most_used_outputs(
                    self.statistics.get_most_used_mss_value())

            # Set TTL based on TTL distribution of IP address
            source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
            if len(source_ttl_dist) > 0:
                source_ttl_prob_dict = lea.Lea.fromValFreqsDict(
                    source_ttl_dist)
                source_ttl_value = source_ttl_prob_dict.random()
            else:
                source_ttl_value = Util.handle_most_used_outputs(
                    self.statistics.get_most_used_ttl_value())
            destination_ttl_dist = self.statistics.get_ttl_distribution(ip)
            if len(destination_ttl_dist) > 0:
                destination_ttl_prob_dict = lea.Lea.fromValFreqsDict(
                    destination_ttl_dist)
                destination_ttl_value = destination_ttl_prob_dict.random()
            else:
                destination_ttl_value = Util.handle_most_used_outputs(
                    self.statistics.get_most_used_ttl_value())

            # Set Window Size based on Window Size distribution of IP address
            source_win_dist = self.statistics.get_win_distribution(ip_source)
            if len(source_win_dist) > 0:
                source_win_prob_dict = lea.Lea.fromValFreqsDict(
                    source_win_dist)
                source_win_value = source_win_prob_dict.random()
            else:
                source_win_value = Util.handle_most_used_outputs(
                    self.statistics.get_most_used_win_size())
            destination_win_dist = self.statistics.get_win_distribution(ip)
            if len(destination_win_dist) > 0:
                destination_win_prob_dict = lea.Lea.fromValFreqsDict(
                    destination_win_dist)
                destination_win_value = destination_win_prob_dict.random()
            else:
                destination_win_value = Util.handle_most_used_outputs(
                    self.statistics.get_most_used_win_size())

            min_delay, max_delay = self.get_reply_latency(ip_source, ip)

            for dport in dest_ports:
                # Parameters changing each iteration
                if self.get_param_value(
                        atkParam.Parameter.IP_SOURCE_RANDOMIZE) and isinstance(
                            ip_source, list):
                    ip_source = rnd.choice(ip_source)

                # 1) Build request package
                request_ether = inet.Ether(src=mac_source, dst=mac_destination)
                request_ip = inet.IP(src=ip_source,
                                     dst=ip,
                                     ttl=source_ttl_value)

                # Random src port for each packet
                sport = rnd.randint(1, 65535)

                request_tcp = inet.TCP(sport=sport,
                                       dport=dport,
                                       window=source_win_value,
                                       flags='S',
                                       options=[('MSS', source_mss_value)])

                request = (request_ether / request_ip / request_tcp)

                request.time = timestamp_next_pkt
                # Append request
                self.packets.append(request)

                # 2) Build reply (for open ports) package
                if dport in ports_open:  # destination port is OPEN
                    reply_ether = inet.Ether(src=mac_destination,
                                             dst=mac_source)
                    reply_ip = inet.IP(src=ip,
                                       dst=ip_source,
                                       ttl=destination_ttl_value,
                                       flags='DF')
                    reply_tcp = inet.TCP(sport=dport,
                                         dport=sport,
                                         seq=0,
                                         ack=1,
                                         flags='SA',
                                         window=destination_win_value,
                                         options=[('MSS',
                                                   destination_mss_value)])
                    reply = (reply_ether / reply_ip / reply_tcp)

                    timestamp_reply = self.timestamp_controller.next_timestamp(
                        latency=min_delay)

                    reply.time = timestamp_reply
                    self.packets.append(reply)

                    # requester confirms
                    confirm_ether = request_ether
                    confirm_ip = request_ip
                    confirm_tcp = inet.TCP(sport=sport,
                                           dport=dport,
                                           seq=1,
                                           window=0,
                                           flags='R')
                    confirm = (confirm_ether / confirm_ip / confirm_tcp)
                    self.timestamp_controller.set_timestamp(timestamp_reply)
                    timestamp_confirm = self.timestamp_controller.next_timestamp(
                        latency=min_delay)
                    confirm.time = timestamp_confirm
                    self.packets.append(confirm)

                    # else: destination port is NOT OPEN -> no reply is sent by target

                self.timestamp_controller.set_timestamp(timestamp_next_pkt)
                timestamp_next_pkt = self.timestamp_controller.next_timestamp()
Beispiel #7
0
    def generate_attack_packets(self):
        """
        Creates the attack packets.
        """
        buffer_size = 1000

        # Determine source IP and MAC address
        num_attackers = self.get_param_value(atkParam.Parameter.NUMBER_ATTACKERS)
        if (num_attackers is not None) and (num_attackers is not 0):
            # user supplied atkParam.Parameter.NUMBER_ATTACKERS
            # The most used IP class in background traffic
            most_used_ip_class = Util.handle_most_used_outputs(self.statistics.get_most_used_ip_class())
            # Create random attackers based on user input atkParam.Parameter.NUMBER_ATTACKERS
            ip_source_list = self.generate_random_ipv4_address(most_used_ip_class, num_attackers)
            mac_source_list = self.generate_random_mac_address(num_attackers)
        else:  # user did not supply atkParam.Parameter.NUMBER_ATTACKS
            # use default values for IP_SOURCE/MAC_SOURCE or overwritten values
            # if user supplied any values for those params
            ip_source_list = self.get_param_value(atkParam.Parameter.IP_SOURCE)
            mac_source_list = self.get_param_value(atkParam.Parameter.MAC_SOURCE)

        # Make sure IPs and MACs are lists
        if not isinstance(ip_source_list, list):
            ip_source_list = [ip_source_list]

        if not isinstance(mac_source_list, list):
            mac_source_list = [mac_source_list]

        # Generate MACs for each IP that has no corresponding MAC yet
        if (num_attackers is None) or (num_attackers is 0):
            if len(ip_source_list) > len(mac_source_list):
                mac_source_list.extend(self.generate_random_mac_address(len(ip_source_list)-len(mac_source_list)))
            num_attackers = min(len(ip_source_list), len(mac_source_list))

        # Initialize parameters
        self.packets = col.deque(maxlen=buffer_size)

        port_source_list = self.get_param_value(atkParam.Parameter.PORT_SOURCE)
        if not isinstance(port_source_list, list):
            port_source_list = [port_source_list]
        mac_destination = self.get_param_value(atkParam.Parameter.MAC_DESTINATION)
        ip_destination = self.get_param_value(atkParam.Parameter.IP_DESTINATION)

        most_used_ip_address = self.statistics.get_most_used_ip_address()
        pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND)
        if pps == 0:
            result = self.statistics.process_db_query(
                "SELECT MAX(maxPktRate) FROM ip_statistics WHERE ipAddress='" + ip_destination + "';")
            if result is not None and not 0:
                pps = num_attackers * result
            else:
                result = self.statistics.process_db_query(
                    "SELECT MAX(maxPktRate) FROM ip_statistics WHERE ipAddress='" + most_used_ip_address + "';")
                pps = num_attackers * result

        # Calculate complement packet rates of the background traffic for each interval
        attacker_pps = pps / num_attackers
        #complement_interval_attacker_pps = self.statistics.calculate_complement_packet_rates(attacker_pps)

        # Check ip.src == ip.dst
        self.ip_src_dst_catch_equal(ip_source_list, ip_destination)

        port_destination = self.get_param_value(atkParam.Parameter.PORT_DESTINATION)
        if not port_destination:  # user did not define port_dest
            port_destination = self.statistics.process_db_query(
                "SELECT portNumber FROM ip_ports WHERE portDirection='in' AND ipAddress='" + ip_destination +
                "' AND portCount==(SELECT MAX(portCount) FROM ip_ports WHERE portDirection='in' AND ipAddress='" +
                ip_destination + "');")
        if not port_destination:  # no port was retrieved
            port_destination = self.statistics.process_db_query(
                "SELECT portNumber FROM (SELECT portNumber, SUM(portCount) as occ FROM ip_ports WHERE "
                "portDirection='in' GROUP BY portNumber ORDER BY occ DESC) WHERE occ=(SELECT SUM(portCount) "
                "FROM ip_ports WHERE portDirection='in' GROUP BY portNumber ORDER BY SUM(portCount) DESC LIMIT 1);")
        if not port_destination:
            port_destination = max(1, int(inet.RandShort()))

        port_destination = Util.handle_most_used_outputs(port_destination)

        self.path_attack_pcap = None

        victim_buffer = self.get_param_value(atkParam.Parameter.VICTIM_BUFFER)

        attack_duration = self.get_param_value(atkParam.Parameter.ATTACK_DURATION)
        pkts_num = int(pps * attack_duration)

        source_win_sizes = self.statistics.get_rnd_win_size(pkts_num)

        destination_win_dist = self.statistics.get_win_distribution(ip_destination)
        if len(destination_win_dist) > 0:
            destination_win_prob_dict = lea.Lea.fromValFreqsDict(destination_win_dist)
            destination_win_value = destination_win_prob_dict.random()
        else:
            destination_win_value = self.statistics.get_most_used_win_size()

        destination_win_value = Util.handle_most_used_outputs(destination_win_value)

        # MSS that was used by IP destination in background traffic
        mss_dst = self.statistics.get_most_used_mss(ip_destination)
        if mss_dst is None:
            mss_dst = self.statistics.get_most_used_mss_value()

        mss_dst = Util.handle_most_used_outputs(mss_dst)

        # get user defined bandwidth
        bandwidth_max = self.get_param_value(atkParam.Parameter.BANDWIDTH_MAX)
        bandwidth_min_local = self.get_param_value(atkParam.Parameter.BANDWIDTH_MIN_LOCAL)
        bandwidth_min_public = self.get_param_value(atkParam.Parameter.BANDWIDTH_MIN_PUBLIC)

        # check user defined latency
        latency_limit = None
        latency_max = self.get_param_value(atkParam.Parameter.LATENCY_MAX)
        if latency_max != 0:
            latency_limit = latency_max

        # Stores triples of (timestamp, source_id, destination_id) for each timestamp.
        # Victim has id=0. Attacker tuple does not need to specify the destination because it's always the victim.
        timestamps_tuples = []
        # For each attacker(id), stores the current source-ports of SYN-packets
        # which still have to be acknowledged by the victim, as a "FIFO" for each attacker
        previous_attacker_port = []
        replies_count = 0
        self.total_pkt_num = 0
        already_used_pkts = 0
        sum_diff = 0

        self.attack_start_utime = self.get_param_value(atkParam.Parameter.INJECT_AT_TIMESTAMP)
        self.timestamp_controller.set_pps(attacker_pps)
        attack_ends_time = self.timestamp_controller.get_timestamp() + attack_duration

        # For each attacker, generate his own packets, then merge all packets
        for attacker in range(num_attackers):
            # set latency limit to either the minimal latency occurring in the pcap, the default or the user specified limit
            # get minimal and maximal latency found in the pcap
            if not latency_limit:
                min_latency, max_latency = self.get_reply_latency(ip_source_list[attacker], ip_destination)
                latency_limit = min_latency

            # Initialize empty port "FIFO" for current attacker
            previous_attacker_port.append([])
            # Calculate timestamp of first SYN-packet of attacker
            timestamp_next_pkt = self.timestamp_controller.reset_timestamp()
            if attacker != 0:
                timestamp_next_pkt = rnd.uniform(timestamp_next_pkt,
                                                 self.timestamp_controller.next_timestamp(latency=latency_limit))
            # calculate each attackers packet count without exceeding the total number of attackers
            attacker_pkts_num = 0
            if already_used_pkts < pkts_num:
                random_offset = rnd.randint(0, int(pkts_num / num_attackers / 2))
                if attacker == num_attackers-1:
                    random_offset = 0
                attacker_pkts_num = int((pkts_num - already_used_pkts) / (num_attackers - attacker)) + random_offset
                already_used_pkts += attacker_pkts_num
                # each attacker gets a different pps according to his pkt count offset
                ratio = float(attacker_pkts_num) / float(pkts_num)
                attacker_pps = pps * ratio
                self.timestamp_controller.set_pps(attacker_pps)

            for pkt_num in range(attacker_pkts_num):
                # Count attack packets that exceed the attack duration
                if timestamp_next_pkt > attack_ends_time:
                    diff = timestamp_next_pkt-attack_ends_time
                    sum_diff += diff
                    self.exceeding_packets += 1

                # Add timestamp of attacker SYN-packet. Attacker tuples do not need to specify destination
                timestamps_tuples.append((timestamp_next_pkt, attacker+1))

                # Calculate timestamp of victim ACK-packet
                timestamp_reply = self.timestamp_controller.next_timestamp(latency=latency_limit)

                # Add timestamp of victim ACK-packet(victim always has id=0)
                timestamps_tuples.append((timestamp_reply, 0, attacker+1))

                # Calculate timestamp for next attacker SYN-packet
                self.timestamp_controller.set_timestamp(timestamp_next_pkt)
                timestamp_next_pkt = self.timestamp_controller.next_timestamp()

        # Sort timestamp-triples according to their timestamps in ascending order
        timestamps_tuples.sort(key=lambda tmstmp: tmstmp[0])
        self.attack_start_utime = timestamps_tuples[0][0]

        sent_bytes = 0
        previous_interval = 0
        interval_count = 0
        full_interval = None
        reply = None

        # For each triple, generate packet
        for timestamp in timestamps_tuples:
            # tuple layout: [timestamp, attacker_id]

            # If current current triple is an attacker
            if timestamp[1] != 0:

                attacker_id = timestamp[1]-1
                # Build request package
                # Select one IP address and its corresponding MAC address
                ip_source = ip_source_list[attacker_id]
                mac_source = mac_source_list[attacker_id]

                # Determine source port
                (port_source, ttl_value) = Util.get_attacker_config(ip_source_list, ip_source)

                # If source ports were specified by the user, get random port from specified ports
                if port_source_list[0] != self.default_port:
                    port_source = rnd.choice(port_source_list)

                # Push port of current attacker SYN-packet into port "FIFO" of the current attacker
                # only if victim can still respond, otherwise, memory is wasted
                if replies_count <= victim_buffer:
                    previous_attacker_port[attacker_id].insert(0, port_source)

                request_ether = inet.Ether(dst=mac_destination, src=mac_source)
                request_ip = inet.IP(src=ip_source, dst=ip_destination, ttl=ttl_value)
                # Random win size for each packet
                source_win_size = rnd.choice(source_win_sizes)
                request_tcp = inet.TCP(sport=port_source, dport=port_destination, flags='S', ack=0,
                                       window=source_win_size)

                request = (request_ether / request_ip / request_tcp)
                request.time = timestamp[0]

                pkt = request

            # If current triple is the victim
            else:

                # Build reply package
                if replies_count <= victim_buffer:
                    attacker_id = timestamp[2]-1
                    ip_source = ip_source_list[attacker_id]

                    reply_ether = inet.Ether(src=mac_destination, dst=mac_source_list[attacker_id])
                    reply_ip = inet.IP(src=ip_destination, dst=ip_source, flags='DF')
                    # Pop port from attacker's port "FIFO" into destination port
                    reply_tcp = inet.TCP(sport=port_destination, dport=previous_attacker_port[attacker_id].pop(), seq=0,
                                         ack=1, flags='SA', window=destination_win_value, options=[('MSS', mss_dst)])
                    reply = (reply_ether / reply_ip / reply_tcp)

                    reply.time = timestamp[0]

                    pkt = reply

            bytes = len(pkt)

            remaining_bytes, current_interval = self.get_remaining_bandwidth(pkt.time, ip_source, ip_destination,
                                                                             bandwidth_max, bandwidth_min_local,
                                                                             bandwidth_min_public)
            if previous_interval != current_interval:
                sent_bytes = 0
                interval_count += 1

            previous_interval = current_interval

            if current_interval != full_interval:
                remaining_bytes *= 1000
                remaining_bytes -= sent_bytes

                if remaining_bytes >= bytes:
                    sent_bytes += bytes
                    self.packets.append(pkt)
                    self.total_pkt_num += 1
                    if pkt == reply:
                        replies_count += 1
                else:
                    print("Warning: generated attack packets exceeded bandwidth. Packets in interval {} "
                          "were omitted.".format(interval_count))
                    full_interval = current_interval

            # every 1000 packets write them to the pcap file (append)
            if (self.total_pkt_num > 0) and (self.total_pkt_num % buffer_size == 0) and (len(self.packets) > 0):
                self.last_packet = self.packets[-1]
                self.attack_end_utime = self.last_packet.time
                self.packets = sorted(self.packets, key=lambda pkt: pkt.time)
                self.path_attack_pcap = self.write_attack_pcap(self.packets, True, self.path_attack_pcap)
                self.packets = []
Beispiel #8
0
    def generate_attack_packets(self):
        """
        Creates the attack packets.
        """
        pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND)

        # Timestamp
        first_timestamp = self.get_param_value(atkParam.Parameter.INJECT_AT_TIMESTAMP)
        # store start time of attack
        self.attack_start_utime = first_timestamp

        # Initialize parameters
        self.packets = []
        ip_destination = self.get_param_value(atkParam.Parameter.IP_DESTINATION)
        mac_destination = self.get_param_value(atkParam.Parameter.MAC_DESTINATION)

        # Determine source IP and MAC address
        num_attackers = self.get_param_value(atkParam.Parameter.NUMBER_ATTACKERS)
        # user supplied atkParam.Parameter.NUMBER_ATTACKERS
        if (num_attackers is not None) and (num_attackers is not 0):
            # The most used IP class in background traffic
            most_used_ip_class = Util.handle_most_used_outputs(self.statistics.get_most_used_ip_class())
            # Create random attackers based on user input atkParam.Parameter.NUMBER_ATTACKERS
            ip_source = self.generate_random_ipv4_address(most_used_ip_class, num_attackers)
            mac_source = self.generate_random_mac_address(num_attackers)
        else:  # user did not supply atkParam.Parameter.NUMBER_ATTACKS
            # use default values for IP_SOURCE/MAC_SOURCE or overwritten values
            # if user supplied any values for those params
            ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE)
            mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE)

        ip_source_list = []
        mac_source_list = []

        if isinstance(ip_source, list):
            ip_source_list = ip_source
        else:
            ip_source_list.append(ip_source)

        if isinstance(mac_source, list):
            mac_source_list = mac_source
        else:
            mac_source_list.append(mac_source)

        if (num_attackers is None) or (num_attackers is 0):
            num_attackers = min(len(ip_source_list), len(mac_source_list))

        # Check ip.src == ip.dst
        self.ip_src_dst_equal_check(ip_source_list, ip_destination)

        # Get MSS, TTL and Window size value for destination IP
        destination_mss_value, destination_ttl_value, destination_win_value = self.get_ip_data(ip_destination)

        min_delay, max_delay = self.get_reply_delay(ip_destination)

        attack_duration = self.get_param_value(atkParam.Parameter.ATTACK_DURATION)
        attack_ends_time = first_timestamp + attack_duration

        victim_pps = pps * num_attackers

        for attacker in range(num_attackers):
            # Get MSS, TTL and Window size value for source IP(attacker)
            source_mss_value, source_ttl_value, source_win_value = self.get_ip_data(ip_source_list[attacker])

            attacker_seq = rnd.randint(1000, 50000)
            victim_seq = rnd.randint(1000, 50000)

            sport = 1025

            # Timestamps of first self.packets shouldn't be exactly the same to look more realistic
            timestamp_next_pkt = rnd.uniform(first_timestamp, Util.update_timestamp(first_timestamp, pps))

            while timestamp_next_pkt <= attack_ends_time:
                # Establish TCP connection
                if sport > 65535:
                    sport = 1025

                # prepare reusable Ethernet- and IP-headers
                attacker_ether = inet.Ether(src=mac_source_list[attacker], dst=mac_destination)
                attacker_ip = inet.IP(src=ip_source_list[attacker], dst=ip_destination, ttl=source_ttl_value,
                                      flags='DF')
                victim_ether = inet.Ether(src=mac_destination, dst=mac_source_list[attacker])
                victim_ip = inet.IP(src=ip_destination, dst=ip_source_list[attacker], ttl=destination_ttl_value,
                                    flags='DF')

                # connection request from attacker (client)
                syn_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, window=source_win_value, flags='S',
                                   seq=attacker_seq, options=[('MSS', source_mss_value)])
                attacker_seq += 1
                syn = (attacker_ether / attacker_ip / syn_tcp)
                syn.time = timestamp_next_pkt
                timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, victim_pps, min_delay)
                self.packets.append(syn)

                # response from victim (server)
                synack_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, seq=victim_seq, ack=attacker_seq, flags='SA',
                                      window=destination_win_value, options=[('MSS', destination_mss_value)])
                victim_seq += 1
                synack = (victim_ether / victim_ip / synack_tcp)
                synack.time = timestamp_next_pkt
                timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps, min_delay)
                self.packets.append(synack)

                # acknowledgement from attacker (client)
                ack_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, seq=attacker_seq, ack=victim_seq, flags='A',
                                   window=source_win_value, options=[('MSS', source_mss_value)])
                ack = (attacker_ether / attacker_ip / ack_tcp)
                ack.time = timestamp_next_pkt
                timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps)
                self.packets.append(ack)

                # send NBT session header packet with maximum LENGTH-field
                req_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, seq=attacker_seq, ack=victim_seq, flags='AP',
                                   window=source_win_value, options=[('MSS', source_mss_value)])
                req_payload = NBTSession(TYPE=0x00, LENGTH=0x1FFFF)

                attacker_seq += len(req_payload)
                req = (attacker_ether / attacker_ip / req_tcp / req_payload)
                req.time = timestamp_next_pkt
                timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, victim_pps, min_delay)
                self.packets.append(req)

                # final ack from victim (server)
                last_ack_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, seq=victim_seq, ack=attacker_seq, flags='A',
                                        window=destination_win_value, options=[('MSS', destination_mss_value)])
                last_ack = (victim_ether / victim_ip / last_ack_tcp)
                last_ack.time = timestamp_next_pkt
                timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps, min_delay)
                self.packets.append(last_ack)

                sport += 1
Beispiel #9
0
    def generate_attack_packets(self):
        """
        Creates the attack packets.
        """
        # Timestamp
        timestamp_next_pkt = self.get_param_value(
            atkParam.Parameter.INJECT_AT_TIMESTAMP)
        pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND)

        # calculate complement packet rates of BG traffic per interval
        complement_interval_pps = self.statistics.calculate_complement_packet_rates(
            pps)

        # Initialize parameters
        self.packets = []
        mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE)
        ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE)
        # FIXME: why is port_source never used?
        port_source = self.get_param_value(atkParam.Parameter.PORT_SOURCE)
        mac_destination = self.get_param_value(
            atkParam.Parameter.MAC_DESTINATION)
        ip_destination = self.get_param_value(
            atkParam.Parameter.IP_DESTINATION)
        port_destination = self.get_param_value(
            atkParam.Parameter.PORT_DESTINATION)

        # Check ip.src == ip.dst
        self.ip_src_dst_equal_check(ip_source, ip_destination)

        # Set TTL based on TTL distribution of IP address
        source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
        if len(source_ttl_dist) > 0:
            source_ttl_prob_dict = lea.Lea.fromValFreqsDict(source_ttl_dist)
            source_ttl_value = source_ttl_prob_dict.random()
        else:
            source_ttl_value = Util.handle_most_used_outputs(
                self.statistics.get_most_used_ttl_value())

        destination_ttl_dist = self.statistics.get_ttl_distribution(
            ip_destination)
        if len(destination_ttl_dist) > 0:
            destination_ttl_prob_dict = lea.Lea.fromValFreqsDict(
                destination_ttl_dist)
            destination_ttl_value = destination_ttl_prob_dict.random()
        else:
            destination_ttl_value = Util.handle_most_used_outputs(
                self.statistics.get_most_used_ttl_value())

        # Set Window Size based on Window Size distribution of IP address
        source_win_dist = self.statistics.get_win_distribution(ip_source)
        if len(source_win_dist) > 0:
            source_win_prob_dict = lea.Lea.fromValFreqsDict(source_win_dist)
        else:
            source_win_dist = self.statistics.get_win_distribution(
                self.statistics.get_most_used_ip_address())
            source_win_prob_dict = lea.Lea.fromValFreqsDict(source_win_dist)

        destination_win_dist = self.statistics.get_win_distribution(
            ip_destination)
        if len(destination_win_dist) > 0:
            destination_win_prob_dict = lea.Lea.fromValFreqsDict(
                destination_win_dist)
        else:
            destination_win_dist = self.statistics.get_win_distribution(
                self.statistics.get_most_used_ip_address())
            destination_win_prob_dict = lea.Lea.fromValFreqsDict(
                destination_win_dist)

        # Set MSS (Maximum Segment Size) based on MSS distribution of IP address
        mss_value = Util.handle_most_used_outputs(
            self.statistics.get_most_used_mss_value())
        if not mss_value:
            mss_value = 1465

        # Inject EternalBlue exploit packets
        # Read Win7_eternalblue_exploit pcap file
        source_origin_wins, destination_origin_wins = {}, {}
        exploit_raw_packets = scapy.utils.RawPcapReader(
            self.template_attack_pcap_path)

        port_source = rnd.randint(
            self.minDefaultPort,
            self.maxDefaultPort)  # experiments show this range of ports
        # conversations = {(ip.src, ip.dst, port.src, port.dst): packets}
        conversations, order_list_conversations = self.packets_to_convs(
            exploit_raw_packets)
        exploit_raw_packets.close()

        conv_start_timesamp = timestamp_next_pkt
        for conv_index, conv in enumerate(order_list_conversations):
            # the distance between the starts of the converstaions
            conv_start_timesamp = conv_start_timesamp + rnd.uniform(
                0.001, 0.01)
            timestamp_next_pkt = conv_start_timesamp

            conv_pkts = conversations[conv]
            inter_arrival_times = self.get_inter_arrival_time(conv_pkts)

            if conv_index == len(
                    order_list_conversations) - 2:  # Not the last conversation
                timestamp_next_pkt = self.packets[-1].time + rnd.uniform(
                    0.001, 0.01)

            if conv_index != len(
                    order_list_conversations) - 1:  # Not the last conversation
                port_source += 2
                for self.pkt_num, pkt in enumerate(conv_pkts):
                    eth_frame = inet.Ether(pkt[0])
                    ip_pkt = eth_frame.payload
                    tcp_pkt = ip_pkt.payload

                    if self.pkt_num == 0:
                        if tcp_pkt.getfieldval("dport") == SMBLib.smb_port:
                            orig_ip_dst = ip_pkt.getfieldval("dst")

                    # Request
                    if ip_pkt.getfieldval("dst") == orig_ip_dst:  # victim IP
                        # Ether
                        eth_frame.setfieldval("src", mac_source)
                        eth_frame.setfieldval("dst", mac_destination)
                        # IP
                        ip_pkt.setfieldval("src", ip_source)
                        ip_pkt.setfieldval("dst", ip_destination)
                        ip_pkt.setfieldval("ttl", source_ttl_value)
                        # TCP
                        tcp_pkt.setfieldval("sport", port_source)
                        tcp_pkt.setfieldval("dport", port_destination)
                        # Window Size
                        source_origin_win = tcp_pkt.getfieldval("window")
                        if source_origin_win not in source_origin_wins:
                            source_origin_wins[
                                source_origin_win] = source_win_prob_dict.random(
                                )
                        new_win = source_origin_wins[source_origin_win]
                        tcp_pkt.setfieldval("window", new_win)
                        # MSS
                        tcp_options = tcp_pkt.getfieldval("options")
                        if tcp_options:
                            if tcp_options[0][0] == "MSS":
                                tcp_options[0] = ("MSS", mss_value)
                                tcp_pkt.setfieldval("options", tcp_options)

                        new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                        new_pkt.time = timestamp_next_pkt

                        pps = max(
                            Util.get_interval_pps(complement_interval_pps,
                                                  timestamp_next_pkt), 10)
                        timestamp_next_pkt = Util.update_timestamp(
                            timestamp_next_pkt, pps) + inter_arrival_times[
                                self.pkt_num]  # float(timeSteps.random())

                    # Reply
                    else:
                        # Ether
                        eth_frame.setfieldval("src", mac_destination)
                        eth_frame.setfieldval("dst", mac_source)
                        # IP
                        ip_pkt.setfieldval("src", ip_destination)
                        ip_pkt.setfieldval("dst", ip_source)
                        ip_pkt.setfieldval("ttl", destination_ttl_value)
                        # TCP
                        tcp_pkt.setfieldval("dport", port_source)
                        tcp_pkt.setfieldval("sport", port_destination)
                        # Window Size
                        destination_origin_win = tcp_pkt.getfieldval("window")
                        if destination_origin_win not in destination_origin_wins:
                            destination_origin_wins[
                                destination_origin_win] = destination_win_prob_dict.random(
                                )
                        new_win = destination_origin_wins[
                            destination_origin_win]
                        tcp_pkt.setfieldval("window", new_win)
                        # MSS
                        tcp_options = tcp_pkt.getfieldval("options")
                        if tcp_options:
                            if tcp_options[0][0] == "MSS":
                                tcp_options[0] = ("MSS", mss_value)
                                tcp_pkt.setfieldval("options", tcp_options)

                        new_pkt = (eth_frame / ip_pkt / tcp_pkt)

                        pps = max(
                            Util.get_interval_pps(complement_interval_pps,
                                                  timestamp_next_pkt), 10)
                        timestamp_next_pkt = Util.update_timestamp(
                            timestamp_next_pkt, pps) + inter_arrival_times[
                                self.pkt_num]  # float(timeSteps.random())

                        new_pkt.time = timestamp_next_pkt

                    self.packets.append(new_pkt)

            else:  # Last conversation where the victim start a connection with the attacker
                timestamp_next_pkt = self.packets[-1].time + rnd.uniform(
                    0.001, 0.01)
                port_source = rnd.randint(self.minDefaultPort,
                                          self.maxDefaultPort)
                for self.pkt_num, pkt in enumerate(conv_pkts):
                    eth_frame = inet.Ether(pkt[0])
                    ip_pkt = eth_frame.payload
                    tcp_pkt = ip_pkt.payload

                    # Request
                    if tcp_pkt.getfieldval("dport") == self.last_conn_dst_port:
                        # Ether
                        eth_frame.setfieldval("src", mac_destination)
                        eth_frame.setfieldval("dst", mac_source)
                        # IP
                        ip_pkt.setfieldval("src", ip_destination)
                        ip_pkt.setfieldval("dst", ip_source)
                        ip_pkt.setfieldval("ttl", destination_ttl_value)
                        # TCP
                        tcp_pkt.setfieldval("sport", port_source)
                        # destination port is fixed 4444
                        # Window Size
                        destination_origin_win = tcp_pkt.getfieldval("window")
                        if destination_origin_win not in destination_origin_wins:
                            destination_origin_wins[
                                destination_origin_win] = destination_win_prob_dict.random(
                                )
                        new_win = destination_origin_wins[
                            destination_origin_win]
                        tcp_pkt.setfieldval("window", new_win)
                        # MSS
                        tcp_options = tcp_pkt.getfieldval("options")
                        if tcp_options:
                            if tcp_options[0][0] == "MSS":
                                tcp_options[0] = ("MSS", mss_value)
                                tcp_pkt.setfieldval("options", tcp_options)

                        new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                        new_pkt.time = timestamp_next_pkt

                        pps = max(
                            Util.get_interval_pps(complement_interval_pps,
                                                  timestamp_next_pkt), 10)
                        timestamp_next_pkt = Util.update_timestamp(
                            timestamp_next_pkt, pps) + inter_arrival_times[
                                self.pkt_num]  # float(timeSteps.random())

                    # Reply
                    else:
                        # Ether
                        eth_frame.setfieldval("src", mac_source)
                        eth_frame.setfieldval("dst", mac_destination)
                        # IP
                        ip_pkt.setfieldval("src", ip_source)
                        ip_pkt.setfieldval("dst", ip_destination)
                        ip_pkt.setfieldval("ttl", source_ttl_value)
                        # TCP
                        tcp_pkt.setfieldval("dport", port_source)
                        # source port is fixed 4444
                        # Window Size
                        source_origin_win = tcp_pkt.getfieldval("window")
                        if source_origin_win not in source_origin_wins:
                            source_origin_wins[
                                source_origin_win] = source_win_prob_dict.random(
                                )
                        new_win = source_origin_wins[source_origin_win]
                        tcp_pkt.setfieldval("window", new_win)
                        # MSS
                        tcp_options = tcp_pkt.getfieldval("options")
                        if tcp_options:
                            if tcp_options[0][0] == "MSS":
                                tcp_options[0] = ("MSS", mss_value)
                                tcp_pkt.setfieldval("options", tcp_options)

                        new_pkt = (eth_frame / ip_pkt / tcp_pkt)

                        pps = max(
                            Util.get_interval_pps(complement_interval_pps,
                                                  timestamp_next_pkt), 10)
                        timestamp_next_pkt = Util.update_timestamp(
                            timestamp_next_pkt, pps) + inter_arrival_times[
                                self.pkt_num]  # float(timeSteps.random())

                        new_pkt.time = timestamp_next_pkt

                    self.packets.append(new_pkt)
Beispiel #10
0
 def test_handle_most_used_outputs_list_unsorted(self):
     test_input = [2, 4, 0, 1, 3]
     self.assertEqual(Utility.handle_most_used_outputs(test_input), 0)
Beispiel #11
0
 def test_handle_most_used_outputs_list_sorted(self):
     test_input = [0, 1, 2, 3, 4]
     self.assertEqual(Utility.handle_most_used_outputs(test_input), 0)
Beispiel #12
0
 def test_handle_most_used_outputs_one_list(self):
     test_input = ["SomeTest"]
     self.assertEqual(Utility.handle_most_used_outputs(test_input),
                      test_input[0])
Beispiel #13
0
 def test_handle_most_used_outputs_one(self):
     test_input = "SomeTest"
     self.assertEqual(Utility.handle_most_used_outputs(test_input),
                      test_input)
Beispiel #14
0
 def test_handle_most_used_outputs_empty(self):
     self.assertIsNone(Utility.handle_most_used_outputs([]))
Beispiel #15
0
    def generate_attack_packets(self):
        """
        Creates the attack packets.
        """
        # Timestamp
        timestamp_next_pkt = self.get_param_value(
            atkParam.Parameter.INJECT_AT_TIMESTAMP)

        # Initialize parameters
        self.packets = []
        mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE)
        ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE)
        port_source = rnd.randint(self.minDefaultPort, self.maxDefaultPort)
        mac_destination = self.get_param_value(
            atkParam.Parameter.MAC_DESTINATION)
        ip_destination = self.get_param_value(
            atkParam.Parameter.IP_DESTINATION)
        port_destination = self.get_param_value(
            atkParam.Parameter.PORT_DESTINATION)

        target_host = self.get_param_value(atkParam.Parameter.TARGET_HOST)
        target_uri = "/"  # self.get_param_value(atkParam.Parameter.TARGET_URI)

        # Check ip.src == ip.dst
        self.ip_src_dst_catch_equal(ip_source, ip_destination)

        # Set TTL based on TTL distribution of IP address
        source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
        if len(source_ttl_dist) > 0:
            source_ttl_prob_dict = lea.Lea.fromValFreqsDict(source_ttl_dist)
            source_ttl_value = source_ttl_prob_dict.random()
        else:
            source_ttl_value = Util.handle_most_used_outputs(
                self.statistics.get_most_used_ttl_value())

        destination_ttl_dist = self.statistics.get_ttl_distribution(
            ip_destination)
        if len(destination_ttl_dist) > 0:
            destination_ttl_prob_dict = lea.Lea.fromValFreqsDict(
                destination_ttl_dist)
            destination_ttl_value = destination_ttl_prob_dict.random()
        else:
            destination_ttl_value = Util.handle_most_used_outputs(
                self.statistics.get_most_used_ttl_value())

        # Inject Joomla_registration_privesc
        # Read joomla_registration_privesc pcap file
        orig_ip_dst = None
        exploit_raw_packets = scapy.utils.RawPcapReader(
            self.template_attack_pcap_path)
        inter_arrival_times, inter_arrival_time_dist = self.get_inter_arrival_time(
            exploit_raw_packets, True)
        exploit_raw_packets.close()
        time_steps = lea.Lea.fromValFreqsDict(inter_arrival_time_dist)
        exploit_raw_packets = scapy.utils.RawPcapReader(
            self.template_attack_pcap_path)

        # Random TCP sequence numbers
        global attacker_seq
        attacker_seq = rnd.randint(1000, 50000)
        global victim_seq
        victim_seq = rnd.randint(1000, 50000)

        for self.pkt_num, pkt in enumerate(exploit_raw_packets):
            eth_frame = inet.Ether(pkt[0])
            ip_pkt = eth_frame.payload
            tcp_pkt = ip_pkt.payload
            str_tcp_seg = str(tcp_pkt.payload)

            # Clean payloads
            eth_frame.payload = b''
            ip_pkt.payload = b''
            tcp_pkt.payload = b''

            # FIXME: no getfieldval in class bytes
            if self.pkt_num == 0:
                prev_orig_port_source = tcp_pkt.getfieldval("sport")
                if tcp_pkt.getfieldval("dport") == self.http_port:
                    orig_ip_dst = ip_pkt.getfieldval("dst")  # victim IP

            # Request: Attacker --> vicitm
            if ip_pkt.getfieldval("dst") == orig_ip_dst:  # victim IP
                # There are 7 TCP connections with different source ports, for each of them we generate random port
                if tcp_pkt.getfieldval("sport") != prev_orig_port_source:
                    port_source = rnd.randint(self.minDefaultPort,
                                              self.maxDefaultPort)
                    prev_orig_port_source = tcp_pkt.getfieldval("sport")
                    # New connection, new random TCP sequence numbers
                    attacker_seq = rnd.randint(1000, 50000)
                    victim_seq = rnd.randint(1000, 50000)
                    # First packet in a connection has ACK = 0
                    tcp_pkt.setfieldval("ack", 0)

                # Ether
                eth_frame.setfieldval("src", mac_source)
                eth_frame.setfieldval("dst", mac_destination)
                # IP
                ip_pkt.setfieldval("src", ip_source)
                ip_pkt.setfieldval("dst", ip_destination)
                ip_pkt.setfieldval("ttl", source_ttl_value)
                # TCP
                tcp_pkt.setfieldval("sport", port_source)
                tcp_pkt.setfieldval("dport", port_destination)

                str_tcp_seg = self.modify_http_header(str_tcp_seg,
                                                      '/joomla360', target_uri,
                                                      orig_ip_dst, target_host)

                # TCP Seq, Ack
                if tcp_pkt.getfieldval("ack") != 0:
                    tcp_pkt.setfieldval("ack", victim_seq)
                tcp_pkt.setfieldval("seq", attacker_seq)
                if not (tcp_pkt.getfieldval("flags") == 16
                        and len(str_tcp_seg) == 0):  # flags=A:
                    attacker_seq += max(len(str_tcp_seg), 1)

                new_pkt = (eth_frame / ip_pkt / tcp_pkt / str_tcp_seg)
                new_pkt.time = timestamp_next_pkt

                timestamp_next_pkt = self.timestamp_controller.next_timestamp(
                ) + float(time_steps.random())

            # Reply: Victim --> attacker
            else:
                # Ether
                eth_frame.setfieldval("src", mac_destination)
                eth_frame.setfieldval("dst", mac_source)
                # IP
                ip_pkt.setfieldval("src", ip_destination)
                ip_pkt.setfieldval("dst", ip_source)
                ip_pkt.setfieldval("ttl", destination_ttl_value)
                # TCP
                tcp_pkt.setfieldval("dport", port_source)
                tcp_pkt.setfieldval("sport", port_destination)

                str_tcp_seg = self.modify_http_header(str_tcp_seg,
                                                      '/joomla360', target_uri,
                                                      orig_ip_dst, target_host)

                # TCP Seq, ACK
                tcp_pkt.setfieldval("ack", attacker_seq)
                tcp_pkt.setfieldval("seq", victim_seq)
                str_len = len(str_tcp_seg)
                if not (tcp_pkt.getfieldval("flags") == 16
                        and str_len == 0):  # flags=A:
                    victim_seq += max(str_len, 1)

                new_pkt = (eth_frame / ip_pkt / tcp_pkt / str_tcp_seg)
                timestamp_next_pkt = self.timestamp_controller.next_timestamp(
                ) + float(time_steps.random())
                new_pkt.time = timestamp_next_pkt

            self.packets.append(new_pkt)

        exploit_raw_packets.close()
Beispiel #16
0
    def generate_attack_packets(self):
        """
        Creates the attack packets.
        """
        pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND)

        # Timestamp
        timestamp_next_pkt = self.get_param_value(
            atkParam.Parameter.INJECT_AT_TIMESTAMP)
        # store start time of attack
        self.attack_start_utime = timestamp_next_pkt

        # Initialize parameters
        ip_victim = self.get_param_value(atkParam.Parameter.IP_SOURCE)
        ip_attacker = self.get_param_value(atkParam.Parameter.IP_DESTINATION)
        mac_victim = self.get_param_value(atkParam.Parameter.MAC_SOURCE)
        mac_attacker = self.get_param_value(atkParam.Parameter.MAC_DESTINATION)

        custom_payload = self.get_param_value(
            atkParam.Parameter.CUSTOM_PAYLOAD)
        custom_payload_len = len(custom_payload)
        custom_payload_limit = 1000
        Util.check_payload_len(custom_payload_len, custom_payload_limit)

        self.packets = []

        # Create random victim if specified
        if self.get_param_value(atkParam.Parameter.IP_SOURCE_RANDOMIZE):
            # The most used IP class in background traffic
            most_used_ip_class = Util.handle_most_used_outputs(
                self.statistics.get_most_used_ip_class())
            ip_victim = self.generate_random_ipv4_address(
                most_used_ip_class, 1)
            mac_victim = self.generate_random_mac_address()

        # Get MSS, TTL and Window size value for victim/attacker IP
        victim_mss_value, victim_ttl_value, victim_win_value = self.get_ip_data(
            ip_victim)
        attacker_mss_value, attacker_ttl_value, attacker_win_value = self.get_ip_data(
            ip_attacker)

        min_delay, max_delay = self.get_reply_delay(ip_attacker)

        attacker_seq = rnd.randint(1000, 50000)
        victim_seq = rnd.randint(1000, 50000)

        sport = Util.generate_source_port_from_platform("win7")

        # connection request from victim (client)
        victim_ether = inet.Ether(src=mac_victim, dst=mac_attacker)
        victim_ip = inet.IP(src=ip_victim,
                            dst=ip_attacker,
                            ttl=victim_ttl_value,
                            flags='DF')
        request_tcp = inet.TCP(sport=sport,
                               dport=ftp_port,
                               window=victim_win_value,
                               flags='S',
                               seq=victim_seq,
                               options=[('MSS', victim_mss_value)])
        victim_seq += 1
        syn = (victim_ether / victim_ip / request_tcp)
        syn.time = timestamp_next_pkt
        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps,
                                                   min_delay)
        self.packets.append(syn)

        # response from attacker (server)
        attacker_ether = inet.Ether(src=mac_attacker, dst=mac_victim)
        attacker_ip = inet.IP(src=ip_attacker,
                              dst=ip_victim,
                              ttl=attacker_ttl_value,
                              flags='DF')
        reply_tcp = inet.TCP(sport=ftp_port,
                             dport=sport,
                             seq=attacker_seq,
                             ack=victim_seq,
                             flags='SA',
                             window=attacker_win_value,
                             options=[('MSS', attacker_mss_value)])
        attacker_seq += 1
        synack = (attacker_ether / attacker_ip / reply_tcp)
        synack.time = timestamp_next_pkt
        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps,
                                                   min_delay)
        self.packets.append(synack)

        # acknowledgement from victim (client)
        ack_tcp = inet.TCP(sport=sport,
                           dport=ftp_port,
                           seq=victim_seq,
                           ack=attacker_seq,
                           flags='A',
                           window=victim_win_value,
                           options=[('MSS', victim_mss_value)])
        ack = (victim_ether / victim_ip / ack_tcp)
        ack.time = timestamp_next_pkt
        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps)
        self.packets.append(ack)

        # FTP exploit packet
        ftp_tcp = inet.TCP(sport=ftp_port,
                           dport=sport,
                           seq=attacker_seq,
                           ack=victim_seq,
                           flags='PA',
                           window=attacker_win_value,
                           options=[('MSS', attacker_mss_value)])

        characters = b'220'
        characters += Util.get_rnd_bytes(2065, Util.forbidden_chars)
        characters += b'\x96\x72\x01\x68'
        characters += Util.get_rnd_x86_nop(10, False, Util.forbidden_chars)

        custom_payload_file = self.get_param_value(
            atkParam.Parameter.CUSTOM_PAYLOAD_FILE)

        # Generation of payload of the FTP exploit packet
        if custom_payload == '':
            if custom_payload_file == '':
                payload = Util.get_rnd_bytes(custom_payload_limit,
                                             Util.forbidden_chars)
            else:
                payload = ID2TLib.Utility.get_bytes_from_file(
                    custom_payload_file)
                Util.check_payload_len(len(payload), custom_payload_limit)
                payload += Util.get_rnd_x86_nop(
                    custom_payload_limit - len(payload), False,
                    Util.forbidden_chars)
        else:
            encoded_payload = custom_payload.encode()
            payload = Util.get_rnd_x86_nop(
                custom_payload_limit - custom_payload_len, False,
                Util.forbidden_chars)
            payload += encoded_payload

        characters += payload
        characters += Util.get_rnd_x86_nop(20, False, Util.forbidden_chars)
        characters += b'\r\n'

        ftp_tcp.add_payload(characters)

        ftp_buff = (attacker_ether / attacker_ip / ftp_tcp)
        ftp_buff.time = timestamp_next_pkt
        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps)
        self.packets.append(ftp_buff)
        attacker_seq += len(ftp_tcp.payload)

        # Fin Ack from attacker
        fin_ack_tcp = inet.TCP(sport=ftp_port,
                               dport=sport,
                               seq=attacker_seq,
                               ack=victim_seq,
                               flags='FA',
                               window=attacker_win_value,
                               options=[('MSS', attacker_mss_value)])

        fin_ack = (attacker_ether / attacker_ip / fin_ack_tcp)
        fin_ack.time = timestamp_next_pkt
        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps,
                                                   min_delay)
        self.packets.append(fin_ack)

        # Ack from victim on FTP packet
        ftp_ack_tcp = inet.TCP(sport=sport,
                               dport=ftp_port,
                               seq=victim_seq,
                               ack=attacker_seq,
                               flags='A',
                               window=victim_win_value,
                               options=[('MSS', victim_mss_value)])
        ftp_ack = (victim_ether / victim_ip / ftp_ack_tcp)
        ftp_ack.time = timestamp_next_pkt
        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps)
        self.packets.append(ftp_ack)

        # Ack from victim on Fin/Ack of attacker
        fin_ack_ack_tcp = inet.TCP(sport=sport,
                                   dport=ftp_port,
                                   seq=victim_seq,
                                   ack=attacker_seq + 1,
                                   flags='A',
                                   window=victim_win_value,
                                   options=[('MSS', victim_mss_value)])
        fin_ack_ack = (victim_ether / victim_ip / fin_ack_ack_tcp)
        fin_ack_ack.time = timestamp_next_pkt
        self.packets.append(fin_ack_ack)
Beispiel #17
0
    def generate_attack_packets(self):
        """
        Creates the attack packets.
        """

        # Timestamp
        timestamp_next_pkt = self.get_param_value(
            atkParam.Parameter.INJECT_AT_TIMESTAMP)

        # Initialize parameters
        self.packets = []
        mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE)
        ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE)

        # Pick a DNS server from the background traffic
        ip_dns_server = self.statistics.process_db_query(
            "SELECT ipAddress FROM ip_protocols WHERE protocolName='DNS' AND protocolCount=(SELECT MAX(protocolCount) "
            "FROM ip_protocols WHERE protocolName='DNS');")
        ip_dns_server = Util.handle_most_used_outputs(ip_dns_server)
        if not ip_dns_server or ip_source == ip_dns_server:
            ip_dns_server = self.statistics.get_random_ip_address()
        mac_dns_server = self.statistics.get_mac_address(ip_dns_server)

        # Bot original config in the template PCAP
        origin_mac_src = "08:00:27:e5:d7:b0"
        origin_ip_src = "10.0.2.15"

        origin_mac_dns_server = "52:54:00:12:35:02"
        origin_ip_dns_server = "10.0.2.2"

        ttl_map = {}

        ip_map = {
            origin_ip_src: ip_source,
            origin_ip_dns_server: ip_dns_server
        }
        mac_map = {
            origin_mac_src: mac_source,
            origin_mac_dns_server: mac_dns_server
        }

        # Inject Sality botnet
        # Read sality_botnet pcap file
        exploit_raw_packets = scapy.utils.RawPcapReader(
            self.template_attack_pcap_path)

        for self.pkt_num, pkt in enumerate(exploit_raw_packets):
            eth_frame = inet.Ether(pkt[0])
            ip_pkt = eth_frame.payload

            # Ether
            if eth_frame.getfieldval("src") in mac_map:
                eth_frame.setfieldval("src",
                                      mac_map[eth_frame.getfieldval("src")])
            if eth_frame.getfieldval("dst") in mac_map:
                eth_frame.setfieldval("dst",
                                      mac_map[eth_frame.getfieldval("dst")])

            # IP
            if ip_pkt.getfieldval("src") in ip_map:
                ip_pkt.setfieldval("src", ip_map[ip_pkt.getfieldval("src")])
            if ip_pkt.getfieldval("dst") in ip_map:
                ip_pkt.setfieldval("dst", ip_map[ip_pkt.getfieldval("dst")])

            # TTL
            if ip_pkt.getfieldval("ttl") not in ttl_map:
                source_ttl = self.statistics.get_most_used_ttl(
                    ip_pkt.getfieldval("src"))
                if not source_ttl:
                    source_ttl = self.statistics.process_db_query(
                        "SELECT ttlValue FROM ip_ttl;")
                    if isinstance(source_ttl, list):
                        source_ttl = rnd.choice(source_ttl)
                ttl_map[ip_pkt.getfieldval("ttl")] = source_ttl
            ip_pkt.setfieldval("ttl", ttl_map[ip_pkt.getfieldval("ttl")])

            new_pkt = (eth_frame / ip_pkt)
            new_pkt.time = timestamp_next_pkt

            timestamp_next_pkt = self.timestamp_controller.next_timestamp()

            self.packets.append(new_pkt)

        exploit_raw_packets.close()
Beispiel #18
0
    def generate_attack_packets(self):
        """
        Creates the attack packets.
        """
        # Timestamp
        timestamp_next_pkt = self.get_param_value(
            atkParam.Parameter.INJECT_AT_TIMESTAMP)
        pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND)

        # calculate complement packet rates of BG traffic per interval
        complement_interval_pps = self.statistics.calculate_complement_packet_rates(
            pps)

        # Initialize parameters
        self.packets = []
        mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE)
        ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE)
        port_source = self.get_param_value(atkParam.Parameter.PORT_SOURCE)
        mac_destination = self.get_param_value(
            atkParam.Parameter.MAC_DESTINATION)
        ip_destination = self.get_param_value(
            atkParam.Parameter.IP_DESTINATION)
        port_destination = self.get_param_value(
            atkParam.Parameter.PORT_DESTINATION)

        # Check ip.src == ip.dst
        self.ip_src_dst_equal_check(ip_source, ip_destination)

        # Set TTL based on TTL distribution of IP address
        source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
        if len(source_ttl_dist) > 0:
            source_ttl_prob_dict = lea.Lea.fromValFreqsDict(source_ttl_dist)
            source_ttl_value = source_ttl_prob_dict.random()
        else:
            source_ttl_value = Util.handle_most_used_outputs(
                self.statistics.get_most_used_ttl_value())

        destination_ttl_dist = self.statistics.get_ttl_distribution(
            ip_destination)
        if len(destination_ttl_dist) > 0:
            destination_ttl_prob_dict = lea.Lea.fromValFreqsDict(
                destination_ttl_dist)
            destination_ttl_value = destination_ttl_prob_dict.random()
        else:
            destination_ttl_value = Util.handle_most_used_outputs(
                self.statistics.get_most_used_ttl_value())

        # Set Window Size based on Window Size distribution of IP address
        source_win_dist = self.statistics.get_win_distribution(ip_source)
        if len(source_win_dist) > 0:
            source_win_prob_dict = lea.Lea.fromValFreqsDict(source_win_dist)
        else:
            source_win_dist = self.statistics.get_win_distribution(
                self.statistics.get_most_used_ip_address())
            source_win_prob_dict = lea.Lea.fromValFreqsDict(source_win_dist)

        destination_win_dist = self.statistics.get_win_distribution(
            ip_destination)
        if len(destination_win_dist) > 0:
            destination_win_prob_dict = lea.Lea.fromValFreqsDict(
                destination_win_dist)
        else:
            destination_win_dist = self.statistics.get_win_distribution(
                self.statistics.get_most_used_ip_address())
            destination_win_prob_dict = lea.Lea.fromValFreqsDict(
                destination_win_dist)

        # Set MSS (Maximum Segment Size) based on MSS distribution of IP address
        mss_value = Util.handle_most_used_outputs(
            self.statistics.get_most_used_mss_value())
        if not mss_value:
            mss_value = 1465

        # Scan (MS17)
        # Read Win7_eternalblue_scan pcap file
        orig_ip_dst = None
        exploit_raw_packets = scapy.utils.RawPcapReader(
            self.template_scan_pcap_path)
        inter_arrival_times = self.get_inter_arrival_time(exploit_raw_packets)
        exploit_raw_packets.close()
        exploit_raw_packets = scapy.utils.RawPcapReader(
            self.template_scan_pcap_path)

        source_origin_wins, destination_origin_wins = {}, {}

        for self.pkt_num, pkt in enumerate(exploit_raw_packets):
            eth_frame = inet.Ether(pkt[0])
            ip_pkt = eth_frame.payload
            tcp_pkt = ip_pkt.payload

            if self.pkt_num == 0:
                if tcp_pkt.getfieldval("dport") == SMBLib.smb_port:
                    orig_ip_dst = ip_pkt.getfieldval("dst")  # victim IP

            # Request
            if ip_pkt.getfieldval("dst") == orig_ip_dst:  # victim IP
                # Ether
                eth_frame.setfieldval("src", mac_source)
                eth_frame.setfieldval("dst", mac_destination)
                # IP
                ip_pkt.setfieldval("src", ip_source)
                ip_pkt.setfieldval("dst", ip_destination)
                ip_pkt.setfieldval("ttl", source_ttl_value)
                # TCP
                tcp_pkt.setfieldval("sport", port_source)
                tcp_pkt.setfieldval("dport", port_destination)
                # Window Size (mapping)
                source_origin_win = tcp_pkt.getfieldval("window")
                if source_origin_win not in source_origin_wins:
                    source_origin_wins[
                        source_origin_win] = source_win_prob_dict.random()
                new_win = source_origin_wins[source_origin_win]
                tcp_pkt.setfieldval("window", new_win)
                # MSS
                tcp_options = tcp_pkt.getfieldval("options")
                if tcp_options:
                    if tcp_options[0][0] == "MSS":
                        tcp_options[0] = ("MSS", mss_value)
                        tcp_pkt.setfieldval("options", tcp_options)

                new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                new_pkt.time = timestamp_next_pkt

                pps = max(
                    Util.get_interval_pps(complement_interval_pps,
                                          timestamp_next_pkt), 10)
                timestamp_next_pkt = Util.update_timestamp(
                    timestamp_next_pkt, pps) + inter_arrival_times[
                        self.pkt_num]  # float(timeSteps.random())
            # Reply
            else:
                # Ether
                eth_frame.setfieldval("src", mac_destination)
                eth_frame.setfieldval("dst", mac_source)
                # IP
                ip_pkt.setfieldval("src", ip_destination)
                ip_pkt.setfieldval("dst", ip_source)
                ip_pkt.setfieldval("ttl", destination_ttl_value)
                # TCP
                tcp_pkt.setfieldval("dport", port_source)
                tcp_pkt.setfieldval("sport", port_destination)
                # Window Size
                destination_origin_win = tcp_pkt.getfieldval("window")
                if destination_origin_win not in destination_origin_wins:
                    destination_origin_wins[
                        destination_origin_win] = destination_win_prob_dict.random(
                        )
                new_win = destination_origin_wins[destination_origin_win]
                tcp_pkt.setfieldval("window", new_win)
                # MSS
                tcp_options = tcp_pkt.getfieldval("options")
                if tcp_options:
                    if tcp_options[0][0] == "MSS":
                        tcp_options[0] = ("MSS", mss_value)
                        tcp_pkt.setfieldval("options", tcp_options)

                new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                timestamp_next_pkt = Util.update_timestamp(
                    timestamp_next_pkt, pps) + inter_arrival_times[
                        self.pkt_num]  # + float(timeSteps.random())
                new_pkt.time = timestamp_next_pkt

            self.packets.append(new_pkt)

        exploit_raw_packets.close()
Beispiel #19
0
    def generate_attack_packets(self):
        """
        Creates the attack packets.
        """
        # Timestamp
        timestamp_next_pkt = self.get_param_value(
            atkParam.Parameter.INJECT_AT_TIMESTAMP)
        pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND)

        # Calculate complement packet rates of BG traffic per interval
        complement_interval_pps = self.statistics.calculate_complement_packet_rates(
            pps)

        # Initialize parameters
        self.packets = []
        mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE)
        ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE)
        if isinstance(ip_source, list):
            ip_source = ip_source[0]
        mac_destination = self.get_param_value(
            atkParam.Parameter.MAC_DESTINATION)
        ip_destination = self.get_param_value(
            atkParam.Parameter.IP_DESTINATION)
        if isinstance(ip_destination, list):
            ip_destination = ip_destination[0]
        port_destination = self.get_param_value(
            atkParam.Parameter.PORT_DESTINATION)

        target_host = self.get_param_value(atkParam.Parameter.TARGET_HOST)
        target_uri = "/"  # self.get_param_value(atkParam.Parameter.TARGET_URI)

        # Check ip.src == ip.dst
        self.ip_src_dst_equal_check(ip_source, ip_destination)

        # Set TTL based on TTL distribution of IP address
        source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
        if len(source_ttl_dist) > 0:
            source_ttl_prob_dict = lea.Lea.fromValFreqsDict(source_ttl_dist)
            source_ttl_value = source_ttl_prob_dict.random()
        else:
            source_ttl_value = Util.handle_most_used_outputs(
                self.statistics.get_most_used_ttl_value())

        destination_ttl_dist = self.statistics.get_ttl_distribution(
            ip_destination)
        if len(destination_ttl_dist) > 0:
            destination_ttl_prob_dict = lea.Lea.fromValFreqsDict(
                destination_ttl_dist)
            destination_ttl_value = destination_ttl_prob_dict.random()
        else:
            destination_ttl_value = Util.handle_most_used_outputs(
                self.statistics.get_most_used_ttl_value())

        # Inject SQLi Attack
        # Read SQLi Attack pcap file
        orig_ip_dst = None
        exploit_raw_packets = scapy.utils.RawPcapReader(
            self.template_attack_pcap_path)
        inter_arrival_times, inter_arrival_time_dist = self.get_inter_arrival_time(
            exploit_raw_packets, True)
        time_steps = lea.Lea.fromValFreqsDict(inter_arrival_time_dist)
        exploit_raw_packets.close()
        exploit_raw_packets = scapy.utils.RawPcapReader(
            self.template_attack_pcap_path)

        port_source = rnd.randint(
            self.minDefaultPort,
            self.maxDefaultPort)  # experiments show this range of ports

        # Random TCP sequence numbers
        global attacker_seq
        attacker_seq = rnd.randint(1000, 50000)
        global victim_seq
        victim_seq = rnd.randint(1000, 50000)

        for self.pkt_num, pkt in enumerate(exploit_raw_packets):
            eth_frame = inet.Ether(pkt[0])
            ip_pkt = eth_frame.payload
            tcp_pkt = ip_pkt.payload
            str_tcp_seg = str(tcp_pkt.payload)

            # Clean payloads
            eth_frame.payload = b''
            ip_pkt.payload = b''
            tcp_pkt.payload = b''

            # FIXME: no getfieldval in class bytes
            if self.pkt_num == 0:
                prev_orig_port_source = tcp_pkt.getfieldval("sport")
                orig_ip_dst = ip_pkt.getfieldval("dst")  # victim IP

            # Last connection
            if tcp_pkt.getfieldval("dport") != 80 and tcp_pkt.getfieldval(
                    "sport") != 80:
                # New connection, new random TCP sequence numbers
                attacker_seq = rnd.randint(1000, 50000)
                victim_seq = rnd.randint(1000, 50000)
                # First packet in a connection has ACK = 0
                tcp_pkt.setfieldval("ack", 0)

            # Attacker --> vicitm
            if ip_pkt.getfieldval("dst") == orig_ip_dst:  # victim IP

                # There are 363 TCP connections with different source ports, for each of them we generate random port
                if tcp_pkt.getfieldval("sport") != prev_orig_port_source and tcp_pkt.getfieldval("dport") != 4444 \
                        and (tcp_pkt.getfieldval("dport") == 80 or tcp_pkt.getfieldval("sport") == 80):
                    port_source = rnd.randint(self.minDefaultPort,
                                              self.maxDefaultPort)
                    prev_orig_port_source = tcp_pkt.getfieldval("sport")
                    # New connection, new random TCP sequence numbers
                    attacker_seq = rnd.randint(1000, 50000)
                    victim_seq = rnd.randint(1000, 50000)
                    # First packet in a connection has ACK = 0
                    tcp_pkt.setfieldval("ack", 0)

                # Ether
                eth_frame.setfieldval("src", mac_source)
                eth_frame.setfieldval("dst", mac_destination)
                # IP
                ip_pkt.setfieldval("src", ip_source)
                ip_pkt.setfieldval("dst", ip_destination)
                ip_pkt.setfieldval("ttl", source_ttl_value)

                # TCP

                # Regular connection
                if tcp_pkt.getfieldval("dport") == 80 or tcp_pkt.getfieldval(
                        "sport") == 80:
                    tcp_pkt.setfieldval("sport", port_source)
                    tcp_pkt.setfieldval("dport", port_destination)

                str_tcp_seg = self.modify_http_header(str_tcp_seg, '/ATutor',
                                                      target_uri, orig_ip_dst,
                                                      target_host)

                # TCP Seq, Ack
                if tcp_pkt.getfieldval("ack") != 0:
                    tcp_pkt.setfieldval("ack", victim_seq)
                tcp_pkt.setfieldval("seq", attacker_seq)
                if not (tcp_pkt.getfieldval("flags") == 16
                        and len(str_tcp_seg) == 0):  # flags=A:
                    attacker_seq += max(len(str_tcp_seg), 1)

                new_pkt = (eth_frame / ip_pkt / tcp_pkt / str_tcp_seg)
                new_pkt.time = timestamp_next_pkt

                pps = max(
                    Util.get_interval_pps(complement_interval_pps,
                                          timestamp_next_pkt), 10)
                timestamp_next_pkt = Util.update_timestamp(
                    timestamp_next_pkt, pps) + float(time_steps.random())

            # Victim --> attacker
            else:
                # Ether
                eth_frame.setfieldval("src", mac_destination)
                eth_frame.setfieldval("dst", mac_source)
                # IP
                ip_pkt.setfieldval("src", ip_destination)
                ip_pkt.setfieldval("dst", ip_source)
                ip_pkt.setfieldval("ttl", destination_ttl_value)

                # TCP

                # Regular connection
                if tcp_pkt.getfieldval("dport") == 80 or tcp_pkt.getfieldval(
                        "sport") == 80:
                    tcp_pkt.setfieldval("dport", port_source)
                    tcp_pkt.setfieldval("sport", port_destination)

                str_tcp_seg = self.modify_http_header(str_tcp_seg, '/ATutor',
                                                      target_uri, orig_ip_dst,
                                                      target_host)

                # TCP Seq, ACK
                tcp_pkt.setfieldval("ack", attacker_seq)
                tcp_pkt.setfieldval("seq", victim_seq)
                strLen = len(str_tcp_seg)
                if not (tcp_pkt.getfieldval("flags") == 16
                        and strLen == 0):  # flags=A:
                    victim_seq += max(strLen, 1)

                new_pkt = (eth_frame / ip_pkt / tcp_pkt / str_tcp_seg)
                timestamp_next_pkt = Util.update_timestamp(
                    timestamp_next_pkt, pps) + float(time_steps.random())
                new_pkt.time = timestamp_next_pkt

            self.packets.append(new_pkt)

        exploit_raw_packets.close()