update regarding time based data retrieval

This commit is contained in:
Miroslav Stampar 2011-01-16 17:52:42 +00:00
parent ec1ab3cd2a
commit 30d6791968
6 changed files with 43 additions and 16 deletions

View File

@ -73,6 +73,7 @@ from lib.core.settings import DUMP_TAB_MARKER
from lib.core.settings import DUMP_START_MARKER from lib.core.settings import DUMP_START_MARKER
from lib.core.settings import DUMP_STOP_MARKER from lib.core.settings import DUMP_STOP_MARKER
from lib.core.settings import MIN_TIME_RESPONSES from lib.core.settings import MIN_TIME_RESPONSES
from lib.core.settings import TIME_DEFAULT_DELAY
from lib.core.settings import TIME_STDEV_COEFF from lib.core.settings import TIME_STDEV_COEFF
from lib.core.settings import DYNAMICITY_MARK_LENGTH from lib.core.settings import DYNAMICITY_MARK_LENGTH
from lib.core.threads import getCurrentThreadData from lib.core.threads import getCurrentThreadData
@ -1588,21 +1589,31 @@ def wasLastRequestDelayed():
warnMsg += "with less than %d response times" % MIN_TIME_RESPONSES warnMsg += "with less than %d response times" % MIN_TIME_RESPONSES
logger.warn(warnMsg) logger.warn(warnMsg)
lowerLimit = average(kb.responseTimes) + TIME_STDEV_COEFF * deviation lowerStdLimit = average(kb.responseTimes) + TIME_STDEV_COEFF * deviation
retVal = (threadData.lastQueryDuration >= lowerLimit) retVal = (threadData.lastQueryDuration >= lowerStdLimit)
if not kb.testMode and retVal: if not kb.testMode and retVal and conf.timeSec == TIME_DEFAULT_DELAY:
newVal = int(ceil((1 - (threadData.lastQueryDuration - lowerLimit) / threadData.lastQueryDuration) * conf.timeSec)) adjustTimeDelay(threadData.lastQueryDuration, lowerStdLimit)
if newVal and newVal != conf.timeSec:
clearConsoleLine(True)
warnMsg = "adjusting time delay to %d seconds" % newVal
logger.warn(warnMsg)
conf.timeSec = newVal
return retVal return retVal
else: else:
return threadData.lastQueryDuration - conf.timeSec return threadData.lastQueryDuration - conf.timeSec
def adjustTimeDelay(lastQueryDuration, lowerStdLimit):
"""
Adjusts time delay in time based data retrieval
"""
candidate = 1 + int(ceil((1 - (lastQueryDuration - lowerStdLimit) / lastQueryDuration) * conf.timeSec))
if candidate:
kb.delayCandidates = [candidate] + kb.delayCandidates[:-1]
if all([x == candidate for x in kb.delayCandidates]) and candidate < conf.timeSec:
clearConsoleLine(True)
warnMsg = "adjusting time delay to %d seconds" % candidate
logger.warn(warnMsg)
conf.timeSec = candidate
def extractErrorMessage(page): def extractErrorMessage(page):
""" """
Returns reported error message from page if it founds one Returns reported error message from page if it founds one

View File

@ -77,6 +77,7 @@ from lib.core.settings import FIREBIRD_ALIASES
from lib.core.settings import MAXDB_ALIASES from lib.core.settings import MAXDB_ALIASES
from lib.core.settings import SYBASE_ALIASES from lib.core.settings import SYBASE_ALIASES
from lib.core.settings import UNKNOWN_DBMS_VERSION from lib.core.settings import UNKNOWN_DBMS_VERSION
from lib.core.settings import TIME_DELAY_CANDIDATES
from lib.core.update import update from lib.core.update import update
from lib.parse.configfile import configFileParser from lib.parse.configfile import configFileParser
from lib.parse.payloads import loadPayloads from lib.parse.payloads import loadPayloads
@ -1116,6 +1117,7 @@ def __setKnowledgeBaseAttributes(flushAll=True):
# Active (extensive) back-end DBMS fingerprint # Active (extensive) back-end DBMS fingerprint
kb.dbmsVersion = [ UNKNOWN_DBMS_VERSION ] kb.dbmsVersion = [ UNKNOWN_DBMS_VERSION ]
kb.delayCandidates = TIME_DELAY_CANDIDATES * [0]
kb.dep = None kb.dep = None
kb.docRoot = None kb.docRoot = None
kb.dynamicMarkings = [] kb.dynamicMarkings = []

View File

@ -58,6 +58,12 @@ NON_CONTROL_CHAR_REGEX = r'[^\x00-\x1f]'
# coefficient used for a time-based query delay checking (must be >= 7) # coefficient used for a time-based query delay checking (must be >= 7)
TIME_STDEV_COEFF = 10 TIME_STDEV_COEFF = 10
# length of queue for candidates for time delay adjustment
TIME_DELAY_CANDIDATES = 3
# default time delay in seconds
TIME_DEFAULT_DELAY = 5
# maximum number of techniques used in inject.py/getValue() per one value # maximum number of techniques used in inject.py/getValue() per one value
MAX_TECHNIQUES_PER_VALUE = 2 MAX_TECHNIQUES_PER_VALUE = 2

View File

@ -16,6 +16,7 @@ from optparse import SUPPRESS_HELP
from lib.core.convert import utf8decode from lib.core.convert import utf8decode
from lib.core.data import logger from lib.core.data import logger
from lib.core.settings import TIME_DEFAULT_DELAY
from lib.core.settings import VERSION_STRING from lib.core.settings import VERSION_STRING
def cmdLineParser(): def cmdLineParser():
@ -223,7 +224,7 @@ def cmdLineParser():
"the default blind SQL injection technique.") "the default blind SQL injection technique.")
techniques.add_option("--time-sec", dest="timeSec", techniques.add_option("--time-sec", dest="timeSec",
type="int", default=5, type="int", default=TIME_DEFAULT_DELAY,
help="Seconds to delay the DBMS response " help="Seconds to delay the DBMS response "
"(default 5)") "(default 5)")

View File

@ -49,7 +49,9 @@ from lib.utils.resume import resume
def __goInference(payload, expression, charsetType=None, firstChar=None, lastChar=None): def __goInference(payload, expression, charsetType=None, firstChar=None, lastChar=None):
start = time.time() start = time.time()
if ( conf.eta or conf.threads > 1 ) and getIdentifiedDBMS(): timeBasedCompare = (kb.technique in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED))
if ( conf.eta or conf.threads > 1 ) and getIdentifiedDBMS() and not timeBasedCompare:
_, length, _ = queryOutputLength(expression, payload) _, length, _ = queryOutputLength(expression, payload)
else: else:
length = None length = None

View File

@ -99,8 +99,13 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
progressTime = [] progressTime = []
if numThreads > 1: if numThreads > 1:
if not timeBasedCompare:
debugMsg = "starting %d thread%s" % (numThreads, ("s" if numThreads > 1 else "")) debugMsg = "starting %d thread%s" % (numThreads, ("s" if numThreads > 1 else ""))
logger.debug(debugMsg) logger.debug(debugMsg)
else:
debugMsg = "multi-threading is not considered safe in time-based data retrieval"
logger.debug(debugMsg)
numThreads = 1
if conf.verbose in (1, 2) and not showEta: if conf.verbose in (1, 2) and not showEta:
if isinstance(length, int) and conf.threads > 1: if isinstance(length, int) and conf.threads > 1: