more advanced time technique(s)

This commit is contained in:
Miroslav Stampar 2010-12-07 16:04:53 +00:00
parent 4959da3ce6
commit 294119d2ec
5 changed files with 28 additions and 24 deletions

View File

@ -14,6 +14,7 @@ import time
from difflib import SequenceMatcher
from lib.core.agent import agent
from lib.core.common import average
from lib.core.common import beep
from lib.core.common import calculateDeltaSeconds
from lib.core.common import extractRegexResult
@ -45,7 +46,8 @@ from lib.core.exception import sqlmapSiteTooDynamic
from lib.core.exception import sqlmapUserQuitException
from lib.core.session import setString
from lib.core.session import setRegexp
from lib.core.settings import TIME_MIN_DELTA
from lib.core.settings import MIN_DURATION_RATIO
from lib.core.settings import TIME_TOLERANCE
from lib.request.connect import Connect as Request
from lib.request.templates import getPageTemplate
from plugins.dbms.firebird.syntax import Syntax as Firebird
@ -352,17 +354,11 @@ def checkSqlInjection(place, parameter, value):
# Perform the test's request and check how long
# it takes to get the response back
start = time.time()
_ = Request.queryPage(reqPayload, place)
_ = Request.queryPage(reqPayload, place, noteResponseTime = False)
duration = calculateDeltaSeconds(start)
trueResult = (check.isdigit() and duration >= int(check)) or (check == "[DELAYED]" and duration >= max(TIME_MIN_DELTA, kb.responseTime))
if trueResult:
start = time.time()
_ = Request.queryPage(reqPayload, place)
duration = calculateDeltaSeconds(start)
trueResult = (check.isdigit() and duration >= int(check)) or (check == "[DELAYED]" and duration >= max(TIME_MIN_DELTA, kb.responseTime))
trueResult = (check.isdigit() and abs(duration - int(check) - average(kb.responseTimes)) < TIME_TOLERANCE)\
or (check == "[DELAYED]" and duration >= MIN_DURATION_RATIO * max(kb.responseTimes))
if trueResult:
infoMsg = "%s parameter '%s' is '%s' injectable " % (place, parameter, title)
@ -763,9 +759,7 @@ def checkConnection(suppressOutput=False):
logger.info(infoMsg)
try:
start = time.time()
page, _ = Request.queryPage(content=True)
kb.responseTime = time.time() - start
kb.originalPage = kb.pageTemplate = page
except sqlmapConnectionException, errMsg:
errMsg = getUnicode(errMsg)

View File

@ -1276,12 +1276,17 @@ def readXmlFile(xmlFile):
xfile.close()
return retVal
def calculateDeltaSeconds(start, epsilon=0.1):
def average(values):
"""
Returns elapsed time from start till now (including expected
error set by epsilon parameter)
Computes the arithmetic mean of a list of numbers.
"""
return time.time() - start - kb.responseTime + epsilon
return sum(values, 0.0) / len(values)
def calculateDeltaSeconds(start):
"""
Returns elapsed time from start till now
"""
return time.time() - start
def initCommonOutputs():
kb.commonOutputs = {}

View File

@ -1173,7 +1173,7 @@ def __setKnowledgeBaseAttributes():
kb.proxyAuthHeader = None
kb.queryCounter = 0
kb.redirectSetCookie = None
kb.responseTime = 0
kb.responseTimes = []
kb.resumedQueries = {}
kb.retriesCount = 0
kb.tamperFunctions = []

View File

@ -48,8 +48,9 @@ DUMP_STOP_MARKER = "__STOP__"
PAYLOAD_DELIMITER = "\x00"
# minimum difference of loading time in seconds for delayed time payloads
TIME_MIN_DELTA = 2
# time testing settings
TIME_TOLERANCE = 0.5
MIN_DURATION_RATIO = 1.5
# System variables
IS_WIN = subprocess.mswindows

View File

@ -320,7 +320,7 @@ class Connect:
return page, responseHeaders
@staticmethod
def queryPage(value=None, place=None, content=False, getSeqMatcher=False, silent=False, method=None, auxHeaders=None, response=False, raise404 = None):
def queryPage(value=None, place=None, content=False, getSeqMatcher=False, silent=False, method=None, auxHeaders=None, response=False, raise404 = None, noteResponseTime = True):
"""
This method calls a function to get the target url page content
and returns its page MD5 hash or a boolean value in case of
@ -339,6 +339,7 @@ class Connect:
uri = None
raise404 = place != PLACE.URI if raise404 is None else raise404
toUrlencode = { PLACE.GET: True, PLACE.POST: True, PLACE.COOKIE: conf.cookieUrlencode, PLACE.UA: True, PLACE.URI: False }
start = time.time()
if not place:
place = kb.injection.place
@ -412,6 +413,9 @@ class Connect:
if conf.cj:
conf.cj.clear()
if noteResponseTime:
kb.responseTimes.append(time.time() - start)
if content or response:
return page, headers
elif getSeqMatcher: