SMBScanAttack.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. import functools as ft
  2. import logging
  3. import random as rnd
  4. import scapy.layers.inet as inet
  5. from scapy.layers.smb import *
  6. import Attack.AttackParameters as atkParam
  7. import Attack.BaseAttack as BaseAttack
  8. import ID2TLib.SMB2 as SMB2
  9. import ID2TLib.SMBLib as SMBLib
  10. import ID2TLib.Utility as Util
  11. logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
  12. # noinspection PyPep8
  13. class SMBScanAttack(BaseAttack.BaseAttack):
  14. def __init__(self):
  15. """
  16. Creates a new instance of the SMBScanAttack.
  17. This Attack injects TCP Syn Requests to the port 445 of several ips and related response into the output
  18. pcap file.
  19. If port 445 is open, it will simulate and inject the SMB Protocol Negotiation too.
  20. """
  21. # Initialize attack
  22. super(SMBScanAttack, self).__init__("SmbScan Attack", "Injects an SMB scan",
  23. "Scanning/Probing")
  24. self.host_os = Util.get_rnd_os()
  25. # Define allowed parameters and their type
  26. self.supported_params.update({
  27. atkParam.Parameter.IP_SOURCE: atkParam.ParameterTypes.TYPE_IP_ADDRESS,
  28. atkParam.Parameter.IP_DESTINATION: atkParam.ParameterTypes.TYPE_IP_ADDRESS,
  29. atkParam.Parameter.TARGET_COUNT: atkParam.ParameterTypes.TYPE_INTEGER_POSITIVE,
  30. atkParam.Parameter.HOSTING_PERCENTAGE: atkParam.ParameterTypes.TYPE_PERCENTAGE,
  31. atkParam.Parameter.PORT_SOURCE: atkParam.ParameterTypes.TYPE_PORT,
  32. atkParam.Parameter.MAC_SOURCE: atkParam.ParameterTypes.TYPE_MAC_ADDRESS,
  33. atkParam.Parameter.INJECT_AT_TIMESTAMP: atkParam.ParameterTypes.TYPE_FLOAT,
  34. atkParam.Parameter.INJECT_AFTER_PACKET: atkParam.ParameterTypes.TYPE_PACKET_POSITION,
  35. atkParam.Parameter.IP_SOURCE_RANDOMIZE: atkParam.ParameterTypes.TYPE_BOOLEAN,
  36. atkParam.Parameter.PACKET_LIMIT_PER_SECOND: atkParam.ParameterTypes.TYPE_FLOAT,
  37. atkParam.Parameter.INJECT_PPS: atkParam.ParameterTypes.TYPE_FLOAT,
  38. atkParam.Parameter.PORT_SOURCE_RANDOMIZE: atkParam.ParameterTypes.TYPE_BOOLEAN,
  39. atkParam.Parameter.HOSTING_IP: atkParam.ParameterTypes.TYPE_IP_ADDRESS,
  40. atkParam.Parameter.HOSTING_VERSION: atkParam.ParameterTypes.TYPE_STRING,
  41. atkParam.Parameter.SOURCE_PLATFORM: atkParam.ParameterTypes.TYPE_STRING,
  42. atkParam.Parameter.PROTOCOL_VERSION: atkParam.ParameterTypes.TYPE_STRING
  43. })
  44. def init_params(self):
  45. """
  46. Initialize the parameters of this attack using the user supplied command line parameters.
  47. Use the provided statistics to calculate default parameters and to process user
  48. supplied queries.
  49. """
  50. # PARAMETERS: initialize with default values
  51. # (values are overwritten if user specifies them)
  52. most_used_ip_address = self.statistics.get_most_used_ip_address()
  53. self.add_param_value(atkParam.Parameter.TARGET_COUNT, 200)
  54. self.add_param_value(atkParam.Parameter.IP_SOURCE, most_used_ip_address)
  55. self.add_param_value(atkParam.Parameter.IP_SOURCE_RANDOMIZE, 'False')
  56. self.add_param_value(atkParam.Parameter.MAC_SOURCE, ft.partial(self.statistics.get_mac_address,
  57. most_used_ip_address))
  58. self.add_param_value(atkParam.Parameter.PORT_SOURCE, ft.partial(rnd.randint, 1024, 65535))
  59. self.add_param_value(atkParam.Parameter.PORT_SOURCE_RANDOMIZE, 'True')
  60. self.add_param_value(atkParam.Parameter.PACKET_LIMIT_PER_SECOND,
  61. (self.statistics.get_pps_sent(most_used_ip_address) +
  62. self.statistics.get_pps_received(most_used_ip_address)) / 2)
  63. def packet():
  64. return rnd.randint(0, self.statistics.get_packet_count())
  65. self.add_param_value(atkParam.Parameter.INJECT_AFTER_PACKET, packet)
  66. def median_timestamp():
  67. start = Util.get_timestamp_from_datetime_str(self.statistics.get_pcap_timestamp_start())
  68. end = Util.get_timestamp_from_datetime_str(self.statistics.get_pcap_timestamp_end())
  69. return (start + end) / 2
  70. self.add_param_value(atkParam.Parameter.INJECT_AT_TIMESTAMP, median_timestamp)
  71. self.add_param_value(atkParam.Parameter.INJECT_PPS, 0)
  72. self.add_param_value(atkParam.Parameter.HOSTING_PERCENTAGE, 0.5)
  73. self.add_param_value(atkParam.Parameter.HOSTING_VERSION, ft.partial(SMBLib.get_smb_version,
  74. platform=self.host_os))
  75. self.add_param_value(atkParam.Parameter.SOURCE_PLATFORM, Util.get_rnd_os)
  76. self.add_param_value(atkParam.Parameter.PROTOCOL_VERSION, "1")
  77. # Check smb version
  78. smb_version = self.get_param_value(atkParam.Parameter.PROTOCOL_VERSION)
  79. print(smb_version)
  80. if not SMBLib.is_valid_version(smb_version):
  81. exit(1)
  82. hosting_version = self.get_param_value(atkParam.Parameter.HOSTING_VERSION)
  83. print(hosting_version)
  84. if not SMBLib.is_valid_version(hosting_version):
  85. exit(1)
  86. ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE)
  87. dest_ip_count = self.get_param_value(atkParam.Parameter.TARGET_COUNT)
  88. ip_addr_count = self.statistics.get_ip_address_count()
  89. if ip_addr_count < dest_ip_count + 1:
  90. dest_ip_count = ip_addr_count
  91. # Check for user defined target IP addresses
  92. ip_destinations = self.get_param_value(atkParam.Parameter.IP_DESTINATION)
  93. if isinstance(ip_destinations, list):
  94. dest_ip_count = dest_ip_count - len(ip_destinations)
  95. elif ip_destinations is not None:
  96. dest_ip_count = dest_ip_count - 1
  97. ip_destinations = [ip_destinations]
  98. else:
  99. ip_destinations = []
  100. # Take random targets from pcap
  101. rnd_ips = self.statistics.get_random_ip_address(dest_ip_count)
  102. if not isinstance(rnd_ips, list):
  103. rnd_ips = [rnd_ips]
  104. ip_destinations = ip_destinations + rnd_ips
  105. # Make sure the source IP is not part of targets
  106. if ip_source in ip_destinations and isinstance(ip_destinations, list):
  107. ip_destinations.remove(ip_source)
  108. self.add_param_value(atkParam.Parameter.IP_DESTINATION, ip_destinations)
  109. # Calculate the amount of IP addresses which are hosting SMB
  110. host_percentage = self.get_param_value(atkParam.Parameter.HOSTING_PERCENTAGE)
  111. rnd_ip_count = len(ip_destinations) * host_percentage
  112. # Check for user defined IP addresses which are hosting SMB
  113. hosting_ip = self.get_param_value(atkParam.Parameter.HOSTING_IP)
  114. if isinstance(hosting_ip, list):
  115. rnd_ip_count = rnd_ip_count - len(hosting_ip)
  116. elif hosting_ip is not None:
  117. rnd_ip_count = rnd_ip_count - 1
  118. hosting_ip = [hosting_ip]
  119. else:
  120. hosting_ip = []
  121. hosting_ip = hosting_ip + ip_destinations[:int(rnd_ip_count)]
  122. self.add_param_value(atkParam.Parameter.HOSTING_IP, hosting_ip)
  123. def generate_attack_packets(self):
  124. """
  125. Creates the attack packets.
  126. """
  127. pps = self.get_param_value(atkParam.Parameter.PACKET_LIMIT_PER_SECOND)
  128. # Calculate complement packet rates of the background traffic for each interval
  129. complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
  130. # Timestamp
  131. timestamp_next_pkt = self.get_param_value(atkParam.Parameter.INJECT_AT_TIMESTAMP)
  132. # store start time of attack
  133. self.attack_start_utime = timestamp_next_pkt
  134. timestamp_prv_reply, timestamp_confirm = 0, 0
  135. # Initialize parameters
  136. ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE)
  137. ip_destinations = self.get_param_value(atkParam.Parameter.IP_DESTINATION)
  138. if not isinstance(ip_destinations, list):
  139. ip_destinations = [ip_destinations]
  140. hosting_ip = self.get_param_value(atkParam.Parameter.HOSTING_IP)
  141. # Get smb version
  142. smb_version = self.get_param_value(atkParam.Parameter.PROTOCOL_VERSION)
  143. hosting_version = self.get_param_value(atkParam.Parameter.HOSTING_VERSION)
  144. # Shuffle targets
  145. rnd.shuffle(ip_destinations)
  146. # FIXME: Handle mac addresses correctly
  147. mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE)
  148. mac_dest = self.get_param_value(atkParam.Parameter.MAC_DESTINATION)
  149. # Check source platform
  150. src_platform = self.get_param_value(atkParam.Parameter.SOURCE_PLATFORM).lower()
  151. self.packets = []
  152. # randomize source ports according to platform, if specified
  153. if self.get_param_value(atkParam.Parameter.PORT_SOURCE_RANDOMIZE):
  154. sport = Util.generate_source_port_from_platform(src_platform)
  155. else:
  156. sport = self.get_param_value(atkParam.Parameter.PORT_SOURCE)
  157. # No destination IP was specified, but a destination MAC was specified, generate IP that fits MAC
  158. if isinstance(ip_destinations, list) and isinstance(mac_dest, str):
  159. ip_destinations = self.statistics.get_ip_address_from_mac(mac_dest)
  160. if len(ip_destinations) == 0:
  161. ip_destinations = self.generate_random_ipv4_address("Unknown", 1)
  162. # Check ip.src == ip.dst
  163. self.ip_src_dst_equal_check(ip_source, ip_destinations)
  164. ip_dests = []
  165. if isinstance(ip_destinations, list):
  166. ip_dests = ip_destinations
  167. else:
  168. ip_dests.append(ip_destinations)
  169. if isinstance(ip_dests, list):
  170. rnd.shuffle(ip_dests)
  171. # Randomize source IP, if specified
  172. if self.get_param_value(atkParam.Parameter.IP_SOURCE_RANDOMIZE):
  173. ip_source = self.generate_random_ipv4_address("Unknown", 1)
  174. while ip_source in ip_dests:
  175. ip_source = self.generate_random_ipv4_address("Unknown", 1)
  176. mac_source = self.statistics.get_mac_address(str(ip_source))
  177. if len(mac_source) == 0:
  178. mac_source = self.generate_random_mac_address()
  179. # Get MSS, TTL and Window size value for source IP
  180. source_mss_value, source_ttl_value, source_win_value = self.get_ip_data(ip_source)
  181. mac_dests = self.statistics.get_mac_addresses(ip_dests)
  182. first_timestamp_smb = self.statistics.get_pcap_timestamp_start()[:19]
  183. # get inject pss
  184. inject_pps = self.get_param_value(atkParam.Parameter.INJECT_PPS)
  185. for ip in ip_dests:
  186. if ip != ip_source:
  187. # Get destination Mac Address
  188. mac_destination = ""
  189. if ip in mac_dests.keys():
  190. mac_destination = mac_dests[ip]
  191. if len(mac_destination) == 0:
  192. if isinstance(mac_dest, str):
  193. ip_from_mac = self.statistics.get_ip_address_from_mac(mac_dest)
  194. if len(ip_from_mac) != 0:
  195. ip = ip_from_mac
  196. self.ip_src_dst_equal_check(ip_source, ip)
  197. mac_destination = mac_dest
  198. else:
  199. mac_destination = self.generate_random_mac_address()
  200. # Get MSS, TTL and Window size value for destination IP
  201. destination_mss_value, destination_ttl_value, destination_win_value = self.get_ip_data(ip)
  202. min_delay, max_delay = self.get_reply_delay(ip)
  203. # New connection, new random TCP sequence numbers
  204. attacker_seq = rnd.randint(1000, 50000)
  205. victim_seq = rnd.randint(1000, 50000)
  206. # Randomize source port for each connection if specified
  207. if self.get_param_value(atkParam.Parameter.PORT_SOURCE_RANDOMIZE):
  208. sport = Util.generate_source_port_from_platform(src_platform, sport)
  209. # 1) Build request package
  210. request_ether = inet.Ether(src=mac_source, dst=mac_destination)
  211. request_ip = inet.IP(src=ip_source, dst=ip, ttl=source_ttl_value, flags='DF')
  212. request_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, window=source_win_value, flags='S',
  213. seq=attacker_seq, options=[('MSS', source_mss_value)])
  214. attacker_seq += 1
  215. request = (request_ether / request_ip / request_tcp)
  216. request.time = timestamp_next_pkt
  217. # Append request
  218. self.packets.append(request)
  219. # Update timestamp for next package
  220. timestamp_reply = Util.update_timestamp(timestamp_next_pkt, pps, min_delay, inj_pps=inject_pps,
  221. inj_timestamp=self.attack_start_utime)
  222. while timestamp_reply <= timestamp_prv_reply:
  223. timestamp_reply = Util.update_timestamp(timestamp_prv_reply, pps, min_delay, inj_pps=inject_pps,
  224. inj_timestamp=self.attack_start_utime)
  225. timestamp_prv_reply = timestamp_reply
  226. if ip in hosting_ip:
  227. # 2) Build TCP packages for ip that hosts SMB
  228. # destination sends SYN, ACK
  229. reply_ether = inet.Ether(src=mac_destination, dst=mac_source)
  230. reply_ip = inet.IP(src=ip, dst=ip_source, ttl=destination_ttl_value, flags='DF')
  231. reply_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, seq=victim_seq, ack=attacker_seq,
  232. flags='SA',
  233. window=destination_win_value, options=[('MSS', destination_mss_value)])
  234. victim_seq += 1
  235. reply = (reply_ether / reply_ip / reply_tcp)
  236. reply.time = timestamp_reply
  237. self.packets.append(reply)
  238. # requester confirms, ACK
  239. confirm_ether = request_ether
  240. confirm_ip = request_ip
  241. confirm_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, seq=attacker_seq, ack=victim_seq,
  242. window=source_win_value, flags='A')
  243. confirm = (confirm_ether / confirm_ip / confirm_tcp)
  244. timestamp_confirm = Util.update_timestamp(timestamp_reply, pps, min_delay)
  245. confirm.time = timestamp_confirm
  246. self.packets.append(confirm)
  247. # 3) Build SMB Negotiation packets
  248. smb_mid = rnd.randint(1, 65535)
  249. smb_pid = rnd.randint(1, 65535)
  250. smb_req_tail_arr = []
  251. smb_req_tail_size = 0
  252. # select dialects based on smb version
  253. if smb_version is "1":
  254. smb_req_dialects = SMBLib.smb_dialects[0:6]
  255. else:
  256. smb_req_dialects = SMBLib.smb_dialects
  257. if len(smb_req_dialects) == 0:
  258. smb_req_tail_arr.append(SMBNegociate_Protocol_Request_Tail())
  259. smb_req_tail_size = len(SMBNegociate_Protocol_Request_Tail())
  260. else:
  261. for dia in smb_req_dialects:
  262. smb_req_tail_arr.append(SMBNegociate_Protocol_Request_Tail(BufferData=dia))
  263. smb_req_tail_size += len(SMBNegociate_Protocol_Request_Tail(BufferData=dia))
  264. # Creation of SMB Negotiate Protocol Request packet
  265. smb_req_head = SMBNegociate_Protocol_Request_Header(Flags2=0x2801, PID=smb_pid, MID=smb_mid,
  266. ByteCount=smb_req_tail_size)
  267. smb_req_length = len(smb_req_head) + smb_req_tail_size
  268. smb_req_net_bio = NBTSession(TYPE=0x00, LENGTH=smb_req_length)
  269. smb_req_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, flags='PA', seq=attacker_seq,
  270. ack=victim_seq)
  271. smb_req_ip = inet.IP(src=ip_source, dst=ip, ttl=source_ttl_value)
  272. smb_req_ether = inet.Ether(src=mac_source, dst=mac_destination)
  273. attacker_seq += len(smb_req_net_bio) + len(smb_req_head) + smb_req_tail_size
  274. smb_req_combined = (smb_req_ether / smb_req_ip / smb_req_tcp / smb_req_net_bio / smb_req_head)
  275. for i in range(0, len(smb_req_tail_arr)):
  276. smb_req_combined = smb_req_combined / smb_req_tail_arr[i]
  277. timestamp_smb_req = Util.update_timestamp(timestamp_confirm, pps, min_delay)
  278. smb_req_combined.time = timestamp_smb_req
  279. self.packets.append(smb_req_combined)
  280. # destination confirms SMB request package
  281. reply_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, seq=victim_seq, ack=attacker_seq,
  282. window=destination_win_value, flags='A')
  283. confirm_smb_req = (reply_ether / reply_ip / reply_tcp)
  284. timestamp_reply = Util.update_timestamp(timestamp_smb_req, pps, min_delay)
  285. confirm_smb_req.time = timestamp_reply
  286. self.packets.append(confirm_smb_req)
  287. # smb response package
  288. first_timestamp = time.mktime(time.strptime(first_timestamp_smb, "%Y-%m-%d %H:%M:%S"))
  289. server_guid, security_blob, capabilities, data_size, server_start_time =\
  290. SMBLib.get_smb_platform_data(self.host_os, first_timestamp)
  291. timestamp_smb_rsp = Util.update_timestamp(timestamp_reply, pps, min_delay)
  292. diff = timestamp_smb_rsp - timestamp_smb_req
  293. begin = Util.get_filetime_format(timestamp_smb_req + diff * 0.1)
  294. end = Util.get_filetime_format(timestamp_smb_rsp - diff * 0.1)
  295. system_time = rnd.randint(begin, end)
  296. # Creation of SMB Negotiate Protocol Response packets
  297. if smb_version is not "1" and hosting_version is not "1":
  298. smb_rsp_packet = SMB2.SMB2_SYNC_Header(Flags=1)
  299. smb_rsp_negotiate_body =\
  300. SMB2.SMB2_Negotiate_Protocol_Response(DialectRevision=0x02ff, SecurityBufferOffset=124,
  301. SecurityBufferLength=len(security_blob),
  302. SecurityBlob=security_blob, Capabilities=capabilities,
  303. MaxTransactSize=data_size, MaxReadSize=data_size,
  304. MaxWriteSize=data_size, SystemTime=system_time,
  305. ServerStartTime=server_start_time,
  306. ServerGuid=server_guid)
  307. smb_rsp_length = len(smb_rsp_packet) + len(smb_rsp_negotiate_body)
  308. else:
  309. smb_rsp_packet =\
  310. SMBNegociate_Protocol_Response_Advanced_Security(Start="\xffSMB", PID=smb_pid, MID=smb_mid,
  311. DialectIndex=5, SecurityBlob=security_blob)
  312. smb_rsp_length = len(smb_rsp_packet)
  313. smb_rsp_net_bio = NBTSession(TYPE=0x00, LENGTH=smb_rsp_length)
  314. smb_rsp_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, flags='PA', seq=victim_seq,
  315. ack=attacker_seq)
  316. smb_rsp_ip = inet.IP(src=ip, dst=ip_source, ttl=destination_ttl_value)
  317. smb_rsp_ether = inet.Ether(src=mac_destination, dst=mac_source)
  318. victim_seq += len(smb_rsp_net_bio) + len(smb_rsp_packet)
  319. if smb_version is not "1" and hosting_version is not "1":
  320. victim_seq += len(smb_rsp_negotiate_body)
  321. smb_rsp_combined = (smb_rsp_ether / smb_rsp_ip / smb_rsp_tcp / smb_rsp_net_bio / smb_rsp_packet)
  322. if smb_version is not "1" and hosting_version is not "1":
  323. smb_rsp_combined = (smb_rsp_combined / smb_rsp_negotiate_body)
  324. smb_rsp_combined.time = timestamp_smb_rsp
  325. self.packets.append(smb_rsp_combined)
  326. # source confirms SMB response package
  327. confirm_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, seq=attacker_seq, ack=victim_seq,
  328. window=source_win_value, flags='A')
  329. confirm_smb_res = (confirm_ether / confirm_ip / confirm_tcp)
  330. timestamp_confirm = Util.update_timestamp(timestamp_smb_rsp, pps, min_delay)
  331. confirm_smb_res.time = timestamp_confirm
  332. self.packets.append(confirm_smb_res)
  333. # attacker sends FIN ACK
  334. confirm_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, seq=attacker_seq, ack=victim_seq,
  335. window=source_win_value, flags='FA')
  336. source_fin_ack = (confirm_ether / confirm_ip / confirm_tcp)
  337. timestamp_src_fin_ack = Util.update_timestamp(timestamp_confirm, pps, min_delay)
  338. source_fin_ack.time = timestamp_src_fin_ack
  339. attacker_seq += 1
  340. self.packets.append(source_fin_ack)
  341. # victim sends FIN ACK
  342. reply_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, seq=victim_seq, ack=attacker_seq,
  343. window=destination_win_value, flags='FA')
  344. destination_fin_ack = (reply_ether / reply_ip / reply_tcp)
  345. timestamp_dest_fin_ack = Util.update_timestamp(timestamp_src_fin_ack, pps, min_delay)
  346. victim_seq += 1
  347. destination_fin_ack.time = timestamp_dest_fin_ack
  348. self.packets.append(destination_fin_ack)
  349. # source sends final ACK
  350. confirm_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, seq=attacker_seq, ack=victim_seq,
  351. window=source_win_value, flags='A')
  352. final_ack = (confirm_ether / confirm_ip / confirm_tcp)
  353. timestamp_final_ack = Util.update_timestamp(timestamp_dest_fin_ack, pps, min_delay)
  354. final_ack.time = timestamp_final_ack
  355. self.packets.append(final_ack)
  356. else:
  357. # Build RST package
  358. reply_ether = inet.Ether(src=mac_destination, dst=mac_source)
  359. reply_ip = inet.IP(src=ip, dst=ip_source, ttl=destination_ttl_value, flags='DF')
  360. reply_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, seq=0, ack=attacker_seq, flags='RA',
  361. window=destination_win_value, options=[('MSS', destination_mss_value)])
  362. reply = (reply_ether / reply_ip / reply_tcp)
  363. reply.time = timestamp_reply
  364. self.packets.append(reply)
  365. pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
  366. timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps)
  367. def generate_attack_pcap(self):
  368. """
  369. Creates a pcap containing the attack packets.
  370. :return: The location of the generated pcap file.
  371. """
  372. # store end time of attack
  373. self.attack_end_utime = self.packets[-1].time
  374. # write attack self.packets to pcap
  375. pcap_path = self.write_attack_pcap(sorted(self.packets, key=lambda pkt: pkt.time))
  376. # return packets sorted by packet time_sec_start
  377. return len(self.packets), pcap_path