diff --git a/doc/ChangeLog b/doc/ChangeLog index 8ebecd164..1e7d3e2aa 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,11 @@ +sqlmap (0.6.5-1) stable; urgency=low + + * Major bug fix in the comparison algorithm to correctly handle also the + case that the url is stable and the False response changes the page + content very little. + + -- Bernardo Damele A. G. Day, DD MMM 2009 HH:MM:SS +0000 + sqlmap (0.6.4-1) stable; urgency=low * Major enhancement to make the comparison algorithm work properly also diff --git a/doc/THANKS b/doc/THANKS index b71788c09..142c0799c 100644 --- a/doc/THANKS +++ b/doc/THANKS @@ -58,6 +58,9 @@ Luke Jahnke Anant Kochhar for providing me with feedback on the user's manual +Alexander Kornbrust + for reporting a bug + Nico Leidecker for providing me with feedback on a few features diff --git a/lib/controller/checks.py b/lib/controller/checks.py index 3f60d5913..784ebda6c 100644 --- a/lib/controller/checks.py +++ b/lib/controller/checks.py @@ -31,6 +31,7 @@ from lib.controller.action import action from lib.core.agent import agent from lib.core.common import randomInt from lib.core.common import randomStr +from lib.core.convert import md5hash from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger @@ -296,12 +297,17 @@ def checkStability(): firstPage, firstHeaders = Request.queryPage(content=True) time.sleep(1) - secondPage, secondHeaders = Request.queryPage(content=True) condition = firstPage == secondPage - if condition == False: + if condition == True: + conf.md5hash = md5hash(firstPage) + + logMsg = "url is stable" + logger.info(logMsg) + + elif condition == False: warnMsg = "url is not stable, sqlmap will base the page " warnMsg += "comparison on a sequence matcher, if no dynamic nor " warnMsg += "injectable parameters are detected, refer to user's " @@ -309,10 +315,6 @@ def checkStability(): warnMsg += "string or regular expression to match on" logger.warn(warnMsg) - if condition == True: - logMsg = "url is stable" - logger.info(logMsg) - return condition diff --git a/lib/core/option.py b/lib/core/option.py index eb3c5b0ca..219270c8a 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -600,6 +600,7 @@ def __setConfAttributes(): conf.httpHeaders = [] conf.hostname = None conf.loggedToOut = None + conf.md5hash = None conf.multipleTargets = False conf.outputPath = None conf.paramDict = {} diff --git a/lib/core/settings.py b/lib/core/settings.py index 335eeffce..7e46a2daf 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -30,7 +30,7 @@ import sys # sqlmap version and site -VERSION = "0.6.4" +VERSION = "0.6.5-rc1" VERSION_STRING = "sqlmap/%s" % VERSION SITE = "http://sqlmap.sourceforge.net" @@ -64,15 +64,18 @@ PGSQL_ALIASES = [ "postgresql", "postgres", "pgsql", "psql", "pg" ] ORACLE_ALIASES = [ "oracle", "orcl", "ora", "or" ] SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES +SUPPORTED_OS = ( "linux", "windows" ) # TODO: port to command line/configuration file options? SECONDS = 5 RETRIES = 3 -MATCH_RATIO = 0.9 + +MATCH_RATIO = None SQL_STATEMENTS = { "SQL SELECT statement": ( "select ", + "show ", " top ", " from ", " from dual", diff --git a/lib/request/comparison.py b/lib/request/comparison.py index 90bdcc3d5..d3443ab9b 100644 --- a/lib/request/comparison.py +++ b/lib/request/comparison.py @@ -26,11 +26,16 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import re +from lib.core.convert import md5hash from lib.core.data import conf -from lib.core.settings import MATCH_RATIO +from lib.core.data import logger +#from lib.core.settings import MATCH_RATIO +MATCH_RATIO = None def comparison(page, headers=None, getSeqMatcher=False): + global MATCH_RATIO + regExpResults = None # String to be excluded before calculating page hash @@ -67,15 +72,34 @@ def comparison(page, headers=None, getSeqMatcher=False): else: return False - # By default it returns sequence matcher between the first untouched - # HTTP response page content and this content conf.seqMatcher.set_seq2(page) + ratio = round(conf.seqMatcher.ratio(), 3) + # 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 MATCH_RATIO == None: + if conf.md5hash != None and ratio != 1: + logger.debug("Setting match ratio to %.3f" % ratio) + MATCH_RATIO = ratio + elif conf.md5hash == None: + logger.debug("Setting match ratio to default value 0.900") + MATCH_RATIO = 0.900 + + # If it has been requested to return the ratio and not a comparison + # response if getSeqMatcher: - return round(conf.seqMatcher.ratio(), 3) + return ratio - elif round(conf.seqMatcher.ratio(), 3) >= MATCH_RATIO: + # If the url is stable it returns True if the page has the same MD5 + # hash of the original one + # NOTE: old implementation, it did not handle automatically the fact + # that the url could be not stable (due to VIEWSTATE, counter, etc.) + #elif conf.md5hash != None: + # return conf.md5hash == md5hash(page) + + # If the url is not stable it returns sequence matcher between the + # first untouched HTTP response page content and this content + elif ratio > MATCH_RATIO: return True - else: return False