added --tamper option

This commit is contained in:
Miroslav Stampar 2010-10-12 22:45:25 +00:00
parent 9a08f7feb8
commit 34580f56fc
6 changed files with 107 additions and 42 deletions

View File

@ -542,6 +542,45 @@ def __setDBMS():
errMsg += "fingerprint it for you." errMsg += "fingerprint it for you."
raise sqlmapUnsupportedDBMSException, errMsg raise sqlmapUnsupportedDBMSException, errMsg
def __setTamperingFunctions():
"""
Loads tampering functions from given module path(s).
"""
if conf.tamper:
kb.tamperFunctions = []
import inspect
import sys
for file in conf.tamper.split(';'):
if not file:
continue
elif not os.path.exists(file):
errMsg = "missing tampering module file '%s'" % file
raise sqlmapFilePathException, errMsg
elif os.path.splitext(file)[1] != '.py':
errMsg = "tampering module file should have an extension '.py'"
raise sqlmapSyntaxException, errMsg
dirname, filename = os.path.split(file)
dirname = os.path.abspath(dirname)
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
raise sqlmapGenericException, errMsg
if dirname not in sys.path:
sys.path.insert(0, dirname)
try:
module = __import__(filename[:-3])
except ImportError, msg:
raise sqlmapSyntaxException, "can't import module file '%s' (%s)" % (file, msg)
found = False
for name, function in inspect.getmembers(module, inspect.isfunction):
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
def __setThreads(): def __setThreads():
if not isinstance(conf.threads, int) or conf.threads <= 0: if not isinstance(conf.threads, int) or conf.threads <= 0:
conf.threads = 1 conf.threads = 1
@ -989,58 +1028,59 @@ def __setKnowledgeBaseAttributes():
debugMsg = "initializing the knowledge base" debugMsg = "initializing the knowledge base"
logger.debug(debugMsg) logger.debug(debugMsg)
kb.absFilePaths = set() kb.absFilePaths = set()
kb.assumeEmpty = False kb.assumeEmpty = False
kb.bannerFp = advancedDict() kb.bannerFp = advancedDict()
kb.cache = advancedDict() kb.cache = advancedDict()
kb.cache.regex = {} kb.cache.regex = {}
kb.commonOutputs = None kb.commonOutputs = None
kb.data = advancedDict() kb.data = advancedDict()
# Basic back-end DBMS fingerprint # Basic back-end DBMS fingerprint
kb.dbms = None kb.dbms = None
kb.dbmsDetected = False kb.dbmsDetected = False
# Active (extensive) back-end DBMS fingerprint # Active (extensive) back-end DBMS fingerprint
kb.dbmsVersion = [ "Unknown" ] kb.dbmsVersion = [ "Unknown" ]
kb.dep = None kb.dep = None
kb.docRoot = None kb.docRoot = None
kb.dynamicContent = [] kb.dynamicContent = []
kb.lastErrorPage = None kb.lastErrorPage = None
kb.headersCount = 0 kb.headersCount = 0
kb.headersFp = {} kb.headersFp = {}
kb.htmlFp = [] kb.htmlFp = []
kb.injParameter = None kb.injParameter = None
kb.injPlace = None kb.injPlace = None
kb.injType = None kb.injType = None
kb.injections = xmlobject.XMLFile(path=paths.INJECTIONS_XML) kb.injections = xmlobject.XMLFile(path=paths.INJECTIONS_XML)
kb.hintValue = None kb.hintValue = None
kb.nullConnection = None kb.nullConnection = None
# Back-end DBMS underlying operating system fingerprint via banner (-b) # Back-end DBMS underlying operating system fingerprint via banner (-b)
# parsing # parsing
kb.os = None kb.os = None
kb.osVersion = None kb.osVersion = None
kb.osSP = None kb.osSP = None
kb.parenthesis = None kb.parenthesis = None
kb.partRun = None kb.partRun = None
kb.lastRequestUID = 0 kb.lastRequestUID = 0
kb.queryCounter = 0 kb.queryCounter = 0
kb.resumedQueries = {} kb.resumedQueries = {}
kb.stackedTest = None kb.stackedTest = None
kb.targetUrls = set() kb.tamperFunctions = None
kb.testedParams = set() kb.targetUrls = set()
kb.timeTest = None kb.testedParams = set()
kb.unionComment = "" kb.timeTest = None
kb.unionCount = None kb.unionComment = ""
kb.unionPosition = None kb.unionCount = None
kb.unionNegative = False kb.unionPosition = None
kb.unionFalseCond = False kb.unionNegative = False
kb.valueStack = [] kb.unionFalseCond = False
kb.valueStack = []
def __saveCmdline(): def __saveCmdline():
""" """
@ -1185,6 +1225,7 @@ def init(inputOptions=advancedDict()):
__basicOptionValidation() __basicOptionValidation()
__setRequestFromFile() __setRequestFromFile()
__setMultipleTargets() __setMultipleTargets()
__setTamperingFunctions()
parseTargetUrl() parseTargetUrl()
parseTargetDirect() parseTargetDirect()

View File

@ -204,6 +204,9 @@ def cmdLineParser():
action="store_true", default=False, action="store_true", default=False,
help="Use operator BETWEEN instead of default '>'") help="Use operator BETWEEN instead of default '>'")
injection.add_option("--tamper", dest="tamper",
help="Use given module(s) for tampering injection data")
# Techniques options # Techniques options
techniques = OptionGroup(parser, "Techniques", "These options can " techniques = OptionGroup(parser, "Techniques", "These options can "
"be used to test for specific SQL injection " "be used to test for specific SQL injection "

View File

@ -306,6 +306,10 @@ class Connect:
if not place: if not place:
place = kb.injPlace place = kb.injPlace
if kb.tamperFunctions:
for function in kb.tamperFunctions:
value = function(place, value)
if "GET" in conf.parameters: if "GET" in conf.parameters:
get = conf.parameters["GET"] if place != "GET" or not value else value get = conf.parameters["GET"] if place != "GET" or not value else value

0
tamper/__init__.py Normal file
View File

6
tamper/dummy.py Normal file
View File

@ -0,0 +1,6 @@
def tamper(place, value):
print "Hi, World!"
print value
if place=="GET" and value:
value=value.upper()
return value

11
tamper/ifnull2ifisnull.py Normal file
View File

@ -0,0 +1,11 @@
import re
#not finished (watch for number of parenthesis)
#IFNULL(A,B) -> IF(ISNULL(A),B,A)
def tamper(place, value):
if value:
if value.find("IFNULL") > -1:
import pdb
pdb.set_trace()
value = re.sub(r"IFNULL(\(|%28)(?P<A>.+?)(,|%2C)(?P<B>.+?)(\)|%29)", lambda match: "IF%%28ISNULL%%28%s%%29%%2C%s%%2C%s%%29" % ("A="+match.group("A"), "B="+match.group("B"), "A="+match.group("A")), value)
return value