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

Skip to content

Commit 16c8673

Browse files
committed
Implementation on request (--csrf-retries)
1 parent 1dedc36 commit 16c8673

6 files changed

Lines changed: 55 additions & 37 deletions

File tree

lib/core/defaults.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"delay": 0,
1616
"timeout": 30,
1717
"retries": 3,
18+
"csrfRetries": 0,
1819
"saFreq": 0,
1920
"threads": 1,
2021
"level": 1,

lib/core/optiondict.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
"csrfToken": "string",
6262
"csrfUrl": "string",
6363
"csrfMethod": "string",
64+
"csrfRetries": "integer",
6465
"forceSSL": "boolean",
6566
"chunked": "boolean",
6667
"hpp": "boolean",

lib/core/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from thirdparty.six import unichr as _unichr
1919

2020
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
21-
VERSION = "1.4.6.4"
21+
VERSION = "1.4.6.5"
2222
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
2323
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
2424
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)

lib/parse/cmdline.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,9 @@ def cmdLineParser(argv=None):
267267
request.add_argument("--csrf-method", dest="csrfMethod",
268268
help="HTTP method to use during anti-CSRF token page visit")
269269

270+
request.add_argument("--csrf-retries", dest="csrfRetries", type=int,
271+
help="Retries for anti-CSRF token retrieval (default %d)" % defaults.csrfRetries)
272+
270273
request.add_argument("--force-ssl", dest="forceSSL", action="store_true",
271274
help="Force usage of SSL/HTTPS")
272275

lib/request/connect.py

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,6 +1045,8 @@ def queryPage(value=None, place=None, content=False, getRatioValue=False, silent
10451045
auxHeaders[value.split(',')[0]] = value.split(',', 1)[-1]
10461046

10471047
if conf.csrfToken:
1048+
token = AttribDict()
1049+
10481050
def _adjustParameter(paramString, parameter, newValue):
10491051
retVal = paramString
10501052

@@ -1061,56 +1063,64 @@ def _adjustParameter(paramString, parameter, newValue):
10611063

10621064
return retVal
10631065

1064-
token = AttribDict()
1065-
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))
1066-
page = urldecode(page) # for anti-CSRF tokens with special characters in their name (e.g. 'foo:bar=...')
1066+
for attempt in xrange(conf.csrfRetries + 1):
1067+
if token:
1068+
break
1069+
1070+
if attempt > 0:
1071+
warnMsg = "unable to find anti-CSRF token '%s' at '%s'" % (conf.csrfToken._original, conf.csrfUrl or conf.url)
1072+
warnMsg += ". sqlmap is going to retry the request"
1073+
logger.warn(warnMsg)
10671074

1068-
match = re.search(r"(?i)<input[^>]+\bname=[\"']?(?P<name>%s)\b[^>]*\bvalue=[\"']?(?P<value>[^>'\"]*)" % conf.csrfToken, page or "", re.I)
1075+
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))
1076+
page = urldecode(page) # for anti-CSRF tokens with special characters in their name (e.g. 'foo:bar=...')
10691077

1070-
if not match:
1071-
match = re.search(r"(?i)<input[^>]+\bvalue=[\"']?(?P<value>[^>'\"]*)[\"']?[^>]*\bname=[\"']?(?P<name>%s)\b" % conf.csrfToken, page or "", re.I)
1078+
match = re.search(r"(?i)<input[^>]+\bname=[\"']?(?P<name>%s)\b[^>]*\bvalue=[\"']?(?P<value>[^>'\"]*)" % conf.csrfToken, page or "", re.I)
10721079

10731080
if not match:
1074-
match = re.search(r"(?P<name>%s)[\"']:[\"'](?P<value>[^\"']+)" % conf.csrfToken, page or "", re.I)
1081+
match = re.search(r"(?i)<input[^>]+\bvalue=[\"']?(?P<value>[^>'\"]*)[\"']?[^>]*\bname=[\"']?(?P<name>%s)\b" % conf.csrfToken, page or "", re.I)
10751082

10761083
if not match:
1077-
match = re.search(r"\b(?P<name>%s)\s*[:=]\s*(?P<value>\w+)" % conf.csrfToken, str(headers), re.I)
1084+
match = re.search(r"(?P<name>%s)[\"']:[\"'](?P<value>[^\"']+)" % conf.csrfToken, page or "", re.I)
10781085

10791086
if not match:
1080-
match = re.search(r"\b(?P<name>%s)\s*=\s*['\"]?(?P<value>[^;'\"]+)" % conf.csrfToken, page or "", re.I)
1087+
match = re.search(r"\b(?P<name>%s)\s*[:=]\s*(?P<value>\w+)" % conf.csrfToken, str(headers), re.I)
10811088

1082-
if match:
1083-
token.name, token.value = match.group("name"), match.group("value")
1089+
if not match:
1090+
match = re.search(r"\b(?P<name>%s)\s*=\s*['\"]?(?P<value>[^;'\"]+)" % conf.csrfToken, page or "", re.I)
10841091

1085-
match = re.search(r"String\.fromCharCode\(([\d+, ]+)\)", token.value)
10861092
if match:
1087-
token.value = "".join(_unichr(int(_)) for _ in match.group(1).replace(' ', "").split(','))
1093+
token.name, token.value = match.group("name"), match.group("value")
10881094

1089-
if not token:
1090-
if conf.csrfUrl and conf.csrfToken and conf.csrfUrl != conf.url and code == _http_client.OK:
1091-
if headers and "text/plain" in headers.get(HTTP_HEADER.CONTENT_TYPE, ""):
1092-
token.name = conf.csrfToken
1093-
token.value = page
1094-
1095-
if not token and conf.cj and any(re.search(conf.csrfToken, _.name, re.I) for _ in conf.cj):
1096-
for _ in conf.cj:
1097-
if re.search(conf.csrfToken, _.name, re.I):
1098-
token.name, token.value = _.name, _.value
1099-
if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))):
1100-
if post:
1101-
post = "%s%s%s=%s" % (post, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
1102-
elif get:
1103-
get = "%s%s%s=%s" % (get, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
1104-
else:
1105-
get = "%s=%s" % (token.name, token.value)
1106-
break
1095+
match = re.search(r"String\.fromCharCode\(([\d+, ]+)\)", token.value)
1096+
if match:
1097+
token.value = "".join(_unichr(int(_)) for _ in match.group(1).replace(' ', "").split(','))
11071098

11081099
if not token:
1109-
errMsg = "anti-CSRF token '%s' can't be found at '%s'" % (conf.csrfToken._original, conf.csrfUrl or conf.url)
1110-
if not conf.csrfUrl:
1111-
errMsg += ". You can try to rerun by providing "
1112-
errMsg += "a valid value for option '--csrf-url'"
1113-
raise SqlmapTokenException(errMsg)
1100+
if conf.csrfUrl and conf.csrfToken and conf.csrfUrl != conf.url and code == _http_client.OK:
1101+
if headers and "text/plain" in headers.get(HTTP_HEADER.CONTENT_TYPE, ""):
1102+
token.name = conf.csrfToken
1103+
token.value = page
1104+
1105+
if not token and conf.cj and any(re.search(conf.csrfToken, _.name, re.I) for _ in conf.cj):
1106+
for _ in conf.cj:
1107+
if re.search(conf.csrfToken, _.name, re.I):
1108+
token.name, token.value = _.name, _.value
1109+
if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))):
1110+
if post:
1111+
post = "%s%s%s=%s" % (post, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
1112+
elif get:
1113+
get = "%s%s%s=%s" % (get, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
1114+
else:
1115+
get = "%s=%s" % (token.name, token.value)
1116+
break
1117+
1118+
if not token:
1119+
errMsg = "anti-CSRF token '%s' can't be found at '%s'" % (conf.csrfToken._original, conf.csrfUrl or conf.url)
1120+
if not conf.csrfUrl:
1121+
errMsg += ". You can try to rerun by providing "
1122+
errMsg += "a valid value for option '--csrf-url'"
1123+
raise SqlmapTokenException(errMsg)
11141124

11151125
if token:
11161126
token.value = token.value.strip("'\"")

sqlmap.conf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ csrfUrl =
189189
# HTTP method to use during anti-CSRF token page visit.
190190
csrfMethod =
191191

192+
# Retries for anti-CSRF token retrieval.
193+
csrfRetries =
194+
192195
# Force usage of SSL/HTTPS
193196
# Valid: True or False
194197
forceSSL = False

0 commit comments

Comments
 (0)