MembersMgmtCommAttack.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. from random import randint
  2. from collections import deque
  3. from Attack import BaseAttack
  4. from Attack.AttackParameters import Parameter as Param
  5. from Attack.AttackParameters import ParameterTypes
  6. from ID2TLib import IPPacketGenerator as IPPktGen, FileUtils
  7. from ID2TLib.IPGenerator import MappingIPGenerator
  8. class MembersMgmtCommAttack(BaseAttack.BaseAttack):
  9. def __init__(self):
  10. """
  11. Creates a new instance of the Membership Management Communication.
  12. """
  13. # Initialize communication
  14. super(MembersMgmtCommAttack, self).__init__("Membership Management Communication Attack (MembersMgmtCommAttack)",
  15. "Injects Membership Management Communication", "Botnet communication")
  16. # Define allowed parameters and their type
  17. self.supported_params = {
  18. # parameters regarding attack
  19. Param.INJECT_AT_TIMESTAMP: ParameterTypes.TYPE_FLOAT,
  20. Param.INJECT_AFTER_PACKET: ParameterTypes.TYPE_PACKET_POSITION,
  21. Param.PACKETS_PER_SECOND: ParameterTypes.TYPE_FLOAT,
  22. Param.PACKETS_LIMIT: ParameterTypes.TYPE_INTEGER_POSITIVE,
  23. Param.ATTACK_DURATION: ParameterTypes.TYPE_INTEGER_POSITIVE,
  24. # use num_attackers to specify number of communicating devices?
  25. Param.NUMBER_ATTACKERS: ParameterTypes.TYPE_INTEGER_POSITIVE,
  26. # input file containing botnet communication
  27. Param.FILE_CSV: ParameterTypes.TYPE_FILEPATH,
  28. Param.FILE_XML: ParameterTypes.TYPE_FILEPATH
  29. }
  30. def init_params(self):
  31. """
  32. Initialize some parameters of this communication-attack using the user supplied command line parameters.
  33. The remaining parameters are implicitly set in the provided data file. Note: the timestamps in the file
  34. have to be sorted in ascending order
  35. :param statistics: Reference to a statistics object.
  36. """
  37. # set class constants
  38. self.MESSAGE_TYPES = {2: "SALITY", 3: "TIMEOUT"}
  39. self.DEFAULT_XML_PATH = "resources/MembersMgmtComm_example.xml"
  40. # PARAMETERS: initialize with default values
  41. # (values are overwritten if user specifies them)
  42. self.add_param_value(Param.INJECT_AFTER_PACKET, randint(0, self.statistics.get_packet_count()))
  43. self.add_param_value(Param.PACKETS_PER_SECOND, 0)
  44. self.add_param_value(Param.FILE_XML, self.DEFAULT_XML_PATH)
  45. def generate_attack_pcap(self):
  46. filepath_xml = self.get_param_value(Param.FILE_XML)
  47. filepath_csv = self.get_param_value(Param.FILE_CSV)
  48. # prefer XML input over CSV input
  49. if filepath_csv and filepath_xml == self.DEFAULT_XML_PATH:
  50. filepath_xml = FileUtils.parse_csv_to_xml(filepath_csv)
  51. comm_entries = FileUtils.parse_xml(filepath_xml)
  52. # Setup initial parameters for packet creation
  53. BUFFER_SIZE = 1000
  54. id_to_ip_mapper = MappingIPGenerator()
  55. file_timestamp_prv = float(comm_entries[0]["Time"])
  56. pcap_timestamp = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
  57. duration = 0
  58. packets = deque(maxlen=BUFFER_SIZE)
  59. total_pkts = 0
  60. limit_packetcount = self.get_param_value(Param.PACKETS_LIMIT)
  61. limit_duration = self.get_param_value(Param.ATTACK_DURATION)
  62. path_attack_pcap = None
  63. # create packets to write to pcap file
  64. for entry in comm_entries:
  65. # map/retrieve ip addresses to ids from input file
  66. ip_src = id_to_ip_mapper.get_mapped_ip(entry["Src"])
  67. ip_dst = id_to_ip_mapper.get_mapped_ip(entry["Dst"])
  68. # update timestamps and duration
  69. file_timestamp = float(entry["Time"])
  70. file_time_delta = file_timestamp - file_timestamp_prv
  71. pcap_timestamp += file_time_delta
  72. duration += file_time_delta
  73. file_timestamp_prv = file_timestamp
  74. # if total number of packets has been sent or the attack duration has been exceeded, stop
  75. if ((limit_packetcount is not None and total_pkts >= limit_packetcount) or
  76. (limit_duration is not None and duration >= limit_duration)):
  77. break
  78. # create ip packet and add to packets list
  79. message_type = self.MESSAGE_TYPES[int(entry["Type"])]
  80. packet = IPPktGen.generate_ip_packet(ip_src=ip_src, ip_dst=ip_dst, payload=message_type)
  81. packet.time = pcap_timestamp
  82. packets.append(packet)
  83. total_pkts += 1
  84. # Store timestamp of first packet (for attack label)
  85. if total_pkts <= 1 :
  86. self.attack_start_utime = packets[0].time
  87. elif total_pkts % BUFFER_SIZE == 0: # every 1000 packets write them to the pcap file (append)
  88. last_packet = packets[-1]
  89. #packets = sorted(packets, key=lambda pkt: pkt.time) # not necessary yet
  90. path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
  91. packets = []
  92. if len(packets) > 0:
  93. #packets = sorted(packets, key=lambda pkt: pkt.time) # not necessary yet
  94. path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
  95. last_packet = packets[-1]
  96. # Store timestamp of last packet
  97. self.attack_end_utime = last_packet.time
  98. # Return packets sorted by packet by timestamp and total number of packets (sent)
  99. return total_pkts , path_attack_pcap