mirror of
				https://github.com/sqlmapproject/sqlmap.git
				synced 2025-11-01 16:37:27 +03:00 
			
		
		
		
	Implementation on request (--csrf-retries)
This commit is contained in:
		
							parent
							
								
									1dedc36d85
								
							
						
					
					
						commit
						16c8673e98
					
				|  | @ -15,6 +15,7 @@ _defaults = { | ||||||
|     "delay": 0, |     "delay": 0, | ||||||
|     "timeout": 30, |     "timeout": 30, | ||||||
|     "retries": 3, |     "retries": 3, | ||||||
|  |     "csrfRetries": 0, | ||||||
|     "saFreq": 0, |     "saFreq": 0, | ||||||
|     "threads": 1, |     "threads": 1, | ||||||
|     "level": 1, |     "level": 1, | ||||||
|  |  | ||||||
|  | @ -61,6 +61,7 @@ optDict = { | ||||||
|         "csrfToken": "string", |         "csrfToken": "string", | ||||||
|         "csrfUrl": "string", |         "csrfUrl": "string", | ||||||
|         "csrfMethod": "string", |         "csrfMethod": "string", | ||||||
|  |         "csrfRetries": "integer", | ||||||
|         "forceSSL": "boolean", |         "forceSSL": "boolean", | ||||||
|         "chunked": "boolean", |         "chunked": "boolean", | ||||||
|         "hpp": "boolean", |         "hpp": "boolean", | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ from lib.core.enums import OS | ||||||
| from thirdparty.six import unichr as _unichr | from thirdparty.six import unichr as _unichr | ||||||
| 
 | 
 | ||||||
| # sqlmap version (<major>.<minor>.<month>.<monthly commit>) | # sqlmap version (<major>.<minor>.<month>.<monthly commit>) | ||||||
| VERSION = "1.4.6.4" | VERSION = "1.4.6.5" | ||||||
| TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" | TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" | ||||||
| TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} | 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) | VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE) | ||||||
|  |  | ||||||
|  | @ -267,6 +267,9 @@ def cmdLineParser(argv=None): | ||||||
|         request.add_argument("--csrf-method", dest="csrfMethod", |         request.add_argument("--csrf-method", dest="csrfMethod", | ||||||
|             help="HTTP method to use during anti-CSRF token page visit") |             help="HTTP method to use during anti-CSRF token page visit") | ||||||
| 
 | 
 | ||||||
|  |         request.add_argument("--csrf-retries", dest="csrfRetries", type=int, | ||||||
|  |             help="Retries for anti-CSRF token retrieval (default %d)" % defaults.csrfRetries) | ||||||
|  | 
 | ||||||
|         request.add_argument("--force-ssl", dest="forceSSL", action="store_true", |         request.add_argument("--force-ssl", dest="forceSSL", action="store_true", | ||||||
|             help="Force usage of SSL/HTTPS") |             help="Force usage of SSL/HTTPS") | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1045,6 +1045,8 @@ class Connect(object): | ||||||
|                 auxHeaders[value.split(',')[0]] = value.split(',', 1)[-1] |                 auxHeaders[value.split(',')[0]] = value.split(',', 1)[-1] | ||||||
| 
 | 
 | ||||||
|         if conf.csrfToken: |         if conf.csrfToken: | ||||||
|  |             token = AttribDict() | ||||||
|  | 
 | ||||||
|             def _adjustParameter(paramString, parameter, newValue): |             def _adjustParameter(paramString, parameter, newValue): | ||||||
|                 retVal = paramString |                 retVal = paramString | ||||||
| 
 | 
 | ||||||
|  | @ -1061,56 +1063,64 @@ class Connect(object): | ||||||
| 
 | 
 | ||||||
|                 return retVal |                 return retVal | ||||||
| 
 | 
 | ||||||
|             token = AttribDict() |             for attempt in xrange(conf.csrfRetries + 1): | ||||||
|             page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=conf.csrfMethod or (conf.method if conf.csrfUrl == conf.url else None), cookie=conf.parameters.get(PLACE.COOKIE), direct=True, silent=True, ua=conf.parameters.get(PLACE.USER_AGENT), referer=conf.parameters.get(PLACE.REFERER), host=conf.parameters.get(PLACE.HOST)) |                 if token: | ||||||
|             page = urldecode(page)  # for anti-CSRF tokens with special characters in their name (e.g. 'foo:bar=...') |                     break | ||||||
| 
 | 
 | ||||||
|             match = re.search(r"(?i)<input[^>]+\bname=[\"']?(?P<name>%s)\b[^>]*\bvalue=[\"']?(?P<value>[^>'\"]*)" % conf.csrfToken, page or "", re.I) |                 if attempt > 0: | ||||||
|  |                     warnMsg = "unable to find anti-CSRF token '%s' at '%s'" % (conf.csrfToken._original, conf.csrfUrl or conf.url) | ||||||
|  |                     warnMsg += ". sqlmap is going to retry the request" | ||||||
|  |                     logger.warn(warnMsg) | ||||||
| 
 | 
 | ||||||
|             if not match: |                 page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=conf.csrfMethod or (conf.method if conf.csrfUrl == conf.url else None), cookie=conf.parameters.get(PLACE.COOKIE), direct=True, silent=True, ua=conf.parameters.get(PLACE.USER_AGENT), referer=conf.parameters.get(PLACE.REFERER), host=conf.parameters.get(PLACE.HOST)) | ||||||
|                 match = re.search(r"(?i)<input[^>]+\bvalue=[\"']?(?P<value>[^>'\"]*)[\"']?[^>]*\bname=[\"']?(?P<name>%s)\b" % conf.csrfToken, page or "", re.I) |                 page = urldecode(page)  # for anti-CSRF tokens with special characters in their name (e.g. 'foo:bar=...') | ||||||
|  | 
 | ||||||
|  |                 match = re.search(r"(?i)<input[^>]+\bname=[\"']?(?P<name>%s)\b[^>]*\bvalue=[\"']?(?P<value>[^>'\"]*)" % conf.csrfToken, page or "", re.I) | ||||||
| 
 | 
 | ||||||
|                 if not match: |                 if not match: | ||||||
|                     match = re.search(r"(?P<name>%s)[\"']:[\"'](?P<value>[^\"']+)" % conf.csrfToken, page or "", re.I) |                     match = re.search(r"(?i)<input[^>]+\bvalue=[\"']?(?P<value>[^>'\"]*)[\"']?[^>]*\bname=[\"']?(?P<name>%s)\b" % conf.csrfToken, page or "", re.I) | ||||||
| 
 | 
 | ||||||
|                     if not match: |                     if not match: | ||||||
|                         match = re.search(r"\b(?P<name>%s)\s*[:=]\s*(?P<value>\w+)" % conf.csrfToken, str(headers), re.I) |                         match = re.search(r"(?P<name>%s)[\"']:[\"'](?P<value>[^\"']+)" % conf.csrfToken, page or "", re.I) | ||||||
| 
 | 
 | ||||||
|                         if not match: |                         if not match: | ||||||
|                             match = re.search(r"\b(?P<name>%s)\s*=\s*['\"]?(?P<value>[^;'\"]+)" % conf.csrfToken, page or "", re.I) |                             match = re.search(r"\b(?P<name>%s)\s*[:=]\s*(?P<value>\w+)" % conf.csrfToken, str(headers), re.I) | ||||||
| 
 | 
 | ||||||
|             if match: |                             if not match: | ||||||
|                 token.name, token.value = match.group("name"), match.group("value") |                                 match = re.search(r"\b(?P<name>%s)\s*=\s*['\"]?(?P<value>[^;'\"]+)" % conf.csrfToken, page or "", re.I) | ||||||
| 
 | 
 | ||||||
|                 match = re.search(r"String\.fromCharCode\(([\d+, ]+)\)", token.value) |  | ||||||
|                 if match: |                 if match: | ||||||
|                     token.value = "".join(_unichr(int(_)) for _ in match.group(1).replace(' ', "").split(',')) |                     token.name, token.value = match.group("name"), match.group("value") | ||||||
| 
 | 
 | ||||||
|             if not token: |                     match = re.search(r"String\.fromCharCode\(([\d+, ]+)\)", token.value) | ||||||
|                 if conf.csrfUrl and conf.csrfToken and conf.csrfUrl != conf.url and code == _http_client.OK: |                     if match: | ||||||
|                     if headers and "text/plain" in headers.get(HTTP_HEADER.CONTENT_TYPE, ""): |                         token.value = "".join(_unichr(int(_)) for _ in match.group(1).replace(' ', "").split(',')) | ||||||
|                         token.name = conf.csrfToken |  | ||||||
|                         token.value = page |  | ||||||
| 
 |  | ||||||
|                 if not token and conf.cj and any(re.search(conf.csrfToken, _.name, re.I) for _ in conf.cj): |  | ||||||
|                     for _ in conf.cj: |  | ||||||
|                         if re.search(conf.csrfToken, _.name, re.I): |  | ||||||
|                             token.name, token.value = _.name, _.value |  | ||||||
|                             if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))): |  | ||||||
|                                 if post: |  | ||||||
|                                     post = "%s%s%s=%s" % (post, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value) |  | ||||||
|                                 elif get: |  | ||||||
|                                     get = "%s%s%s=%s" % (get, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value) |  | ||||||
|                                 else: |  | ||||||
|                                     get = "%s=%s" % (token.name, token.value) |  | ||||||
|                             break |  | ||||||
| 
 | 
 | ||||||
|                 if not token: |                 if not token: | ||||||
|                     errMsg = "anti-CSRF token '%s' can't be found at '%s'" % (conf.csrfToken._original, conf.csrfUrl or conf.url) |                     if conf.csrfUrl and conf.csrfToken and conf.csrfUrl != conf.url and code == _http_client.OK: | ||||||
|                     if not conf.csrfUrl: |                         if headers and "text/plain" in headers.get(HTTP_HEADER.CONTENT_TYPE, ""): | ||||||
|                         errMsg += ". You can try to rerun by providing " |                             token.name = conf.csrfToken | ||||||
|                         errMsg += "a valid value for option '--csrf-url'" |                             token.value = page | ||||||
|                     raise SqlmapTokenException(errMsg) | 
 | ||||||
|  |                     if not token and conf.cj and any(re.search(conf.csrfToken, _.name, re.I) for _ in conf.cj): | ||||||
|  |                         for _ in conf.cj: | ||||||
|  |                             if re.search(conf.csrfToken, _.name, re.I): | ||||||
|  |                                 token.name, token.value = _.name, _.value | ||||||
|  |                                 if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))): | ||||||
|  |                                     if post: | ||||||
|  |                                         post = "%s%s%s=%s" % (post, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value) | ||||||
|  |                                     elif get: | ||||||
|  |                                         get = "%s%s%s=%s" % (get, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value) | ||||||
|  |                                     else: | ||||||
|  |                                         get = "%s=%s" % (token.name, token.value) | ||||||
|  |                                 break | ||||||
|  | 
 | ||||||
|  |             if not token: | ||||||
|  |                 errMsg = "anti-CSRF token '%s' can't be found at '%s'" % (conf.csrfToken._original, conf.csrfUrl or conf.url) | ||||||
|  |                 if not conf.csrfUrl: | ||||||
|  |                     errMsg += ". You can try to rerun by providing " | ||||||
|  |                     errMsg += "a valid value for option '--csrf-url'" | ||||||
|  |                 raise SqlmapTokenException(errMsg) | ||||||
| 
 | 
 | ||||||
|             if token: |             if token: | ||||||
|                 token.value = token.value.strip("'\"") |                 token.value = token.value.strip("'\"") | ||||||
|  |  | ||||||
|  | @ -189,6 +189,9 @@ csrfUrl = | ||||||
| # HTTP method to use during anti-CSRF token page visit. | # HTTP method to use during anti-CSRF token page visit. | ||||||
| csrfMethod = | csrfMethod = | ||||||
| 
 | 
 | ||||||
|  | # Retries for anti-CSRF token retrieval. | ||||||
|  | csrfRetries = | ||||||
|  | 
 | ||||||
| # Force usage of SSL/HTTPS | # Force usage of SSL/HTTPS | ||||||
| # Valid: True or False | # Valid: True or False | ||||||
| forceSSL = False | forceSSL = False | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user