diff --git a/lib/controller/checks.py b/lib/controller/checks.py index 92de2f75d..7ca2410dc 100644 --- a/lib/controller/checks.py +++ b/lib/controller/checks.py @@ -96,10 +96,10 @@ def checkSqlInjection(place, parameter, value): # Skip test if the user's wants to test only for a specific # technique - if conf.technique and isinstance(conf.technique, list) and stype not in conf.technique: + if conf.tech and isinstance(conf.tech, list) and stype not in conf.tech: debugMsg = "skipping test '%s' because the user " % title debugMsg += "specified to test only for " - debugMsg += "%s" % ",".join(map(lambda x: PAYLOAD.SQLINJECTION[x], conf.technique)) + debugMsg += "%s" % ",".join(map(lambda x: PAYLOAD.SQLINJECTION[x], conf.tech)) logger.debug(debugMsg) continue diff --git a/lib/controller/controller.py b/lib/controller/controller.py index a07b3d0ba..ed4558db9 100644 --- a/lib/controller/controller.py +++ b/lib/controller/controller.py @@ -406,14 +406,19 @@ def start(): if len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place is None): if not conf.realTest: - errMsg = "all parameters are not injectable, try " - errMsg += "a higher --level/--risk to use more tests" + errMsg = "all parameters are not injectable, try to " + errMsg += "increase --level/--risk values to perform " + errMsg += "more tests." + + if isinstance(conf.tech, list) and len(conf.tech) > 0: + errMsg += " Rerun without providing the --technique switch." if not conf.textOnly and kb.originalPage: percent = (100.0 * len(getFilteredPageContent(kb.originalPage)) / len(kb.originalPage)) - errMsg += " and/or --text-only switch if the target page " - errMsg += "has a low percentage of textual content " - errMsg += "(approximately %.2f%% of page content is text)" % percent + errMsg += " Give it a go with the --text-only switch " + errMsg += "if the target page has a low percentage of " + errMsg += "textual content (~%.2f%% of " % percent + errMsg += "page content is text)" raise sqlmapNotVulnerableException, errMsg else: diff --git a/lib/core/common.py b/lib/core/common.py index 0e9bc1983..e55cb82e5 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -2177,7 +2177,7 @@ def isTechniqueAvailable(technique=None): technique specified """ - if conf.technique and isinstance(conf.technique, list) and technique not in conf.technique: + if conf.tech and isinstance(conf.tech, list) and technique not in conf.tech: return False else: return getTechniqueData(technique) is not None diff --git a/lib/core/option.py b/lib/core/option.py index 8557d5b62..874971bde 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -605,10 +605,22 @@ def __setOS(): raise sqlmapUnsupportedDBMSException, errMsg def __setTechnique(): - if not conf.technique or not isinstance(conf.technique, int): - conf.technique = [] + if not conf.tech or not isinstance(conf.tech, int): + conf.tech = [] else: - conf.technique = filter(lambda x: x in PAYLOAD.SQLINJECTION, [int(c) for c in str(conf.technique)]) + conf.tech = filter(lambda x: x in PAYLOAD.SQLINJECTION, [int(c) for c in str(conf.tech)]) + + if len(conf.tech) > 0: + # TODO: consider MySQL/PHP/ASP/web backdoor case where stacked + # queries is technically not necessary + if any(map(lambda x: conf.__getitem__(x), ['rFile', 'wFile', \ + 'osCmd', 'osShell', 'osPwn', 'osSmb', 'osBof', 'regRead', \ + 'regAdd', 'regDel'])) and PAYLOAD.TECHNIQUE.STACKED not in conf.tech: + errMsg = "value for --technique must include stacked queries " + errMsg += "technique (4) when you want to access the file " + errMsg += "system, takeover the operating system or access " + errMsg += "Windows registry hives" + raise sqlmapSyntaxException, errMsg def __setDBMS(): """ diff --git a/lib/core/optiondict.py b/lib/core/optiondict.py index 5ea49b11c..398e6eeca 100644 --- a/lib/core/optiondict.py +++ b/lib/core/optiondict.py @@ -70,6 +70,7 @@ optDict = { }, "Techniques": { + "tech": "integer", "timeSec": "integer", "uCols": "string", "uChar": "string" diff --git a/lib/core/session.py b/lib/core/session.py index 49e424304..49d18114e 100644 --- a/lib/core/session.py +++ b/lib/core/session.py @@ -164,9 +164,9 @@ def resumeConfKb(expression, url, value): if injection.place in conf.paramDict and \ injection.parameter in conf.paramDict[injection.place]: - if not conf.technique or intersect(conf.technique, injection.data.keys()): - if intersect(conf.technique, injection.data.keys()): - injection.data = dict(filter(lambda (key, item): key in conf.technique, injection.data.items())) + if not conf.tech or intersect(conf.tech, injection.data.keys()): + if intersect(conf.tech, injection.data.keys()): + injection.data = dict(filter(lambda (key, item): key in conf.tech, injection.data.items())) if injection not in kb.injections: kb.injections.append(injection) diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index a14a6f2d1..f7890bb04 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -207,6 +207,10 @@ def cmdLineParser(): "used to tweak testing of specific SQL " "injection techniques.") + techniques.add_option("--technique", dest="tech", type="int", + default=0, help="SQL injection techniques to " + "test for (default all)") + techniques.add_option("--time-sec", dest="timeSec", type="int", default=TIME_DEFAULT_DELAY, help="Seconds to delay the DBMS response " @@ -528,9 +532,6 @@ def cmdLineParser(): parser.add_option("--run-case", dest="runCase", type="int", default=None, help=SUPPRESS_HELP) - parser.add_option("--technique", dest="technique", type="int", - default=0, help=SUPPRESS_HELP) - parser.add_option("--group-concat", dest="groupConcat", action="store_true", default=False, help=SUPPRESS_HELP) diff --git a/sqlmap.conf b/sqlmap.conf index 43720b769..1af48a9e9 100644 --- a/sqlmap.conf +++ b/sqlmap.conf @@ -223,6 +223,18 @@ textOnly = False # techniques. [Techniques] +# SQL injection techniques to test for. +# Valid: an integer composed by 1, 2, 3, 4 or 5 where: +# 1: boolean-based blind SQL injection +# 2: error-based SQL injection +# 3: UNION query SQL injection +# 4: stacked queries SQL injection +# 5: time-based blind SQL injection +# Example: 24 (means test for error-based and stacked queries SQL +# injection types only) +# Default: 0 (means test for all SQL injection types - recommended) +tech = 0 + # Seconds to delay the response from the DBMS. # Valid: integer # Default: 5