SalityBotnet.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import logging
  2. import random as rnd
  3. import scapy.layers.inet as inet
  4. import scapy.utils
  5. import Attack.AttackParameters as atkParam
  6. import Attack.BaseAttack as BaseAttack
  7. import ID2TLib.Utility as Util
  8. logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
  9. # noinspection PyPep8
  10. class SalityBotnet(BaseAttack.BaseAttack):
  11. template_attack_pcap_path = Util.RESOURCE_DIR + "/../resources/sality_botnet.pcap"
  12. def __init__(self):
  13. """
  14. Creates a new instance of the Sality botnet.
  15. """
  16. # Initialize attack
  17. super(SalityBotnet, self).__init__("Sality Botnet", "Injects an Sality botnet'",
  18. "Botnet")
  19. self.pkt_num = 0
  20. self.path_attack_pcap = None
  21. # Define allowed parameters and their type
  22. self.supported_params.update({
  23. atkParam.Parameter.MAC_SOURCE: atkParam.ParameterTypes.TYPE_MAC_ADDRESS,
  24. atkParam.Parameter.IP_SOURCE: atkParam.ParameterTypes.TYPE_IP_ADDRESS,
  25. atkParam.Parameter.INJECT_AT_TIMESTAMP: atkParam.ParameterTypes.TYPE_FLOAT,
  26. atkParam.Parameter.INJECT_AFTER_PACKET: atkParam.ParameterTypes.TYPE_PACKET_POSITION,
  27. atkParam.Parameter.PACKETS_PER_SECOND: atkParam.ParameterTypes.TYPE_FLOAT
  28. })
  29. def init_params(self):
  30. """
  31. Initialize the parameters of this attack using the user supplied command line parameters.
  32. Use the provided statistics to calculate default parameters and to process user
  33. supplied queries.
  34. """
  35. # PARAMETERS: initialize with default utilsvalues
  36. # (values are overwritten if user specifies them)
  37. most_used_ip_address = self.statistics.get_most_used_ip_address()
  38. self.add_param_value(atkParam.Parameter.IP_SOURCE, most_used_ip_address)
  39. self.add_param_value(atkParam.Parameter.MAC_SOURCE, self.statistics.get_mac_address(most_used_ip_address))
  40. # Attack configuration
  41. self.add_param_value(atkParam.Parameter.INJECT_AFTER_PACKET, rnd.randint(0, self.statistics.get_packet_count()))
  42. self.add_param_value(atkParam.Parameter.PACKETS_PER_SECOND,
  43. (self.statistics.get_pps_sent(most_used_ip_address) +
  44. self.statistics.get_pps_received(most_used_ip_address)) / 2)
  45. def generate_attack_packets(self):
  46. """
  47. Creates the attack packets.
  48. """
  49. # Timestamp
  50. timestamp_next_pkt = self.get_param_value(atkParam.Parameter.INJECT_AT_TIMESTAMP)
  51. pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND)
  52. # Calculate complement packet rates of BG traffic per interval
  53. complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
  54. # Initialize parameters
  55. self.packets = []
  56. mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE)
  57. ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE)
  58. # Pick a DNS server from the background traffic
  59. ip_dns_server = self.statistics.process_db_query(
  60. "SELECT ipAddress FROM ip_protocols WHERE protocolName='DNS' AND protocolCount=(SELECT MAX(protocolCount) "
  61. "FROM ip_protocols WHERE protocolName='DNS');")
  62. ip_dns_server = Util.handle_most_used_outputs(ip_dns_server)
  63. if not ip_dns_server or ip_source == ip_dns_server:
  64. ip_dns_server = self.statistics.get_random_ip_address()
  65. mac_dns_server = self.statistics.get_mac_address(ip_dns_server)
  66. # Bot original config in the template PCAP
  67. origin_mac_src = "08:00:27:e5:d7:b0"
  68. origin_ip_src = "10.0.2.15"
  69. origin_mac_dns_server = "52:54:00:12:35:02"
  70. origin_ip_dns_server = "10.0.2.2"
  71. ttl_map = {}
  72. ip_map = {origin_ip_src: ip_source, origin_ip_dns_server: ip_dns_server}
  73. mac_map = {origin_mac_src: mac_source, origin_mac_dns_server: mac_dns_server}
  74. # Inject Sality botnet
  75. # Read sality_botnet pcap file
  76. exploit_raw_packets = scapy.utils.RawPcapReader(self.template_attack_pcap_path)
  77. for self.pkt_num, pkt in enumerate(exploit_raw_packets):
  78. eth_frame = inet.Ether(pkt[0])
  79. ip_pkt = eth_frame.payload
  80. # Ether
  81. if eth_frame.getfieldval("src") in mac_map:
  82. eth_frame.setfieldval("src", mac_map[eth_frame.getfieldval("src")])
  83. if eth_frame.getfieldval("dst") in mac_map:
  84. eth_frame.setfieldval("dst", mac_map[eth_frame.getfieldval("dst")])
  85. # IP
  86. if ip_pkt.getfieldval("src") in ip_map:
  87. ip_pkt.setfieldval("src", ip_map[ip_pkt.getfieldval("src")])
  88. if ip_pkt.getfieldval("dst") in ip_map:
  89. ip_pkt.setfieldval("dst", ip_map[ip_pkt.getfieldval("dst")])
  90. # TTL
  91. if ip_pkt.getfieldval("ttl") not in ttl_map:
  92. source_ttl = self.statistics.get_most_used_ttl(ip_pkt.getfieldval("src"))
  93. if not source_ttl:
  94. source_ttl = self.statistics.process_db_query("SELECT ttlValue FROM ip_ttl;")
  95. if isinstance(source_ttl, list):
  96. source_ttl = rnd.choice(source_ttl)
  97. ttl_map[ip_pkt.getfieldval("ttl")] = source_ttl
  98. ip_pkt.setfieldval("ttl", ttl_map[ip_pkt.getfieldval("ttl")])
  99. new_pkt = (eth_frame / ip_pkt)
  100. new_pkt.time = timestamp_next_pkt
  101. pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
  102. timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps)
  103. self.packets.append(new_pkt)
  104. exploit_raw_packets.close()
  105. def generate_attack_pcap(self):
  106. """
  107. Creates a pcap containing the attack packets.
  108. :return: The location of the generated pcap file.
  109. """
  110. # Store timestamp of first packet (for attack label)
  111. self.attack_start_utime = self.packets[0].time
  112. self.attack_end_utime = self.packets[-1].time
  113. if len(self.packets) > 0:
  114. self.packets = sorted(self.packets, key=lambda pkt: pkt.time)
  115. self.path_attack_pcap = self.write_attack_pcap(self.packets, True, self.path_attack_pcap)
  116. # return packets sorted by packet time_sec_start
  117. # pkt_num+1: because pkt_num starts at 0
  118. return self.pkt_num + 1, self.path_attack_pcap