diff --git a/lib/core/option.py b/lib/core/option.py index e23f51347..168dfa982 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -2648,6 +2648,13 @@ def _basicOptionValidation(): errMsg = "invalid regular expression '%s' ('%s')" % (conf.paramExclude, getSafeExString(ex)) raise SqlmapSyntaxException(errMsg) + if conf.retryOn: + try: + re.compile(conf.retryOn) + except Exception as ex: + errMsg = "invalid regular expression '%s' ('%s')" % (conf.retryOn, getSafeExString(ex)) + raise SqlmapSyntaxException(errMsg) + if conf.cookieDel and len(conf.cookieDel): errMsg = "option '--cookie-del' should contain a single character (e.g. ';')" raise SqlmapSyntaxException(errMsg) diff --git a/lib/core/optiondict.py b/lib/core/optiondict.py index c22b9d11e..ca42ff0ca 100644 --- a/lib/core/optiondict.py +++ b/lib/core/optiondict.py @@ -54,6 +54,7 @@ optDict = { "delay": "float", "timeout": "float", "retries": "integer", + "retryOn": "string", "rParam": "string", "safeUrl": "string", "safePost": "string", diff --git a/lib/core/settings.py b/lib/core/settings.py index 6f1781066..ce0e7affa 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from thirdparty import six from thirdparty.six import unichr as _unichr # sqlmap version (...) -VERSION = "1.5.10.21" +VERSION = "1.5.11.0" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE) diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index bc4027cd0..bb64f2dd8 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -246,6 +246,9 @@ def cmdLineParser(argv=None): request.add_argument("--retries", dest="retries", type=int, help="Retries when the connection timeouts (default %d)" % defaults.retries) + request.add_argument("--retry-on", dest="retryOn", + help="Retry request on regexp matching content (e.g. \"drop\")") + request.add_argument("--randomize", dest="rParam", help="Randomly change value for given parameter(s)") diff --git a/lib/request/connect.py b/lib/request/connect.py index f88be5783..6580ca0a6 100644 --- a/lib/request/connect.py +++ b/lib/request/connect.py @@ -909,6 +909,17 @@ class Connect(object): socket.setdefaulttimeout(conf.timeout) + if conf.retryOn and re.search(conf.retryOn, page, re.I): + if threadData.retriesCount < conf.retries: + warnMsg = "forced retry of the request because of undesired page content" + logger.warn(warnMsg) + return Connect._retryProxy(**kwargs) + else: + errMsg = "unable to get the page content not matching " + errMsg += "the given regular expression '%s'. Please use as high " % conf.retryOn + errMsg += "value for option '--retries' as possible (e.g. 20 or more)" + raise SqlmapConnectionException(errMsg) + processResponse(page, responseHeaders, code, status) if not skipLogTraffic: diff --git a/sqlmap.conf b/sqlmap.conf index a771a4e79..1e436c56d 100644 --- a/sqlmap.conf +++ b/sqlmap.conf @@ -160,6 +160,9 @@ timeout = 30 # Default: 3 retries = 3 +# Retry request on regexp matching content. +retries = 3 + # Randomly change value for the given parameter. rParam =