From fe67d3827ce084ea92f2b07a786cc3c99f298a8c Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Sat, 18 Dec 2010 09:51:34 +0000 Subject: [PATCH] code refactoring and some fixes --- lib/controller/checks.py | 8 ++++---- lib/controller/controller.py | 9 --------- lib/core/common.py | 23 +++++++++++++++++++++++ lib/core/option.py | 3 +-- lib/core/session.py | 22 ---------------------- lib/core/settings.py | 2 +- lib/request/comparison.py | 18 +++++++++--------- lib/request/inject.py | 11 ++++++++--- lib/request/templates.py | 4 ++++ lib/techniques/error/use.py | 3 +++ 10 files changed, 53 insertions(+), 50 deletions(-) diff --git a/lib/controller/checks.py b/lib/controller/checks.py index ffd56f9e8..d11095fb3 100644 --- a/lib/controller/checks.py +++ b/lib/controller/checks.py @@ -292,9 +292,9 @@ def checkSqlInjection(place, parameter, value): boundPayload = agent.cleanupPayload(boundPayload, value) cmpPayload = agent.payload(place, parameter, value, boundPayload) - # Useful to set conf.matchRatio at first based on + # Useful to set kb.matchRatio at first based on # the False response content - conf.matchRatio = None + kb.matchRatio = None _ = Request.queryPage(cmpPayload, place) # Perform the test's True request @@ -308,7 +308,6 @@ def checkSqlInjection(place, parameter, value): infoMsg = "%s parameter '%s' is '%s' injectable " % (place, parameter, title) logger.info(infoMsg) - kb.paramMatchRatio[(place, parameter)] = conf.matchRatio injectable = True # In case of error-based or UNION query SQL injections @@ -382,6 +381,7 @@ def checkSqlInjection(place, parameter, value): injection.data[stype].where = where injection.data[stype].vector = vector injection.data[stype].comment = comment + injection.data[stype].matchRatio = kb.matchRatio injection.data[stype].templatePayload = templatePayload if hasattr(test, "details"): @@ -455,7 +455,7 @@ def checkDynParam(place, parameter, value): dynamicity might depend on another parameter. """ - conf.matchRatio = None + kb.matchRatio = None infoMsg = "testing if %s parameter '%s' is dynamic" % (place, parameter) logger.info(infoMsg) diff --git a/lib/controller/controller.py b/lib/controller/controller.py index f699d2cea..2c43ab482 100644 --- a/lib/controller/controller.py +++ b/lib/controller/controller.py @@ -37,7 +37,6 @@ from lib.core.exception import sqlmapSilentQuitException from lib.core.exception import sqlmapValueException from lib.core.exception import sqlmapUserQuitException from lib.core.session import setInjection -from lib.core.session import setMatchRatio from lib.core.target import initTargetEnv from lib.core.target import setupTargetEnv @@ -382,14 +381,6 @@ def start(): condition = True if condition: - if kb.paramMatchRatio: - key = (kb.injection.place, kb.injection.parameter) - if key in kb.paramMatchRatio: - conf.matchRatio = kb.paramMatchRatio[key] - setMatchRatio() - else: - conf.matchRatio = None - action() except KeyboardInterrupt: diff --git a/lib/core/common.py b/lib/core/common.py index dc59a642c..11cbba0ab 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -48,6 +48,7 @@ from lib.core.convert import htmlunescape from lib.core.convert import urlencode from lib.core.enums import DBMS from lib.core.enums import PLACE +from lib.core.enums import PAYLOAD from lib.core.exception import sqlmapFilePathException from lib.core.exception import sqlmapGenericException from lib.core.exception import sqlmapNoneDataException @@ -1652,6 +1653,9 @@ def logHTTPTraffic(requestLogMsg, responseLogMsg): kb.locks.reqLock.release() +def getPageTemplate(payload, place): + pass + def getPublicTypeMembers(type_, onlyValues=False): """ Useful for getting members from types (e.g. in enums) @@ -1667,6 +1671,16 @@ def getPublicTypeMembers(type_, onlyValues=False): return retVal +def enumValueToNameLookup(type_, value_): + retVal = None + + for name, value in getPublicTypeMembers(type_): + if value == value_: + retVal = name + break + + return retVal + def extractRegexResult(regex, content, flags=0): retVal = None @@ -1758,3 +1772,12 @@ def getTechniqueData(technique=None): def isTechniqueAvailable(technique=None): return getTechniqueData(technique) is not None + +def initTechnique(technique=None): + data = getTechniqueData(technique) + if data: + kb.pageTemplate = getPageTemplate(data.templatePayload, kb.injection.place) + kb.matchRatio = data.matchRatio + else: + warnMsg = "there is no injection data available for technique '%s'" % enumValueToNameLookup(PAYLOAD.TECHNIQUE, technique) + logger.warn(warnMsg) diff --git a/lib/core/option.py b/lib/core/option.py index 81f2340f5..1e45b8a15 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -1091,7 +1091,6 @@ def __setConfAttributes(): conf.httpHeaders = [] conf.hostname = None conf.loggedToOut = None - conf.matchRatio = None conf.multipleTargets = False conf.outputPath = None conf.paramDict = {} @@ -1169,6 +1168,7 @@ def __setKnowledgeBaseAttributes(): kb.locks.reqLock = threading.Lock() kb.locks.seqLock = None + kb.matchRatio = None kb.nullConnection = None kb.pageTemplate = None kb.pageTemplates = advancedDict() @@ -1181,7 +1181,6 @@ def __setKnowledgeBaseAttributes(): kb.osSP = None kb.pageStable = None - kb.paramMatchRatio = {} kb.partRun = None kb.proxyAuthHeader = None kb.queryCounter = 0 diff --git a/lib/core/session.py b/lib/core/session.py index 5f0136333..c48b898fc 100644 --- a/lib/core/session.py +++ b/lib/core/session.py @@ -65,17 +65,6 @@ def setRegexp(): if condition: dataToSessionFile("[%s][None][None][Regular expression][%s]\n" % (conf.url, safeFormatString(conf.regexp))) -def setMatchRatio(): - condition = ( - isinstance(conf.matchRatio, (int, float)) - and ( not kb.resumedQueries - or ( kb.resumedQueries.has_key(conf.url) and not - kb.resumedQueries[conf.url].has_key("Match ratio") ) ) - ) - - if condition: - dataToSessionFile("[%s][%s][%s][Match ratio][%s]\n" % (conf.url, kb.injection.place, safeFormatString(conf.parameters[kb.injection.place]), conf.matchRatio)) - def setInjection(inj): """ Save information retrieved about injection place and parameter in the @@ -336,17 +325,6 @@ def resumeConfKb(expression, url, value): if not test or test[0] in ("y", "Y"): conf.regexp = regexp - elif expression == "Match ratio" and url == conf.url and conf.matchRatio is None: - matchRatio = value[:-1] - - logMsg = "resuming match ratio '%s' from session file" % matchRatio - logger.info(logMsg) - - try: - conf.matchRatio = round(float(matchRatio), 3) - except ValueError: - pass - elif expression == "Injection data" and url == conf.url: injection = base64unpickle(value[:-1]) logMsg = "resuming injection data from session file" diff --git a/lib/core/settings.py b/lib/core/settings.py index 52354d941..67315e4f2 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -21,7 +21,7 @@ VERSION_STRING = "sqlmap/%s" % VERSION DESCRIPTION = "automatic SQL injection and database takeover tool" SITE = "http://sqlmap.sourceforge.net" -# minimum distance of ratio from conf.matchRatio to result in True +# minimum distance of ratio from kb.matchRatio to result in True DIFF_TOLERANCE = 0.05 CONSTANT_RATIO = 0.9 diff --git a/lib/request/comparison.py b/lib/request/comparison.py index 80cb00695..40c158060 100644 --- a/lib/request/comparison.py +++ b/lib/request/comparison.py @@ -89,16 +89,16 @@ def comparison(page, headers=None, getSeqMatcher=False, pageLength=None): # If the url is stable and we did not set yet the match ratio and the # current injected value changes the url page content - if conf.matchRatio is None: + if kb.matchRatio is None: if conf.thold: - conf.matchRatio = conf.thold + kb.matchRatio = conf.thold elif kb.pageStable and ratio > 0.6 and ratio < 0.99: - conf.matchRatio = ratio - logger.debug("setting match ratio for current parameter to %.3f" % conf.matchRatio) + kb.matchRatio = ratio + logger.debug("setting match ratio for current parameter to %.3f" % kb.matchRatio) elif not kb.pageStable or ( kb.pageStable and ratio < 0.6 ): - conf.matchRatio = CONSTANT_RATIO + kb.matchRatio = CONSTANT_RATIO logger.debug("setting match ratio for current parameter to default value 0.900") # If it has been requested to return the ratio and not a comparison @@ -109,11 +109,11 @@ def comparison(page, headers=None, getSeqMatcher=False, pageLength=None): elif ratio == 1: return True - elif conf.matchRatio is None: + elif kb.matchRatio is None: return None else: - if conf.matchRatio == CONSTANT_RATIO or conf.thold: - return ratio > conf.matchRatio + if kb.matchRatio == CONSTANT_RATIO or conf.thold: + return ratio > kb.matchRatio else: - return (ratio - conf.matchRatio) > DIFF_TOLERANCE + return (ratio - kb.matchRatio) > DIFF_TOLERANCE diff --git a/lib/request/inject.py b/lib/request/inject.py index a3a8c23b2..e59db2077 100644 --- a/lib/request/inject.py +++ b/lib/request/inject.py @@ -17,6 +17,7 @@ from lib.core.common import dataToSessionFile from lib.core.common import dataToStdout from lib.core.common import expandAsteriskForColumns from lib.core.common import getPublicTypeMembers +from lib.core.common import initTechnique from lib.core.common import isTechniqueAvailable from lib.core.common import parseUnionPage from lib.core.common import popValue @@ -37,7 +38,6 @@ from lib.core.settings import MIN_TIME_RESPONSES from lib.core.unescaper import unescaper from lib.request.connect import Connect as Request from lib.request.direct import direct -from lib.request.templates import getPageTemplate from lib.techniques.inband.union.use import unionUse from lib.techniques.blind.inference import bisection from lib.techniques.error.use import errorUse @@ -99,7 +99,11 @@ def __goInferenceFields(expression, expressionFields, expressionFieldsList, payl return outputs def __goBooleanProxy(expression, resumeValue=True): - kb.pageTemplate = getPageTemplate(kb.injection.data[kb.technique].templatePayload, kb.injection.place) + """ + Retrieve the output of a boolean based SQL query + """ + + initTechnique(kb.technique) vector = kb.injection.data[kb.technique].vector vector = vector.replace("[INFERENCE]", expression) @@ -125,7 +129,8 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r parameter through a bisection algorithm. """ - kb.pageTemplate = getPageTemplate(kb.injection.data[kb.technique].templatePayload, kb.injection.place) + initTechnique(kb.technique) + vector = agent.cleanupPayload(kb.injection.data[kb.technique].vector) query = agent.prefixQuery(vector) query = agent.suffixQuery(query) diff --git a/lib/request/templates.py b/lib/request/templates.py index 789242f45..84bdfc1db 100644 --- a/lib/request/templates.py +++ b/lib/request/templates.py @@ -7,6 +7,8 @@ Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/) See the file 'doc/COPYING' for copying permission """ +import lib.core.common + from lib.core.data import kb from lib.request.connect import Connect as Request @@ -20,3 +22,5 @@ def getPageTemplate(payload, place): retVal = kb.pageTemplates[(payload, place)] return retVal + +lib.core.common.getPageTemplate = getPageTemplate \ No newline at end of file diff --git a/lib/techniques/error/use.py b/lib/techniques/error/use.py index c166ae898..22406aa4d 100644 --- a/lib/techniques/error/use.py +++ b/lib/techniques/error/use.py @@ -13,6 +13,7 @@ import time from lib.core.agent import agent from lib.core.common import extractRegexResult from lib.core.common import getUnicode +from lib.core.common import initTechnique from lib.core.common import randomInt from lib.core.common import replaceNewlineTabs from lib.core.common import safeStringFormat @@ -31,6 +32,8 @@ def errorUse(expression): injection vulnerability on the affected parameter. """ + initTechnique(PAYLOAD.TECHNIQUE.ERROR) + output = None vector = agent.cleanupPayload(kb.injection.data[PAYLOAD.TECHNIQUE.ERROR].vector) query = unescaper.unescape(vector)