AttackController.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import importlib
  2. import os
  3. import tempfile
  4. import sys
  5. from scapy.utils import PcapWriter
  6. from Attack.AttackParameters import Parameter
  7. from ID2TLib import LabelManager
  8. from ID2TLib import Statistics
  9. from ID2TLib.Label import Label
  10. from ID2TLib.PcapFile import PcapFile
  11. class AttackController:
  12. def __init__(self, pcap_file: PcapFile, statistics_class: Statistics, label_manager: LabelManager):
  13. """
  14. Creates a new AttackController. The controller manages the attack injection, including the PCAP writing.
  15. :param statistics_class:
  16. """
  17. self.statistics = statistics_class
  18. self.pcap_file = pcap_file
  19. self.label_mgr = label_manager
  20. self.current_attack = None
  21. self.added_attacks = []
  22. # The PCAP where the attack should be injected into
  23. self.base_pcap = self.statistics.pcap_filepath
  24. def create_attack(self, attack_name: str):
  25. """
  26. Creates dynamically a new class instance based on the given attack_name.
  27. :param attack_name: The name of the attack, must correspond to the attack's class name.
  28. :return: None
  29. """
  30. print("\nCreating attack instance of \033[1m" + attack_name + "\033[0m")
  31. # Load attack class
  32. attack_module = importlib.import_module("Attack." + attack_name)
  33. attack_class = getattr(attack_module, attack_name)
  34. # Set current attack
  35. self.current_attack = attack_class(self.statistics, self.base_pcap)
  36. self.added_attacks.append(self.current_attack)
  37. def process_attack(self, attack: str, params: str):
  38. """
  39. Takes as input the name of an attack (classname) and the attack parameters as string. Parses the string of
  40. attack parameters, creates the attack by writing the attack packets, merges these packets into the existing
  41. dataset and stores the label file of the injected attacks.
  42. :param attack: The classname of the attack to injecect.
  43. :param params: The parameters for attack customization, see attack class for supported params.
  44. :return: The file path to the created pcap file.
  45. """
  46. self.create_attack(attack)
  47. # Add attack parameters if provided
  48. print("Validating and adding attack parameters.")
  49. params_dict = []
  50. if params is not None:
  51. # Convert attack param list into dictionary
  52. for entry in params:
  53. params_dict.append(entry.split('='))
  54. params_dict = dict(params_dict)
  55. # Check if Parameter.INJECT_AT_TIMESTAMP and Parameter.INJECT_AFTER_PACKET are provided at the same time
  56. # if TRUE: delete Paramter.INJECT_AT_TIMESTAMP (lower priority) and use Parameter.INJECT_AFTER_PACKET
  57. if (Parameter.INJECT_AFTER_PACKET.value in params_dict) and (
  58. Parameter.INJECT_AT_TIMESTAMP.value in params_dict):
  59. print("CONFLICT: Parameters", Parameter.INJECT_AT_TIMESTAMP.value, "and",
  60. Parameter.INJECT_AFTER_PACKET.value,
  61. "given at the same time. Ignoring", Parameter.INJECT_AT_TIMESTAMP.value, "and using",
  62. Parameter.INJECT_AFTER_PACKET.value, "instead to derive the timestamp.")
  63. del params_dict[Parameter.INJECT_AT_TIMESTAMP.value]
  64. # Extract attack_note parameter, if not provided returns an empty string
  65. key_attack_note = "attack.note"
  66. attack_note = params_dict.get(key_attack_note, "")
  67. params_dict.pop(key_attack_note, None) # delete entry if found, otherwise return an empty string
  68. # Pass paramters to attack controller
  69. self.set_params(params_dict)
  70. else:
  71. attack_note = ""
  72. # Write attack into pcap file
  73. print("Generating attack packets...", end=" ")
  74. sys.stdout.flush() # force python to print text immediately
  75. total_packets, temp_attack_pcap_path = self.current_attack.generate_attack_pcap()
  76. print("done. (total: " + str(total_packets) + " pkts.)")
  77. # Merge attack with existing pcap
  78. pcap_dest_path = self.pcap_file.merge_attack(temp_attack_pcap_path)
  79. # Delete temporary attack pcap
  80. os.remove(temp_attack_pcap_path)
  81. # Store label into LabelManager
  82. l = Label(attack, self.get_attack_start_utime(),
  83. self.get_attack_end_utime(), attack_note)
  84. self.label_mgr.add_labels(l)
  85. return pcap_dest_path
  86. def get_attack_start_utime(self):
  87. """
  88. :return: The start time (timestamp of first packet) of the attack as unix timestamp.
  89. """
  90. return self.current_attack.attack_start_utime
  91. def get_attack_end_utime(self):
  92. """
  93. :return: The end time (timestamp of last packet) of the attack as unix timestamp.
  94. """
  95. return self.current_attack.attack_end_utime
  96. def set_params(self, params: dict):
  97. """
  98. Sets the attack's parameters.
  99. :param params: The parameters in a dictionary: {parameter_name: parameter_value}
  100. :return: None
  101. """
  102. for param_key, param_value in params.items():
  103. self.current_attack.add_param_value(param_key, param_value)