MemcrashedSpooferAttack.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import logging
  2. import random as rnd
  3. import typing
  4. import scapy.layers.inet as inet
  5. import Attack.AttackParameters as atkParam
  6. import Attack.BaseAttack as BaseAttack
  7. import ID2TLib.Utility as Util
  8. import ID2TLib.Memcached as Memcd
  9. logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
  10. class MemcrashedSpooferAttack(BaseAttack.BaseAttack):
  11. def __init__(self):
  12. """
  13. Creates a new instance of the "Memcrashed" Memcached amplification attack.
  14. """
  15. # Initialize attack
  16. super(MemcrashedSpooferAttack, self).__init__("Memcrashed Attack (Spoofer side)",
  17. "Injects the spoofer-side of a Memcached amplification attack",
  18. "Resource Exhaustion")
  19. # Define allowed parameters and their type
  20. self.supported_params.update({
  21. atkParam.Parameter.IP_SOURCE: atkParam.ParameterTypes.TYPE_IP_ADDRESS,
  22. atkParam.Parameter.MAC_SOURCE: atkParam.ParameterTypes.TYPE_MAC_ADDRESS,
  23. atkParam.Parameter.IP_DESTINATION: atkParam.ParameterTypes.TYPE_IP_ADDRESS,
  24. atkParam.Parameter.MAC_DESTINATION: atkParam.ParameterTypes.TYPE_MAC_ADDRESS,
  25. atkParam.Parameter.IP_VICTIM: atkParam.ParameterTypes.TYPE_IP_ADDRESS,
  26. atkParam.Parameter.INJECT_AT_TIMESTAMP: atkParam.ParameterTypes.TYPE_FLOAT,
  27. atkParam.Parameter.INJECT_AFTER_PACKET: atkParam.ParameterTypes.TYPE_PACKET_POSITION,
  28. atkParam.Parameter.PACKETS_PER_SECOND: atkParam.ParameterTypes.TYPE_FLOAT,
  29. atkParam.Parameter.ATTACK_DURATION: atkParam.ParameterTypes.TYPE_INTEGER_POSITIVE
  30. })
  31. def init_params(self) -> None:
  32. """
  33. Initialize the parameters of this attack using the user supplied command line parameters.
  34. Use the provided statistics to calculate default parameters and to process user
  35. supplied queries.
  36. """
  37. # By default, the most used IP is the attacker
  38. most_used_ip = self.statistics.get_most_used_ip_address()
  39. self.add_param_value(atkParam.Parameter.IP_SOURCE, most_used_ip)
  40. self.add_param_value(atkParam.Parameter.MAC_SOURCE, self.statistics.get_mac_address(most_used_ip))
  41. # Target (i.e. amplifier) is a random public IP
  42. self.add_param_value(atkParam.Parameter.IP_DESTINATION, self.generate_random_ipv4_address('A'))
  43. self.add_param_value(atkParam.Parameter.MAC_DESTINATION, self.generate_random_mac_address())
  44. # IP of the victim which is supposed to get hit by the amplified attack
  45. self.add_param_value(atkParam.Parameter.IP_VICTIM, self.generate_random_ipv4_address('A'))
  46. self.add_param_value(atkParam.Parameter.PACKETS_PER_SECOND, (self.statistics.get_pps_sent(most_used_ip) +
  47. self.statistics.get_pps_received(most_used_ip)) / 2)
  48. self.add_param_value(atkParam.Parameter.ATTACK_DURATION, rnd.randint(5, 30))
  49. self.add_param_value(atkParam.Parameter.INJECT_AFTER_PACKET, rnd.randint(0, self.statistics.get_packet_count()))
  50. def generate_attack_packets(self) -> None:
  51. ip_attacker = self.get_param_value(atkParam.Parameter.IP_SOURCE)
  52. mac_attacker = self.get_param_value(atkParam.Parameter.MAC_SOURCE)
  53. ip_amplifier = self.get_param_value(atkParam.Parameter.IP_DESTINATION)
  54. mac_amplifier = self.get_param_value(atkParam.Parameter.MAC_DESTINATION)
  55. ip_victim = self.get_param_value(atkParam.Parameter.IP_VICTIM)
  56. pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND)
  57. timestamp_next_pkt = self.get_param_value(atkParam.Parameter.INJECT_AT_TIMESTAMP)
  58. self.attack_start_utime = timestamp_next_pkt
  59. attack_duration = self.get_param_value(atkParam.Parameter.ATTACK_DURATION)
  60. attack_ends_time = timestamp_next_pkt + attack_duration
  61. _, src_ttl, _ = self.get_ip_data(ip_attacker)
  62. sport = Util.generate_source_port_from_platform('linux')
  63. # Use MAC of the actual source, but the IP of the victim
  64. attacker_ether = inet.Ether(src=mac_attacker, dst=mac_amplifier)
  65. attacker_ip = inet.IP(src=ip_victim, dst=ip_amplifier, ttl=src_ttl, flags='DF')
  66. while timestamp_next_pkt <= attack_ends_time:
  67. request_udp = inet.UDP(sport=sport, dport=Memcd.memcached_port)
  68. request_memcd = Memcd.Memcached_Request(Request=b'stats\r\n', RequestID=inet.RandShort())
  69. request = (attacker_ether / attacker_ip / request_udp / request_memcd)
  70. request.time = timestamp_next_pkt
  71. self.packets.append(request)
  72. timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps)
  73. def generate_attack_pcap(self) -> typing.Tuple[int, str]:
  74. # store end time of attack
  75. self.attack_end_utime = self.packets[-1].time
  76. # write attack packets to pcap
  77. pcap_path = self.write_attack_pcap(self.packets)
  78. # return packet count and path
  79. return len(self.packets), pcap_path