Implementation for an Issue #377

This commit is contained in:
Miroslav Stampar 2013-01-25 12:34:57 +01:00
parent e150316d97
commit 194a9e7b88
4 changed files with 46 additions and 7 deletions

View File

@ -22,6 +22,7 @@ from lib.core.common import extractTextTagContent
from lib.core.common import findDynamicContent
from lib.core.common import Format
from lib.core.common import getLastRequestHTTPError
from lib.core.common import getPublicTypeMembers
from lib.core.common import getSortedInjectionTests
from lib.core.common import getUnicode
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.datatype import AttribDict
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 HTTPHEADER
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 HEURISTIC_CHECK_ALPHABET
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 UPPER_RATIO_BOUND
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)
if not Backend.getIdentifiedDbms():
if not kb.heuristicDbms:
kb.heuristicDbms = heuristicCheckDbms(injection) or UNKNOWN_DBMS
if kb.heuristicDbms == UNKNOWN_DBMS:
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:
infoMsg = "automatically extending ranges "
@ -582,6 +595,27 @@ def checkSqlInjection(place, parameter, value):
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):
"""
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'
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)
else:

View File

@ -122,6 +122,7 @@ from lib.core.settings import SUPPORTED_DBMS
from lib.core.settings import TEXT_TAG_REGEX
from lib.core.settings import TIME_STDEV_COEFF
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 URI_QUESTION_MARKER
from lib.core.settings import URLENCODE_CHAR_LIMIT

View File

@ -1526,6 +1526,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.fileReadMode = False
kb.forcedDbms = None
kb.headersFp = {}
kb.heuristicDbms = None
kb.heuristicTest = None
kb.hintValue = None
kb.htmlFp = []

View File

@ -111,6 +111,9 @@ INFERENCE_EQUALS_CHAR = "="
# Character used for operation "not-equals" in inference
INFERENCE_NOT_EQUALS_CHAR = "!="
# String used for representation of unknown dbms
UNKNOWN_DBMS = "Unknown"
# String used for representation of unknown dbms version
UNKNOWN_DBMS_VERSION = "Unknown"