mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-22 17:46:37 +03:00
Implementation for an Issue #363
This commit is contained in:
parent
231ea51fe6
commit
e7b93b5b66
|
@ -85,6 +85,24 @@ def checkSqlInjection(place, parameter, value):
|
||||||
if kb.endDetection:
|
if kb.endDetection:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
if conf.dbms is None:
|
||||||
|
if not injection.dbms and PAYLOAD.TECHNIQUE.BOOLEAN in injection.data:
|
||||||
|
if not Backend.getIdentifiedDbms() and not kb.heuristicDbms:
|
||||||
|
kb.heuristicDbms = heuristicCheckDbms(injection) or UNKNOWN_DBMS
|
||||||
|
|
||||||
|
if not conf.testFilter and (Backend.getErrorParsedDBMSes() or kb.heuristicDbms) not in ([], None, UNKNOWN_DBMS):
|
||||||
|
if kb.reduceTests is None and Backend.getErrorParsedDBMSes():
|
||||||
|
msg = "heuristic (parsing) test showed that the "
|
||||||
|
msg += "back-end DBMS could be '%s'. " % (Format.getErrorParsedDBMSes() if Backend.getErrorParsedDBMSes() else kb.heuristicDbms)
|
||||||
|
msg += "Do you want to skip test payloads specific for other DBMSes? [Y/n]"
|
||||||
|
kb.reduceTests = [] if readInput(msg, default='Y').upper() != 'Y' else (Backend.getErrorParsedDBMSes() or [kb.heuristicDbms])
|
||||||
|
|
||||||
|
if kb.extendTests is None:
|
||||||
|
_ = (Format.getErrorParsedDBMSes() if Backend.getErrorParsedDBMSes() else kb.heuristicDbms)
|
||||||
|
msg = "do you want to include all tests for '%s' " % _
|
||||||
|
msg += "ignoring provided level (%d) and risk (%s)? [Y/n]" % (conf.level, conf.risk)
|
||||||
|
kb.extendTests = [] if readInput(msg, default='Y').upper() != 'Y' else (Backend.getErrorParsedDBMSes() or [kb.heuristicDbms])
|
||||||
|
|
||||||
title = test.title
|
title = test.title
|
||||||
stype = test.stype
|
stype = test.stype
|
||||||
clause = test.clause
|
clause = test.clause
|
||||||
|
@ -143,15 +161,24 @@ def checkSqlInjection(place, parameter, value):
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
# Skip DBMS-specific test if it does not match either the
|
||||||
|
# previously identified or the user's provided DBMS (either
|
||||||
|
# from program switch or from parsed error message(s))
|
||||||
|
if "details" in test and "dbms" in test.details:
|
||||||
|
dbms = test.details.dbms
|
||||||
|
else:
|
||||||
|
dbms = None
|
||||||
|
|
||||||
# Skip tests if title is not included by the given filter
|
# Skip tests if title is not included by the given filter
|
||||||
if conf.testFilter:
|
if conf.testFilter:
|
||||||
if not any(re.search(conf.testFilter, str(item), re.I) for item in (test.title, test.vector,\
|
if not any(re.search(conf.testFilter, str(item), re.I) for item in (test.title, test.vector, dbms)):
|
||||||
test.details.dbms if "details" in test and "dbms" in test.details else "")):
|
|
||||||
debugMsg = "skipping test '%s' because " % title
|
debugMsg = "skipping test '%s' because " % title
|
||||||
debugMsg += "its name/vector/dbms is not included by the given filter"
|
debugMsg += "its name/vector/dbms is not included by the given filter"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
continue
|
continue
|
||||||
else:
|
|
||||||
|
if not (kb.extendTests and intersect(dbms, kb.extendTests)):
|
||||||
# Skip test if the risk is higher than the provided (or default)
|
# Skip test if the risk is higher than the provided (or default)
|
||||||
# value
|
# value
|
||||||
# Parse test's <risk>
|
# Parse test's <risk>
|
||||||
|
@ -170,14 +197,6 @@ def checkSqlInjection(place, parameter, value):
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Skip DBMS-specific test if it does not match either the
|
|
||||||
# previously identified or the user's provided DBMS (either
|
|
||||||
# from program switch or from parsed error message(s))
|
|
||||||
if "details" in test and "dbms" in test.details:
|
|
||||||
dbms = test.details.dbms
|
|
||||||
else:
|
|
||||||
dbms = None
|
|
||||||
|
|
||||||
if dbms is not None:
|
if dbms is not None:
|
||||||
if injection.dbms is not None and not intersect(injection.dbms, dbms):
|
if injection.dbms is not None and not intersect(injection.dbms, dbms):
|
||||||
debugMsg = "skipping test '%s' because " % title
|
debugMsg = "skipping test '%s' because " % title
|
||||||
|
@ -192,17 +211,7 @@ def checkSqlInjection(place, parameter, value):
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if conf.dbms is None and len(Backend.getErrorParsedDBMSes()) > 0 and not intersect(dbms, Backend.getErrorParsedDBMSes()) and kb.skipOthersDbms is None:
|
if kb.reduceTests and not intersect(dbms, kb.reduceTests):
|
||||||
msg = "parsed error message(s) showed that the "
|
|
||||||
msg += "back-end DBMS could be %s. " % Format.getErrorParsedDBMSes()
|
|
||||||
msg += "Do you want to skip test payloads specific for other DBMSes? [Y/n]"
|
|
||||||
|
|
||||||
if readInput(msg, default="Y") in ("y", "Y"):
|
|
||||||
kb.skipOthersDbms = Backend.getErrorParsedDBMSes()
|
|
||||||
else:
|
|
||||||
kb.skipOthersDbms = []
|
|
||||||
|
|
||||||
if kb.skipOthersDbms and not intersect(dbms, kb.skipOthersDbms):
|
|
||||||
debugMsg = "skipping test '%s' because " % title
|
debugMsg = "skipping test '%s' because " % title
|
||||||
debugMsg += "the parsed error message(s) showed "
|
debugMsg += "the parsed error message(s) showed "
|
||||||
debugMsg += "that the back-end DBMS could be "
|
debugMsg += "that the back-end DBMS could be "
|
||||||
|
@ -549,20 +558,12 @@ def checkSqlInjection(place, parameter, value):
|
||||||
# Reset forced back-end DBMS value
|
# Reset forced back-end DBMS value
|
||||||
Backend.flushForcedDbms()
|
Backend.flushForcedDbms()
|
||||||
|
|
||||||
if len(injection.data) == 1 and PAYLOAD.TECHNIQUE.BOOLEAN in injection.data:
|
|
||||||
if not Backend.getIdentifiedDbms() and kb.heuristicDbms in (None, UNKNOWN_DBMS):
|
|
||||||
kb.heuristicDbms = heuristicCheckDbms(injection) or UNKNOWN_DBMS
|
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() or kb.heuristicDbms not in (None, UNKNOWN_DBMS):
|
|
||||||
#do you want to extend <- one time question!!!!!!!!!! (mirek)
|
|
||||||
pass
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
warnMsg = "user aborted during detection phase"
|
warnMsg = "user aborted during detection phase"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
message = "How do you want to proceed? [(S)kip current test/(e)nd detection phase/(n)ext parameter/(q)uit]"
|
msg = "How do you want to proceed? [(S)kip current test/(e)nd detection phase/(n)ext parameter/(q)uit]"
|
||||||
choice = readInput(message, default="S", checkBatch=False)
|
choice = readInput(msg, default="S", checkBatch=False)
|
||||||
|
|
||||||
if choice[0] in ("s", "S"):
|
if choice[0] in ("s", "S"):
|
||||||
pass
|
pass
|
||||||
|
@ -615,7 +616,7 @@ def heuristicCheckDbms(injection):
|
||||||
kb.injection = popValue()
|
kb.injection = popValue()
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
infoMsg = "heuristic test showed that the back-end DBMS "
|
infoMsg = "heuristic (extended) test shows that the back-end DBMS " # not as important as "parsing" counter-part (because of false-positives)
|
||||||
infoMsg += "could be '%s' " % retVal
|
infoMsg += "could be '%s' " % retVal
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -729,7 +730,7 @@ def heuristicCheckSqlInjection(place, parameter):
|
||||||
parseFilePaths(page)
|
parseFilePaths(page)
|
||||||
result = wasLastResponseDBMSError()
|
result = wasLastResponseDBMSError()
|
||||||
|
|
||||||
infoMsg = "heuristic test shows that %s " % place
|
infoMsg = "heuristic (parsing) test shows that %s " % place
|
||||||
infoMsg += "parameter '%s' might " % parameter
|
infoMsg += "parameter '%s' might " % parameter
|
||||||
|
|
||||||
def _(page):
|
def _(page):
|
||||||
|
@ -762,7 +763,7 @@ def heuristicCheckSqlInjection(place, parameter):
|
||||||
kb.ignoreCasted = readInput(message, default='Y' if conf.multipleTargets else 'N').upper() != 'N'
|
kb.ignoreCasted = readInput(message, default='Y' if conf.multipleTargets else 'N').upper() != 'N'
|
||||||
|
|
||||||
elif result:
|
elif result:
|
||||||
infoMsg += "be injectable (possible DBMS: %s)" % (Format.getErrorParsedDBMSes() or UNKNOWN_DBMS)
|
infoMsg += "be injectable (possible DBMS: '%s')" % (Format.getErrorParsedDBMSes() or UNKNOWN_DBMS)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1525,6 +1525,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||||
kb.dynamicParameter = False
|
kb.dynamicParameter = False
|
||||||
kb.endDetection = False
|
kb.endDetection = False
|
||||||
kb.explicitSettings = set()
|
kb.explicitSettings = set()
|
||||||
|
kb.extendTests = None
|
||||||
kb.errorIsNone = True
|
kb.errorIsNone = True
|
||||||
kb.fileReadMode = False
|
kb.fileReadMode = False
|
||||||
kb.forcedDbms = None
|
kb.forcedDbms = None
|
||||||
|
@ -1552,12 +1553,6 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||||
kb.multiThreadMode = False
|
kb.multiThreadMode = False
|
||||||
kb.negativeLogic = False
|
kb.negativeLogic = False
|
||||||
kb.nullConnection = None
|
kb.nullConnection = None
|
||||||
kb.pageCompress = True
|
|
||||||
kb.pageTemplate = None
|
|
||||||
kb.pageTemplates = dict()
|
|
||||||
kb.postHint = None
|
|
||||||
kb.previousMethod = None
|
|
||||||
kb.processUserMarks = None
|
|
||||||
kb.orderByColumns = None
|
kb.orderByColumns = None
|
||||||
kb.originalCode = None
|
kb.originalCode = None
|
||||||
kb.originalPage = None
|
kb.originalPage = None
|
||||||
|
@ -1570,12 +1565,19 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||||
kb.osVersion = None
|
kb.osVersion = None
|
||||||
kb.osSP = None
|
kb.osSP = None
|
||||||
|
|
||||||
|
kb.pageCompress = True
|
||||||
|
kb.pageTemplate = None
|
||||||
|
kb.pageTemplates = dict()
|
||||||
kb.pageEncoding = DEFAULT_PAGE_ENCODING
|
kb.pageEncoding = DEFAULT_PAGE_ENCODING
|
||||||
kb.pageStable = None
|
kb.pageStable = None
|
||||||
kb.partRun = None
|
kb.partRun = None
|
||||||
kb.permissionFlag = False
|
kb.permissionFlag = False
|
||||||
|
kb.postHint = None
|
||||||
|
kb.postSpaceToPlus = False
|
||||||
kb.prependFlag = False
|
kb.prependFlag = False
|
||||||
kb.processResponseCounter = 0
|
kb.processResponseCounter = 0
|
||||||
|
kb.previousMethod = None
|
||||||
|
kb.processUserMarks = None
|
||||||
kb.proxyAuthHeader = None
|
kb.proxyAuthHeader = None
|
||||||
kb.queryCounter = 0
|
kb.queryCounter = 0
|
||||||
kb.redirectChoice = None
|
kb.redirectChoice = None
|
||||||
|
@ -1588,8 +1590,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||||
kb.resumeValues = True
|
kb.resumeValues = True
|
||||||
kb.safeCharEncode = False
|
kb.safeCharEncode = False
|
||||||
kb.singleLogFlags = set()
|
kb.singleLogFlags = set()
|
||||||
kb.skipOthersDbms = None
|
kb.reduceTests = None
|
||||||
kb.postSpaceToPlus = False
|
|
||||||
kb.stickyDBMS = False
|
kb.stickyDBMS = False
|
||||||
kb.stickyLevel = None
|
kb.stickyLevel = None
|
||||||
kb.suppressResumeInfo = False
|
kb.suppressResumeInfo = False
|
||||||
|
|
|
@ -466,7 +466,7 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100
|
||||||
CHECK_ZERO_COLUMNS_THRESHOLD = 10
|
CHECK_ZERO_COLUMNS_THRESHOLD = 10
|
||||||
|
|
||||||
# Boldify all logger messages containing these "patterns"
|
# Boldify all logger messages containing these "patterns"
|
||||||
BOLD_PATTERNS = ("' injectable", "might be injectable", "' is vulnerable", "is not injectable", "test failed", "test passed", "live test final result", "heuristic test showed")
|
BOLD_PATTERNS = ("' injectable", "might be injectable", "' is vulnerable", "is not injectable", "test failed", "test passed", "live test final result", "test shows that")
|
||||||
|
|
||||||
# Generic www root directory names
|
# Generic www root directory names
|
||||||
GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "wwwroot", "www")
|
GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "wwwroot", "www")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user