MembersMgmtCommAttack.py 5.4 KB

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