mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-01-24 08:14:24 +03:00
Implementation for an Issue #377
This commit is contained in:
parent
e150316d97
commit
194a9e7b88
|
@ -22,6 +22,7 @@ from lib.core.common import extractTextTagContent
|
||||||
from lib.core.common import findDynamicContent
|
from lib.core.common import findDynamicContent
|
||||||
from lib.core.common import Format
|
from lib.core.common import Format
|
||||||
from lib.core.common import getLastRequestHTTPError
|
from lib.core.common import getLastRequestHTTPError
|
||||||
|
from lib.core.common import getPublicTypeMembers
|
||||||
from lib.core.common import getSortedInjectionTests
|
from lib.core.common import getSortedInjectionTests
|
||||||
from lib.core.common import getUnicode
|
from lib.core.common import getUnicode
|
||||||
from lib.core.common import intersect
|
from lib.core.common import intersect
|
||||||
|
@ -42,6 +43,8 @@ from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.core.datatype import AttribDict
|
from lib.core.datatype import AttribDict
|
||||||
from lib.core.datatype import InjectionDict
|
from lib.core.datatype import InjectionDict
|
||||||
|
from lib.core.dicts import FROM_DUMMY_TABLE
|
||||||
|
from lib.core.enums import DBMS
|
||||||
from lib.core.enums import HEURISTIC_TEST
|
from lib.core.enums import HEURISTIC_TEST
|
||||||
from lib.core.enums import HTTPHEADER
|
from lib.core.enums import HTTPHEADER
|
||||||
from lib.core.enums import HTTPMETHOD
|
from lib.core.enums import HTTPMETHOD
|
||||||
|
@ -55,7 +58,7 @@ from lib.core.exception import SqlmapUserQuitException
|
||||||
from lib.core.settings import FORMAT_EXCEPTION_STRINGS
|
from lib.core.settings import FORMAT_EXCEPTION_STRINGS
|
||||||
from lib.core.settings import HEURISTIC_CHECK_ALPHABET
|
from lib.core.settings import HEURISTIC_CHECK_ALPHABET
|
||||||
from lib.core.settings import SUHOSIN_MAX_VALUE_LENGTH
|
from lib.core.settings import SUHOSIN_MAX_VALUE_LENGTH
|
||||||
from lib.core.settings import UNKNOWN_DBMS_VERSION
|
from lib.core.settings import UNKNOWN_DBMS
|
||||||
from lib.core.settings import LOWER_RATIO_BOUND
|
from lib.core.settings import LOWER_RATIO_BOUND
|
||||||
from lib.core.settings import UPPER_RATIO_BOUND
|
from lib.core.settings import UPPER_RATIO_BOUND
|
||||||
from lib.core.settings import IDS_WAF_CHECK_PAYLOAD
|
from lib.core.settings import IDS_WAF_CHECK_PAYLOAD
|
||||||
|
@ -441,11 +444,21 @@ def checkSqlInjection(place, parameter, value):
|
||||||
configUnion(test.request.char, test.request.columns)
|
configUnion(test.request.char, test.request.columns)
|
||||||
|
|
||||||
if not Backend.getIdentifiedDbms():
|
if not Backend.getIdentifiedDbms():
|
||||||
warnMsg = "using unescaped version of the test "
|
if not kb.heuristicDbms:
|
||||||
warnMsg += "because of zero knowledge of the "
|
kb.heuristicDbms = heuristicCheckDbms(injection) or UNKNOWN_DBMS
|
||||||
warnMsg += "back-end DBMS. You can try to "
|
|
||||||
warnMsg += "explicitly set it using option '--dbms'"
|
if kb.heuristicDbms == UNKNOWN_DBMS:
|
||||||
singleTimeWarnMessage(warnMsg)
|
warnMsg = "using unescaped version of the test "
|
||||||
|
warnMsg += "because of zero knowledge of the "
|
||||||
|
warnMsg += "back-end DBMS. You can try to "
|
||||||
|
warnMsg += "explicitly set it using option '--dbms'"
|
||||||
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
else:
|
||||||
|
warnMsg = "heuristic test showed that the back-end DBMS "
|
||||||
|
warnMsg += "could be '%s' " % kb.heuristicDbms
|
||||||
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
|
||||||
|
Backend.forceDbms(kb.heuristicDbms)
|
||||||
|
|
||||||
if unionExtended:
|
if unionExtended:
|
||||||
infoMsg = "automatically extending ranges "
|
infoMsg = "automatically extending ranges "
|
||||||
|
@ -582,6 +595,27 @@ def checkSqlInjection(place, parameter, value):
|
||||||
|
|
||||||
return injection
|
return injection
|
||||||
|
|
||||||
|
def heuristicCheckDbms(injection):
|
||||||
|
retVal = None
|
||||||
|
|
||||||
|
if not Backend.getIdentifiedDbms() and len(injection.data) == 1 and PAYLOAD.TECHNIQUE.BOOLEAN in injection.data:
|
||||||
|
pushValue(kb.injection)
|
||||||
|
kb.injection = injection
|
||||||
|
randStr1, randStr2 = randomStr(), randomStr()
|
||||||
|
|
||||||
|
for dbms in getPublicTypeMembers(DBMS, True):
|
||||||
|
Backend.forceDbms(dbms)
|
||||||
|
|
||||||
|
if checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr1)):
|
||||||
|
if not checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr2)):
|
||||||
|
retVal = dbms
|
||||||
|
break
|
||||||
|
|
||||||
|
Backend.flushForcedDbms()
|
||||||
|
kb.injection = popValue()
|
||||||
|
|
||||||
|
return retVal
|
||||||
|
|
||||||
def checkFalsePositives(injection):
|
def checkFalsePositives(injection):
|
||||||
"""
|
"""
|
||||||
Checks for false positives (only in single special cases)
|
Checks for false positives (only in single special cases)
|
||||||
|
@ -723,7 +757,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_VERSION)
|
infoMsg += "be injectable (possible DBMS: %s)" % (Format.getErrorParsedDBMSes() or UNKNOWN_DBMS)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -122,6 +122,7 @@ from lib.core.settings import SUPPORTED_DBMS
|
||||||
from lib.core.settings import TEXT_TAG_REGEX
|
from lib.core.settings import TEXT_TAG_REGEX
|
||||||
from lib.core.settings import TIME_STDEV_COEFF
|
from lib.core.settings import TIME_STDEV_COEFF
|
||||||
from lib.core.settings import UNICODE_ENCODING
|
from lib.core.settings import UNICODE_ENCODING
|
||||||
|
from lib.core.settings import UNKNOWN_DBMS
|
||||||
from lib.core.settings import UNKNOWN_DBMS_VERSION
|
from lib.core.settings import UNKNOWN_DBMS_VERSION
|
||||||
from lib.core.settings import URI_QUESTION_MARKER
|
from lib.core.settings import URI_QUESTION_MARKER
|
||||||
from lib.core.settings import URLENCODE_CHAR_LIMIT
|
from lib.core.settings import URLENCODE_CHAR_LIMIT
|
||||||
|
|
|
@ -1526,6 +1526,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||||
kb.fileReadMode = False
|
kb.fileReadMode = False
|
||||||
kb.forcedDbms = None
|
kb.forcedDbms = None
|
||||||
kb.headersFp = {}
|
kb.headersFp = {}
|
||||||
|
kb.heuristicDbms = None
|
||||||
kb.heuristicTest = None
|
kb.heuristicTest = None
|
||||||
kb.hintValue = None
|
kb.hintValue = None
|
||||||
kb.htmlFp = []
|
kb.htmlFp = []
|
||||||
|
|
|
@ -111,6 +111,9 @@ INFERENCE_EQUALS_CHAR = "="
|
||||||
# Character used for operation "not-equals" in inference
|
# Character used for operation "not-equals" in inference
|
||||||
INFERENCE_NOT_EQUALS_CHAR = "!="
|
INFERENCE_NOT_EQUALS_CHAR = "!="
|
||||||
|
|
||||||
|
# String used for representation of unknown dbms
|
||||||
|
UNKNOWN_DBMS = "Unknown"
|
||||||
|
|
||||||
# String used for representation of unknown dbms version
|
# String used for representation of unknown dbms version
|
||||||
UNKNOWN_DBMS_VERSION = "Unknown"
|
UNKNOWN_DBMS_VERSION = "Unknown"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user