Implementation for an Issue #118

This commit is contained in:
Miroslav Stampar 2012-07-24 15:34:50 +02:00
parent 42f518b2d6
commit f8c9868cb6
11 changed files with 39 additions and 29 deletions

View File

@ -855,7 +855,7 @@ class Agent:
return re.sub("(%s.*?%s)" % (PAYLOAD_DELIMITER, PAYLOAD_DELIMITER), ("%s%s%s" % (PAYLOAD_DELIMITER, payload, PAYLOAD_DELIMITER)).replace("\\", r"\\"), inpStr) if inpStr else inpStr return re.sub("(%s.*?%s)" % (PAYLOAD_DELIMITER, PAYLOAD_DELIMITER), ("%s%s%s" % (PAYLOAD_DELIMITER, payload, PAYLOAD_DELIMITER)).replace("\\", r"\\"), inpStr) if inpStr else inpStr
def runAsDBMSUser(self, query): def runAsDBMSUser(self, query):
if conf.dCred and "Ad Hoc Distributed Queries" not in query: if conf.dbmsCred and "Ad Hoc Distributed Queries" not in query:
query = getSQLSnippet(DBMS.MSSQL, "run_statement_as_user", USER=conf.dbmsUsername, PASSWORD=conf.dbmsPassword, STATEMENT=query.replace("'", "''")) query = getSQLSnippet(DBMS.MSSQL, "run_statement_as_user", USER=conf.dbmsUsername, PASSWORD=conf.dbmsPassword, STATEMENT=query.replace("'", "''"))
return query return query

View File

@ -3211,11 +3211,11 @@ def resetCookieJar(cookieJar):
Cleans cookies from a given cookie jar Cleans cookies from a given cookie jar
""" """
if not conf.loC: if not conf.loadCookies:
cookieJar.clear() cookieJar.clear()
else: else:
try: try:
cookieJar.load(conf.loC) cookieJar.load(conf.loadCookies)
cookieJar.clear_expired_cookies() cookieJar.clear_expired_cookies()
except cookielib.LoadError, msg: except cookielib.LoadError, msg:
errMsg = "there was a problem loading " errMsg = "there was a problem loading "

View File

@ -150,7 +150,7 @@ def __urllib2Opener():
handlers = [proxyHandler, authHandler, redirectHandler, rangeHandler, httpsHandler] handlers = [proxyHandler, authHandler, redirectHandler, rangeHandler, httpsHandler]
if not conf.dropSetCookie: if not conf.dropSetCookie:
if not conf.loC: if not conf.loadCookies:
conf.cj = cookielib.CookieJar() conf.cj = cookielib.CookieJar()
else: else:
conf.cj = cookielib.MozillaCookieJar() conf.cj = cookielib.MozillaCookieJar()
@ -562,13 +562,13 @@ def __setDBMSAuthentication():
another user, not the session user another user, not the session user
""" """
if not conf.dCred: if not conf.dbmsCred:
return return
debugMsg = "setting the DBMS authentication credentials" debugMsg = "setting the DBMS authentication credentials"
logger.debug(debugMsg) logger.debug(debugMsg)
match = re.search("^(.+?):(.*?)$", conf.dCred) match = re.search("^(.+?):(.*?)$", conf.dbmsCred)
if not match: if not match:
errMsg = "DBMS authentication credentials value must be in format " errMsg = "DBMS authentication credentials value must be in format "
@ -1730,7 +1730,7 @@ def __setTrafficOutputFP():
conf.trafficFP = openFile(conf.trafficFile, "w+") conf.trafficFP = openFile(conf.trafficFile, "w+")
def __setDNSServer(): def __setDNSServer():
if not conf.dName: if not conf.dnsName:
return return
infoMsg = "setting up DNS server instance" infoMsg = "setting up DNS server instance"
@ -1944,9 +1944,9 @@ def __basicOptionValidation():
errMsg += "supported charsets" errMsg += "supported charsets"
raise sqlmapSyntaxException, errMsg raise sqlmapSyntaxException, errMsg
if conf.loC: if conf.loadCookies:
if not os.path.exists(conf.loC): if not os.path.exists(conf.loadCookies):
errMsg = "cookies file '%s' does not exist" % conf.loC errMsg = "cookies file '%s' does not exist" % conf.loadCookies
raise sqlmapFilePathException, errMsg raise sqlmapFilePathException, errMsg
def __resolveCrossReferences(): def __resolveCrossReferences():

View File

@ -24,7 +24,7 @@ optDict = {
"data": "string", "data": "string",
"pDel": "string", "pDel": "string",
"cookie": "string", "cookie": "string",
"loC": "string", "loadCookies": "string",
"cookieUrlencode": "boolean", "cookieUrlencode": "boolean",
"dropSetCookie": "boolean", "dropSetCookie": "boolean",
"agent": "string", "agent": "string",
@ -87,7 +87,7 @@ optDict = {
"timeSec": "integer", "timeSec": "integer",
"uCols": "string", "uCols": "string",
"uChar": "string", "uChar": "string",
"dName": "string" "dnsName": "string"
}, },
"Fingerprint": { "Fingerprint": {
@ -171,7 +171,7 @@ optDict = {
"checkTor": "boolean", "checkTor": "boolean",
"crawlDepth": "integer", "crawlDepth": "integer",
"csvDel": "string", "csvDel": "string",
"dCred": "string", "dbmsCred": "string",
"eta": "boolean", "eta": "boolean",
"flushSession": "boolean", "flushSession": "boolean",
"forms": "boolean", "forms": "boolean",

View File

@ -76,7 +76,7 @@ def cmdLineParser():
request.add_option("--cookie", dest="cookie", request.add_option("--cookie", dest="cookie",
help="HTTP Cookie header") help="HTTP Cookie header")
request.add_option("--load-cookies", dest="loC", request.add_option("--load-cookies", dest="loadCookies",
help="File containing cookies in Netscape/wget format") help="File containing cookies in Netscape/wget format")
request.add_option("--cookie-urlencode", dest="cookieUrlencode", request.add_option("--cookie-urlencode", dest="cookieUrlencode",
@ -280,7 +280,7 @@ def cmdLineParser():
techniques.add_option("--union-char", dest="uChar", techniques.add_option("--union-char", dest="uChar",
help="Character to use for bruteforcing number of columns") help="Character to use for bruteforcing number of columns")
techniques.add_option("--dns-domain", dest="dName", techniques.add_option("--dns-domain", dest="dnsName",
help="Domain name used for DNS exfiltration attack") help="Domain name used for DNS exfiltration attack")
# Fingerprint options # Fingerprint options
@ -533,7 +533,7 @@ def cmdLineParser():
help="Delimiting character used in CSV output " help="Delimiting character used in CSV output "
"(default \"%s\")" % defaults.csvDel) "(default \"%s\")" % defaults.csvDel)
general.add_option("--dbms-cred", dest="dCred", general.add_option("--dbms-cred", dest="dbmsCred",
help="DBMS authentication credentials (user:password)") help="DBMS authentication credentials (user:password)")
general.add_option("--eta", dest="eta", general.add_option("--eta", dest="eta",
@ -674,6 +674,16 @@ def cmdLineParser():
parser.add_option_group(general) parser.add_option_group(general)
parser.add_option_group(miscellaneous) parser.add_option_group(miscellaneous)
# Dirty hack to display longer options without breaking into two lines
def _(self, *args):
_ = parser.formatter._format_option_strings(*args)
if len(_) > 18:
_ = "%.16s.." % _
return _
parser.formatter._format_option_strings = parser.formatter.format_option_strings
parser.formatter.format_option_strings = type(parser.formatter.format_option_strings)(_, parser, type(parser))
# Dirty hack for making a short option -hh # Dirty hack for making a short option -hh
option = parser.get_option("--hh") option = parser.get_option("--hh")
option._short_opts = ["-hh"] option._short_opts = ["-hh"]

View File

@ -57,7 +57,7 @@ from lib.techniques.union.use import unionUse
def __goDns(payload, expression): def __goDns(payload, expression):
value = None value = None
if conf.dName and kb.dnsTest is not False: if conf.dnsName and kb.dnsTest is not False:
if kb.dnsTest is None: if kb.dnsTest is None:
dnsTest(payload) dnsTest(payload)

View File

@ -142,7 +142,7 @@ class Abstraction(Web, UDF, xp_cmdshell):
self.runCmd(command) self.runCmd(command)
def __initRunAs(self): def __initRunAs(self):
if not conf.dCred: if not conf.dbmsCred:
return return
if not conf.direct and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED): if not conf.direct and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
@ -186,7 +186,7 @@ class Abstraction(Web, UDF, xp_cmdshell):
warnMsg = "functionality requested probably does not work because " warnMsg = "functionality requested probably does not work because "
warnMsg += "the curent session user is not a database administrator" warnMsg += "the curent session user is not a database administrator"
if not conf.dCred and Backend.getIdentifiedDbms() in ( DBMS.MSSQL, DBMS.PGSQL ): if not conf.dbmsCred and Backend.getIdentifiedDbms() in ( DBMS.MSSQL, DBMS.PGSQL ):
warnMsg += ". You can try to use option '--dbms-cred' " warnMsg += ". You can try to use option '--dbms-cred' "
warnMsg += "to execute statements as a DBA user if you " warnMsg += "to execute statements as a DBA user if you "
warnMsg += "were able to extract and crack a DBA " warnMsg += "were able to extract and crack a DBA "

View File

@ -155,7 +155,7 @@ class xp_cmdshell:
# to retrieve it afterwards # to retrieve it afterwards
# NOTE: this does not need to be done when the command is 'del' to # NOTE: this does not need to be done when the command is 'del' to
# delete the temporary file # delete the temporary file
if conf.dCred and insertIntoTable: if conf.dbmsCred and insertIntoTable:
self.tmpFile = "%s/tmpc%s.txt" % (conf.tmpPath, randomStr(lowercase=True)) self.tmpFile = "%s/tmpc%s.txt" % (conf.tmpPath, randomStr(lowercase=True))
cmd = "%s > \"%s\"" % (cmd, self.tmpFile) cmd = "%s > \"%s\"" % (cmd, self.tmpFile)
@ -171,7 +171,7 @@ class xp_cmdshell:
# it does not work unfortunately, BULK INSERT needs to be used to # it does not work unfortunately, BULK INSERT needs to be used to
# retrieve the output when OPENROWSET is used hence the redirection # retrieve the output when OPENROWSET is used hence the redirection
# to a temporary file from above # to a temporary file from above
if insertIntoTable and not conf.dCred: if insertIntoTable and not conf.dbmsCred:
self.__forgedCmd += "INSERT INTO %s " % insertIntoTable self.__forgedCmd += "INSERT INTO %s " % insertIntoTable
self.__forgedCmd += "EXEC %s @%s" % (self.xpCmdshellStr, self.__randStr) self.__forgedCmd += "EXEC %s @%s" % (self.xpCmdshellStr, self.__randStr)
@ -203,7 +203,7 @@ class xp_cmdshell:
# command standard output is redirected to a temporary file # command standard output is redirected to a temporary file
# The file needs to be copied to the support table, # The file needs to be copied to the support table,
# 'sqlmapoutput' # 'sqlmapoutput'
if conf.dCred: if conf.dbmsCred:
inject.goStacked("BULK INSERT %s FROM '%s' WITH (CODEPAGE='RAW', FIELDTERMINATOR='%s', ROWTERMINATOR='%s')" % (self.cmdTblName, self.tmpFile, randomStr(10), randomStr(10))) inject.goStacked("BULK INSERT %s FROM '%s' WITH (CODEPAGE='RAW', FIELDTERMINATOR='%s', ROWTERMINATOR='%s')" % (self.cmdTblName, self.tmpFile, randomStr(10), randomStr(10)))
self.delRemoteFile(self.tmpFile) self.delRemoteFile(self.tmpFile)

View File

@ -24,7 +24,7 @@ def dnsTest(payload):
errMsg = "data retrieval through DNS channel failed. Turning off DNS exfiltration support" errMsg = "data retrieval through DNS channel failed. Turning off DNS exfiltration support"
logger.error(errMsg) logger.error(errMsg)
conf.dName = None conf.dnsName = None
else: else:
infoMsg = "data retrieval through DNS channel was successful" infoMsg = "data retrieval through DNS channel was successful"
logger.info(infoMsg) logger.info(infoMsg)

View File

@ -48,7 +48,7 @@ def dnsUse(payload, expression):
count = 0 count = 0
offset = 1 offset = 1
if conf.dName and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.ORACLE, DBMS.MYSQL, DBMS.PGSQL): if conf.dnsName and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.ORACLE, DBMS.MYSQL, DBMS.PGSQL):
output = hashDBRetrieve(expression, checkConf=True) output = hashDBRetrieve(expression, checkConf=True)
if output and PARTIAL_VALUE_MARKER in output or kb.dnsTest is None: if output and PARTIAL_VALUE_MARKER in output or kb.dnsTest is None:
@ -67,7 +67,7 @@ def dnsUse(payload, expression):
nulledCastedField = agent.hexConvertField(nulledCastedField) nulledCastedField = agent.hexConvertField(nulledCastedField)
expressionReplaced = expression.replace(fieldToCastStr, nulledCastedField, 1) expressionReplaced = expression.replace(fieldToCastStr, nulledCastedField, 1)
expressionRequest = getSQLSnippet(Backend.getIdentifiedDbms(), "dns_request", PREFIX=prefix, QUERY=expressionReplaced, SUFFIX=suffix, DOMAIN=conf.dName) expressionRequest = getSQLSnippet(Backend.getIdentifiedDbms(), "dns_request", PREFIX=prefix, QUERY=expressionReplaced, SUFFIX=suffix, DOMAIN=conf.dnsName)
expressionUnescaped = unescaper.unescape(expressionRequest) expressionUnescaped = unescaper.unescape(expressionRequest)
if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.PGSQL): if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.PGSQL):
@ -108,7 +108,7 @@ def dnsUse(payload, expression):
debugMsg = "performed %d queries in %d seconds" % (count, calculateDeltaSeconds(start)) debugMsg = "performed %d queries in %d seconds" % (count, calculateDeltaSeconds(start))
logger.debug(debugMsg) logger.debug(debugMsg)
elif conf.dName: elif conf.dnsName:
warnMsg = "DNS data exfiltration method through SQL injection " warnMsg = "DNS data exfiltration method through SQL injection "
warnMsg += "is currently not available for DBMS %s" % Backend.getIdentifiedDbms() warnMsg += "is currently not available for DBMS %s" % Backend.getIdentifiedDbms()
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)

View File

@ -43,7 +43,7 @@ pDel =
cookie = cookie =
# File containing cookies in Netscape/wget format # File containing cookies in Netscape/wget format
loC = loadCookies =
# URL-encode generated cookie injections. # URL-encode generated cookie injections.
# Valid: True or False # Valid: True or False
@ -303,7 +303,7 @@ uChar =
# Domain name used for DNS exfiltration attack # Domain name used for DNS exfiltration attack
# Valid: string # Valid: string
dName = dnsName =
[Fingerprint] [Fingerprint]
@ -584,7 +584,7 @@ csvDel = ,
# vulnerable by stacked queries SQL injection or you are connecting directly # vulnerable by stacked queries SQL injection or you are connecting directly
# to the DBMS (-d switch). # to the DBMS (-d switch).
# Syntax: username:password # Syntax: username:password
dCred = dbmsCred =
# Retrieve each query output length and calculate the estimated time of # Retrieve each query output length and calculate the estimated time of
# arrival in real time. # arrival in real time.