123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- from random import randint
- from collections import deque
- from Attack import BaseAttack
- from Attack.AttackParameters import Parameter as Param
- from Attack.AttackParameters import ParameterTypes
- from ID2TLib import IPPacketGenerator as IPPktGen, FileUtils
- from ID2TLib.IPGenerator import MappingIPGenerator
- class MembersMgmtCommAttack(BaseAttack.BaseAttack):
- def __init__(self):
- """
- Creates a new instance of the Membership Management Communication.
- """
- # Initialize communication
- super(MembersMgmtCommAttack, self).__init__("Membership Management Communication Attack (MembersMgmtCommAttack)",
- "Injects Membership Management Communication", "Botnet communication")
- # Define allowed parameters and their type
- self.supported_params = {
- # parameters regarding attack
- Param.INJECT_AT_TIMESTAMP: ParameterTypes.TYPE_FLOAT,
- Param.INJECT_AFTER_PACKET: ParameterTypes.TYPE_PACKET_POSITION,
- Param.PACKETS_PER_SECOND: ParameterTypes.TYPE_FLOAT,
- Param.PACKETS_LIMIT: ParameterTypes.TYPE_INTEGER_POSITIVE,
- Param.ATTACK_DURATION: ParameterTypes.TYPE_INTEGER_POSITIVE,
- # use num_attackers to specify number of communicating devices?
- Param.NUMBER_ATTACKERS: ParameterTypes.TYPE_INTEGER_POSITIVE,
- # input file containing botnet communication
- Param.FILE_CSV: ParameterTypes.TYPE_FILEPATH,
- Param.FILE_XML: ParameterTypes.TYPE_FILEPATH
- }
- def init_params(self):
- """
- Initialize some parameters of this communication-attack using the user supplied command line parameters.
- The remaining parameters are implicitly set in the provided data file. Note: the timestamps in the file
- have to be sorted in ascending order
- :param statistics: Reference to a statistics object.
- """
- # set class constants
- self.MESSAGE_TYPES = {2: "SALITY", 3: "TIMEOUT"}
- self.DEFAULT_XML_PATH = "resources/MembersMgmtComm_example.xml"
- # PARAMETERS: initialize with default values
- # (values are overwritten if user specifies them)
- self.add_param_value(Param.INJECT_AFTER_PACKET, randint(0, self.statistics.get_packet_count()))
- self.add_param_value(Param.PACKETS_PER_SECOND, 0)
- self.add_param_value(Param.FILE_XML, self.DEFAULT_XML_PATH)
-
- def generate_attack_pcap(self):
- filepath_xml = self.get_param_value(Param.FILE_XML)
- filepath_csv = self.get_param_value(Param.FILE_CSV)
- # prefer XML input over CSV input
- if filepath_csv and filepath_xml == self.DEFAULT_XML_PATH:
- filepath_xml = FileUtils.parse_csv_to_xml(filepath_csv)
- comm_entries = FileUtils.parse_xml(filepath_xml)
- # Setup initial parameters for packet creation
- BUFFER_SIZE = 1000
- id_to_ip_mapper = MappingIPGenerator()
- file_timestamp_prv = float(comm_entries[0]["Time"])
- pcap_timestamp = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
- duration = 0
- packets = deque(maxlen=BUFFER_SIZE)
- total_pkts = 0
- limit_packetcount = self.get_param_value(Param.PACKETS_LIMIT)
- limit_duration = self.get_param_value(Param.ATTACK_DURATION)
- path_attack_pcap = None
- # create packets to write to pcap file
- for entry in comm_entries:
- # map/retrieve ip addresses to ids from input file
- ip_src = id_to_ip_mapper.get_mapped_ip(entry["Src"])
- ip_dst = id_to_ip_mapper.get_mapped_ip(entry["Dst"])
-
- # update timestamps and duration
- file_timestamp = float(entry["Time"])
- file_time_delta = file_timestamp - file_timestamp_prv
- pcap_timestamp += file_time_delta
- duration += file_time_delta
- file_timestamp_prv = file_timestamp
- # if total number of packets has been sent or the attack duration has been exceeded, stop
- if ((limit_packetcount is not None and total_pkts >= limit_packetcount) or
- (limit_duration is not None and duration >= limit_duration)):
- break
-
- # create ip packet and add to packets list
- message_type = self.MESSAGE_TYPES[int(entry["Type"])]
- packet = IPPktGen.generate_ip_packet(ip_src=ip_src, ip_dst=ip_dst, payload=message_type)
- packet.time = pcap_timestamp
- packets.append(packet)
- total_pkts += 1
- # Store timestamp of first packet (for attack label)
- if total_pkts <= 1 :
- self.attack_start_utime = packets[0].time
- elif total_pkts % BUFFER_SIZE == 0: # every 1000 packets write them to the pcap file (append)
- last_packet = packets[-1]
- packets = list(packets)
- path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
- packets = deque(maxlen=BUFFER_SIZE)
- if len(packets) > 0:
- packets = list(packets)
- path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
- last_packet = packets[-1]
- # Store timestamp of last packet
- self.attack_end_utime = last_packet.time
- # Return packets sorted by packet by timestamp and total number of packets (sent)
- return total_pkts , path_attack_pcap
|