added standard deviation check in time based tests

This commit is contained in:
Miroslav Stampar 2010-12-07 16:39:31 +00:00
parent 294119d2ec
commit ecd4a5a532
4 changed files with 48 additions and 20 deletions

View File

@ -26,6 +26,7 @@ from lib.core.common import randomStr
from lib.core.common import readInput from lib.core.common import readInput
from lib.core.common import removeDynamicContent from lib.core.common import removeDynamicContent
from lib.core.common import showStaticWords from lib.core.common import showStaticWords
from lib.core.common import stdev
from lib.core.common import trimAlphaNum from lib.core.common import trimAlphaNum
from lib.core.common import wasLastRequestDBMSError from lib.core.common import wasLastRequestDBMSError
from lib.core.common import DynamicContentItem from lib.core.common import DynamicContentItem
@ -47,6 +48,7 @@ from lib.core.exception import sqlmapUserQuitException
from lib.core.session import setString from lib.core.session import setString
from lib.core.session import setRegexp from lib.core.session import setRegexp
from lib.core.settings import MIN_DURATION_RATIO from lib.core.settings import MIN_DURATION_RATIO
from lib.core.settings import MAX_TIME_STDEV
from lib.core.settings import TIME_TOLERANCE from lib.core.settings import TIME_TOLERANCE
from lib.request.connect import Connect as Request from lib.request.connect import Connect as Request
from lib.request.templates import getPageTemplate from lib.request.templates import getPageTemplate
@ -343,31 +345,42 @@ def checkSqlInjection(place, parameter, value):
# In case of time-based blind or stacked queries # In case of time-based blind or stacked queries
# SQL injections # SQL injections
elif method == PAYLOAD.METHOD.TIME: elif method == PAYLOAD.METHOD.TIME and kb.timeTests:
# Store old value of socket timeout if stdev(kb.responseTimes) > MAX_TIME_STDEV:
pushValue(socket.getdefaulttimeout()) # the standard deviation tells us how far from the mean
# the data points tend to be. It will have the same units
# as the data points themselves
warnMsg = "loading time(s) of the target url is too "
warnMsg += "chaotic. skipping further time-based tests."
logger.critical(warnMsg)
# Set socket timeout to 2 minutes as some kb.timeTests = False
# time based checks can take awhile else:
socket.setdefaulttimeout(120) # Store old value of socket timeout
pushValue(socket.getdefaulttimeout())
# Perform the test's request and check how long # Set socket timeout to 2 minutes as some
# it takes to get the response back # time based checks can take awhile
start = time.time() socket.setdefaulttimeout(120)
_ = Request.queryPage(reqPayload, place, noteResponseTime = False)
duration = calculateDeltaSeconds(start)
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: # Perform the test's request and check how long
infoMsg = "%s parameter '%s' is '%s' injectable " % (place, parameter, title) # it takes to get the response back
logger.info(infoMsg) start = time.time()
_ = Request.queryPage(reqPayload, place, noteResponseTime = False)
duration = calculateDeltaSeconds(start)
trueResult = duration > max(kb.responseTimes) and ((check.isdigit()\
and abs(duration - int(check) - average(kb.responseTimes)) < TIME_TOLERANCE)\
or (check == "[DELAYED]" and duration >= MIN_DURATION_RATIO * max(kb.responseTimes)))
injectable = True if trueResult:
infoMsg = "%s parameter '%s' is '%s' injectable " % (place, parameter, title)
logger.info(infoMsg)
# Restore value of socket timeout injectable = True
socket.setdefaulttimeout(popValue())
# Restore value of socket timeout
socket.setdefaulttimeout(popValue())
# If the injection test was successful feed the injection # If the injection test was successful feed the injection
# object with the test's details # object with the test's details

View File

@ -27,6 +27,7 @@ from ConfigParser import RawConfigParser
from StringIO import StringIO from StringIO import StringIO
from difflib import SequenceMatcher from difflib import SequenceMatcher
from inspect import getmembers from inspect import getmembers
from math import sqrt
from subprocess import PIPE from subprocess import PIPE
from subprocess import Popen as execute from subprocess import Popen as execute
from tempfile import NamedTemporaryFile from tempfile import NamedTemporaryFile
@ -1276,6 +1277,18 @@ def readXmlFile(xmlFile):
xfile.close() xfile.close()
return retVal return retVal
def stdev(values):
"""
Computes standard deviation of a list of numbers.
"""
sum = 0.0
avg = average(values)
for value in values:
sum += pow(value - avg, 2)
return sqrt(sum/len(values))
def average(values): def average(values):
""" """
Computes the arithmetic mean of a list of numbers. Computes the arithmetic mean of a list of numbers.

View File

@ -1182,6 +1182,7 @@ def __setKnowledgeBaseAttributes():
kb.technique = None kb.technique = None
kb.testMode = False kb.testMode = False
kb.testQueryCount = 0 kb.testQueryCount = 0
kb.timeTests = True
kb.unionComment = "" kb.unionComment = ""
kb.unionCount = None kb.unionCount = None
kb.unionPosition = None kb.unionPosition = None

View File

@ -51,6 +51,7 @@ PAYLOAD_DELIMITER = "\x00"
# time testing settings # time testing settings
TIME_TOLERANCE = 0.5 TIME_TOLERANCE = 0.5
MIN_DURATION_RATIO = 1.5 MIN_DURATION_RATIO = 1.5
MAX_TIME_STDEV = 1
# System variables # System variables
IS_WIN = subprocess.mswindows IS_WIN = subprocess.mswindows