Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 34580f5

Browse files
committed
added --tamper option
1 parent 9a08f7f commit 34580f5

6 files changed

Lines changed: 109 additions & 44 deletions

File tree

lib/core/option.py

Lines changed: 84 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,45 @@ def __setDBMS():
542542
errMsg += "fingerprint it for you."
543543
raise sqlmapUnsupportedDBMSException, errMsg
544544

545+
def __setTamperingFunctions():
546+
"""
547+
Loads tampering functions from given module path(s).
548+
"""
549+
if conf.tamper:
550+
kb.tamperFunctions = []
551+
import inspect
552+
import sys
553+
for file in conf.tamper.split(';'):
554+
if not file:
555+
continue
556+
elif not os.path.exists(file):
557+
errMsg = "missing tampering module file '%s'" % file
558+
raise sqlmapFilePathException, errMsg
559+
elif os.path.splitext(file)[1] != '.py':
560+
errMsg = "tampering module file should have an extension '.py'"
561+
raise sqlmapSyntaxException, errMsg
562+
dirname, filename = os.path.split(file)
563+
dirname = os.path.abspath(dirname)
564+
if not os.path.exists(os.path.join(dirname, '__init__.py')):
565+
errMsg = "make sure that there is an empty file '__init__.py' "
566+
errMsg += "inside of tampering module directory '%s'" % dirname
567+
raise sqlmapGenericException, errMsg
568+
if dirname not in sys.path:
569+
sys.path.insert(0, dirname)
570+
try:
571+
module = __import__(filename[:-3])
572+
except ImportError, msg:
573+
raise sqlmapSyntaxException, "can't import module file '%s' (%s)" % (file, msg)
574+
575+
found = False
576+
for name, function in inspect.getmembers(module, inspect.isfunction):
577+
if name=="tamper" and function.func_code.co_argcount == 2:
578+
kb.tamperFunctions.append(function)
579+
found = True
580+
break
581+
if not found:
582+
raise sqlmapGenericException, "missing function 'tamper(place, value)' in tampering module '%s'" % filename
583+
545584
def __setThreads():
546585
if not isinstance(conf.threads, int) or conf.threads <= 0:
547586
conf.threads = 1
@@ -989,58 +1028,59 @@ def __setKnowledgeBaseAttributes():
9891028
debugMsg = "initializing the knowledge base"
9901029
logger.debug(debugMsg)
9911030

992-
kb.absFilePaths = set()
993-
kb.assumeEmpty = False
994-
kb.bannerFp = advancedDict()
1031+
kb.absFilePaths = set()
1032+
kb.assumeEmpty = False
1033+
kb.bannerFp = advancedDict()
9951034

996-
kb.cache = advancedDict()
997-
kb.cache.regex = {}
1035+
kb.cache = advancedDict()
1036+
kb.cache.regex = {}
9981037

999-
kb.commonOutputs = None
1000-
kb.data = advancedDict()
1038+
kb.commonOutputs = None
1039+
kb.data = advancedDict()
10011040

10021041
# Basic back-end DBMS fingerprint
1003-
kb.dbms = None
1004-
kb.dbmsDetected = False
1042+
kb.dbms = None
1043+
kb.dbmsDetected = False
10051044

10061045
# Active (extensive) back-end DBMS fingerprint
1007-
kb.dbmsVersion = [ "Unknown" ]
1008-
1009-
kb.dep = None
1010-
kb.docRoot = None
1011-
kb.dynamicContent = []
1012-
kb.lastErrorPage = None
1013-
kb.headersCount = 0
1014-
kb.headersFp = {}
1015-
kb.htmlFp = []
1016-
kb.injParameter = None
1017-
kb.injPlace = None
1018-
kb.injType = None
1019-
kb.injections = xmlobject.XMLFile(path=paths.INJECTIONS_XML)
1020-
kb.hintValue = None
1021-
kb.nullConnection = None
1046+
kb.dbmsVersion = [ "Unknown" ]
1047+
1048+
kb.dep = None
1049+
kb.docRoot = None
1050+
kb.dynamicContent = []
1051+
kb.lastErrorPage = None
1052+
kb.headersCount = 0
1053+
kb.headersFp = {}
1054+
kb.htmlFp = []
1055+
kb.injParameter = None
1056+
kb.injPlace = None
1057+
kb.injType = None
1058+
kb.injections = xmlobject.XMLFile(path=paths.INJECTIONS_XML)
1059+
kb.hintValue = None
1060+
kb.nullConnection = None
10221061

10231062
# Back-end DBMS underlying operating system fingerprint via banner (-b)
10241063
# parsing
1025-
kb.os = None
1026-
kb.osVersion = None
1027-
kb.osSP = None
1028-
1029-
kb.parenthesis = None
1030-
kb.partRun = None
1031-
kb.lastRequestUID = 0
1032-
kb.queryCounter = 0
1033-
kb.resumedQueries = {}
1034-
kb.stackedTest = None
1035-
kb.targetUrls = set()
1036-
kb.testedParams = set()
1037-
kb.timeTest = None
1038-
kb.unionComment = ""
1039-
kb.unionCount = None
1040-
kb.unionPosition = None
1041-
kb.unionNegative = False
1042-
kb.unionFalseCond = False
1043-
kb.valueStack = []
1064+
kb.os = None
1065+
kb.osVersion = None
1066+
kb.osSP = None
1067+
1068+
kb.parenthesis = None
1069+
kb.partRun = None
1070+
kb.lastRequestUID = 0
1071+
kb.queryCounter = 0
1072+
kb.resumedQueries = {}
1073+
kb.stackedTest = None
1074+
kb.tamperFunctions = None
1075+
kb.targetUrls = set()
1076+
kb.testedParams = set()
1077+
kb.timeTest = None
1078+
kb.unionComment = ""
1079+
kb.unionCount = None
1080+
kb.unionPosition = None
1081+
kb.unionNegative = False
1082+
kb.unionFalseCond = False
1083+
kb.valueStack = []
10441084

10451085
def __saveCmdline():
10461086
"""
@@ -1185,6 +1225,7 @@ def init(inputOptions=advancedDict()):
11851225
__basicOptionValidation()
11861226
__setRequestFromFile()
11871227
__setMultipleTargets()
1228+
__setTamperingFunctions()
11881229

11891230
parseTargetUrl()
11901231
parseTargetDirect()

lib/parse/cmdline.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ def cmdLineParser():
204204
action="store_true", default=False,
205205
help="Use operator BETWEEN instead of default '>'")
206206

207+
injection.add_option("--tamper", dest="tamper",
208+
help="Use given module(s) for tampering injection data")
209+
207210
# Techniques options
208211
techniques = OptionGroup(parser, "Techniques", "These options can "
209212
"be used to test for specific SQL injection "

lib/request/connect.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,13 @@ def queryPage(value=None, place=None, content=False, getSeqMatcher=False, silent
305305

306306
if not place:
307307
place = kb.injPlace
308+
309+
if kb.tamperFunctions:
310+
for function in kb.tamperFunctions:
311+
value = function(place, value)
308312

309313
if "GET" in conf.parameters:
310-
get = conf.parameters["GET"] if place != "GET" or not value else value
314+
get = conf.parameters["GET"] if place != "GET" or not value else value
311315

312316
if "POST" in conf.parameters:
313317
post = conf.parameters["POST"] if place != "POST" or not value else value

tamper/__init__.py

Whitespace-only changes.

tamper/dummy.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
def tamper(place, value):
2+
print "Hi, World!"
3+
print value
4+
if place=="GET" and value:
5+
value=value.upper()
6+
return value

tamper/ifnull2ifisnull.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import re
2+
3+
#not finished (watch for number of parenthesis)
4+
#IFNULL(A,B) -> IF(ISNULL(A),B,A)
5+
def tamper(place, value):
6+
if value:
7+
if value.find("IFNULL") > -1:
8+
import pdb
9+
pdb.set_trace()
10+
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)
11+
return value

0 commit comments

Comments
 (0)