diff --git a/lib/core/exception.py b/lib/core/exception.py index 2f9d2b62e..0b93ab4d9 100644 --- a/lib/core/exception.py +++ b/lib/core/exception.py @@ -70,7 +70,7 @@ class sqlmapValueException(Exception): def unhandledException(): errMsg = "unhandled exception in %s, please copy " % VERSION_STRING errMsg += "the command line and the following text and send by e-mail " - errMsg += "to sqlmap-users@lists.sourceforge.net. The developer will " + errMsg += "to sqlmap-users@lists.sourceforge.net. The developers will " errMsg += "fix it as soon as possible:\nsqlmap version: %s\n" % VERSION errMsg += "Python version: %s\n" % PYVERSION errMsg += "Operating system: %s" % PLATFORM @@ -95,4 +95,4 @@ exceptionsTuple = ( sqlmapUnsupportedDBMSException, sqlmapUnsupportedFeatureException, sqlmapValueException, - ) \ No newline at end of file + ) diff --git a/lib/core/option.py b/lib/core/option.py index 43bf6ec75..329b83e06 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -11,6 +11,7 @@ import codecs import cookielib import ctypes import difflib +import inspect import logging import os import re @@ -531,34 +532,33 @@ def __setDBMS(): def __setTamperingFunctions(): """ - Loads tampering functions from given module path(s). + Loads tampering functions from given script(s) """ + if conf.tamper: - kb.tamperFunctions = [] + for tfile in conf.tamper.split(';'): + found = False - import inspect - - for file in conf.tamper.split(';'): - if not file: + if not tfile: continue - elif not os.path.exists(file): - errMsg = "missing tampering module file '%s'" % file + elif not os.path.exists(tfile): + errMsg = "tamper script '%s' does not exist" % tfile raise sqlmapFilePathException, errMsg - elif os.path.splitext(file)[1] != '.py': - errMsg = "tampering module file should have an extension '.py'" + elif not tfile.endswith('.py'): + errMsg = "tamper script '%s' should have an extension '.py'" % tfile raise sqlmapSyntaxException, errMsg - dirname, filename = os.path.split(file) + dirname, filename = os.path.split(tfile) dirname = os.path.abspath(dirname) - infoMsg = "loading tampering module: '%s'" % filename[:-3] + infoMsg = "loading tamper script '%s'" % filename[:-3] logger.info(infoMsg) if not os.path.exists(os.path.join(dirname, '__init__.py')): errMsg = "make sure that there is an empty file '__init__.py' " - errMsg += "inside of tampering module directory '%s'" % dirname + errMsg += "inside of tamper scripts directory '%s'" % dirname raise sqlmapGenericException, errMsg if dirname not in sys.path: @@ -567,17 +567,17 @@ def __setTamperingFunctions(): try: module = __import__(filename[:-3]) except ImportError, msg: - raise sqlmapSyntaxException, "can't import module file '%s' (%s)" % (file, msg) + raise sqlmapSyntaxException, "can not import tamper script '%s' (%s)" % (filename[:-3], msg) - found = False for name, function in inspect.getmembers(module, inspect.isfunction): - if name=="tamper" and function.func_code.co_argcount == 2: + if name == "tamper" and function.func_code.co_argcount == 2: kb.tamperFunctions.append(function) found = True + break if not found: - raise sqlmapGenericException, "missing function 'tamper(place, value)' in tampering module '%s'" % filename + raise sqlmapGenericException, "missing function 'tamper(place, value)' in tamper script '%s'" % tfile def __setThreads(): if not isinstance(conf.threads, int) or conf.threads <= 0: @@ -943,6 +943,9 @@ def __cleanupOptions(): else: conf.testParameter = [] + if conf.tamper: + conf.tamper = conf.tamper.replace(" ", "") + if conf.db: conf.db = conf.db.replace(" ", "") @@ -1071,7 +1074,7 @@ def __setKnowledgeBaseAttributes(): kb.queryCounter = 0 kb.resumedQueries = {} kb.stackedTest = None - kb.tamperFunctions = None + kb.tamperFunctions = [] kb.targetUrls = set() kb.testedParams = set() kb.timeTest = None diff --git a/tamper/between.py b/tamper/between.py index 7f0e4a635..7a58d5fd2 100644 --- a/tamper/between.py +++ b/tamper/between.py @@ -7,15 +7,15 @@ Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/) See the file 'doc/COPYING' for copying permission """ -import re - from lib.core.convert import urldecode from lib.core.convert import urlencode -""" -'>' -> NOT BETWEEN 0 AND (e.g., A>B->A NOT BETWEEN 0 AND B) -""" def tamper(place, value): + """ + Replaces '>' with 'NOT BETWEEN 0 AND #' + Example: 'A > B' becomes 'A NOT BETWEEN 0 AND B' + """ + retVal = value if value: @@ -23,25 +23,26 @@ def tamper(place, value): value = urldecode(value) retVal = "" - qoute, doublequote, firstspace = False, False, False + quote, doublequote, firstspace = False, False, False for i in xrange(len(value)): if not firstspace: if value[i].isspace(): firstspace = True - retVal += "/**/" + retVal += " " continue elif value[i] == '\'': - qoute = not qoute + quote = not quote elif value[i] == '"': doublequote = not doublequote - elif value[i]==">" and not doublequote and not qoute: + elif value[i] == ">" and not doublequote and not quote: retVal += " " if i > 0 and not value[i-1].isspace() else "" retVal += "NOT BETWEEN 0 AND" retVal += " " if i < len(value) - 1 and not value[i+1].isspace() else "" + continue retVal += value[i] diff --git a/tamper/charencode.py b/tamper/charencode.py index 154132a27..9070e76fc 100644 --- a/tamper/charencode.py +++ b/tamper/charencode.py @@ -7,15 +7,16 @@ Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/) See the file 'doc/COPYING' for copying permission """ -import re import string from lib.core.exception import sqlmapUnsupportedFeatureException -""" -value -> urlencode of nonencoded chars in value (e.g., SELECT%20FIELD%20FROM%20TABLE -> %53%45%4c%45%43%54%20%46%49%45%4c%44%20%46%52%4f%4d%20%54%41%42%4c%45) -""" def tamper(place, value): + """ + Replaces value with urlencode of non-encoded chars in value + Example: 'SELECT%20FIELD%20FROM%20TABLE' becomes '%53%45%4c%45%43%54%20%46%49%45%4c%44%20%46%52%4f%4d%20%54%41%42%4c%45' + """ + retVal = value if value: @@ -31,6 +32,6 @@ def tamper(place, value): retVal += '%%%X' % ord(value[i]) i += 1 else: - raise sqlmapUnsupportedFeatureException, "can't use tampering module '%s' with 'URI' type injections" % __name__ + raise sqlmapUnsupportedFeatureException, "can't use tamper script '%s' with 'URI' type injections" % __name__ return retVal diff --git a/tamper/doubleencode.py b/tamper/doubleencode.py index 80c2529f4..bfac5da67 100644 --- a/tamper/doubleencode.py +++ b/tamper/doubleencode.py @@ -7,19 +7,19 @@ Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/) See the file 'doc/COPYING' for copying permission """ -import re - from lib.core.convert import urlencode from lib.core.exception import sqlmapUnsupportedFeatureException -""" -Tampering value -> urlencode(value) (e.g., SELECT%20FIELD%20FROM%20TABLE -> SELECT%25%20FIELD%25%20FROM%25%20TABLE) -""" def tamper(place, value): + """ + Replaces value with urlencode(value) + Example: 'SELECT%20FIELD%20FROM%20TABLE' becomes 'SELECT%25%20FIELD%25%20FROM%25%20TABLE' + """ + if value: if place != "URI": - value = urlencode(value) + value = urlencode(value, convall=True) else: - raise sqlmapUnsupportedFeatureException, "can't use tampering module '%s' with 'URI' type injections" % __name__ + raise sqlmapUnsupportedFeatureException, "can't use tamper script '%s' with 'URI' type injections" % __name__ return value diff --git a/tamper/ifnull2ifisnull.py b/tamper/ifnull2ifisnull.py index 25d0a1ee1..aa6564d12 100644 --- a/tamper/ifnull2ifisnull.py +++ b/tamper/ifnull2ifisnull.py @@ -7,15 +7,14 @@ Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/) See the file 'doc/COPYING' for copying permission """ -import re - from lib.core.convert import urldecode from lib.core.convert import urlencode -""" -IFNULL(A,B) -> IF(ISNULL(A),B,A) (e.g., IFNULL(1,2) -> IF(ISNULL(1),2,1)) -""" def tamper(place, value): + """ + Replaces 'IFNULL(A, B)' with 'IF(ISNULL(A), B, A)' + Example: 'IFNULL(1, 2)' becomes 'IF(ISNULL(1), 2, 1)' + """ if value and value.find("IFNULL") > -1: if place != "URI": diff --git a/tamper/randomcase.py b/tamper/randomcase.py index 9e0de62bf..b5fc465fd 100644 --- a/tamper/randomcase.py +++ b/tamper/randomcase.py @@ -8,17 +8,18 @@ See the file 'doc/COPYING' for copying permission """ import re -import string from lib.core.common import randomRange from lib.core.convert import urldecode from lib.core.convert import urlencode from lib.core.data import kb -""" -value -> chars from value with random case (e.g., INSERT->InsERt) -""" def tamper(place, value): + """ + Replaces each character with random case value + Example: 'INSERT' might become 'InsERt' + """ + retVal = value if value: diff --git a/tamper/randomblanks.py b/tamper/randomcomments.py similarity index 87% rename from tamper/randomblanks.py rename to tamper/randomcomments.py index fa065bdcc..0f78f70fa 100644 --- a/tamper/randomblanks.py +++ b/tamper/randomcomments.py @@ -8,17 +8,18 @@ See the file 'doc/COPYING' for copying permission """ import re -import string from lib.core.common import randomRange from lib.core.convert import urldecode from lib.core.convert import urlencode from lib.core.data import kb -""" -value -> value with inserted random blanks (e.g., INSERT->IN/**/S/**/ERT) -""" def tamper(place, value): + """ + Add random comments to value + Example: 'INSERT' becomes 'IN/**/S/**/ERT' + """ + retVal = value if value: diff --git a/tamper/space2comment.py b/tamper/space2comment.py index ba6b9835c..960844192 100644 --- a/tamper/space2comment.py +++ b/tamper/space2comment.py @@ -7,15 +7,15 @@ Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/) See the file 'doc/COPYING' for copying permission """ -import re - from lib.core.convert import urldecode from lib.core.convert import urlencode -""" -' ' -> /**/ (e.g., SELECT id FROM users->SELECT/**/id/**/FROM users) -""" def tamper(place, value): + """ + Replaces ' ' with '/**/' + Example: 'SELECT id FROM users' becomes 'SELECT/**/id/**/FROM users' + """ + retVal = value if value: @@ -23,7 +23,7 @@ def tamper(place, value): value = urldecode(value) retVal = "" - qoute, doublequote, firstspace = False, False, False + quote, doublequote, firstspace = False, False, False for i in xrange(len(value)): if not firstspace: @@ -33,12 +33,12 @@ def tamper(place, value): continue elif value[i] == '\'': - qoute = not qoute + quote = not quote elif value[i] == '"': doublequote = not doublequote - elif value[i]==" " and not doublequote and not qoute: + elif value[i]==" " and not doublequote and not quote: retVal += "/**/" continue