mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-07-28 09:00:08 +03:00
added star wildcard to csrf token
This commit is contained in:
parent
f04584bb68
commit
da2d5b7b3d
|
@ -470,7 +470,21 @@ def start():
|
||||||
|
|
||||||
paramType = conf.method if conf.method not in (None, HTTPMETHOD.GET, HTTPMETHOD.POST) else place
|
paramType = conf.method if conf.method not in (None, HTTPMETHOD.GET, HTTPMETHOD.POST) else place
|
||||||
|
|
||||||
|
# Creating csrf token pattern
|
||||||
|
csrfTokenPattern = r""
|
||||||
|
strings = conf.csrfToken.split("*")
|
||||||
|
for index, string in enumerate(strings):
|
||||||
|
csrfTokenPattern += re.escape(string)
|
||||||
|
if index < len(strings) - 1:
|
||||||
|
csrfTokenPattern += ".*"
|
||||||
|
|
||||||
for parameter, value in paramDict.items():
|
for parameter, value in paramDict.items():
|
||||||
|
# Csrf parameter should never be injected
|
||||||
|
if (re.match(csrfTokenPattern, parameter)):
|
||||||
|
infoMsg = "skipping csrf parameter '%s'" % parameter
|
||||||
|
logger.info(infoMsg)
|
||||||
|
continue
|
||||||
|
|
||||||
if not proceed:
|
if not proceed:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
|
@ -2341,6 +2341,7 @@ def _basicOptionValidation():
|
||||||
errMsg = "option '--safe-req' is incompatible with option '--safe-url' and option '--safe-post'"
|
errMsg = "option '--safe-req' is incompatible with option '--safe-url' and option '--safe-post'"
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
|
conf.originalCsrfToken = conf.csrfToken
|
||||||
if conf.csrfUrl and not conf.csrfToken:
|
if conf.csrfUrl and not conf.csrfToken:
|
||||||
errMsg = "option '--csrf-url' requires usage of option '--csrf-token'"
|
errMsg = "option '--csrf-url' requires usage of option '--csrf-token'"
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
|
@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
|
||||||
from lib.core.enums import OS
|
from lib.core.enums import OS
|
||||||
|
|
||||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||||
VERSION = "1.2.12.0"
|
VERSION = "1.2.11.19"
|
||||||
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)
|
||||||
|
|
|
@ -393,7 +393,20 @@ def _setRequestParams():
|
||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
|
|
||||||
if conf.csrfToken:
|
if conf.csrfToken:
|
||||||
if not any(conf.csrfToken in _ for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))) and not re.search(r"\b%s\b" % re.escape(conf.csrfToken), conf.data or "") and conf.csrfToken not in set(_[0].lower() for _ in conf.httpHeaders) and conf.csrfToken not in conf.paramDict.get(PLACE.COOKIE, {}):
|
csrfTokenPattern = ""
|
||||||
|
strings = conf.csrfToken.split("*")
|
||||||
|
for index, string in enumerate(strings):
|
||||||
|
csrfTokenPattern += re.escape(string)
|
||||||
|
if index < len(strings) - 1:
|
||||||
|
csrfTokenPattern += ".*"
|
||||||
|
|
||||||
|
def csrfTokenAppearsInGetOrPost():
|
||||||
|
for params in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {})):
|
||||||
|
for paramKey in params:
|
||||||
|
if re.search(r"\b%s\b" % csrfTokenPattern, paramKey):
|
||||||
|
return True
|
||||||
|
|
||||||
|
if not csrfTokenAppearsInGetOrPost() and not re.search(r"\b%s\b" % re.escape(conf.csrfToken), conf.data or "") and conf.csrfToken not in set(_[0].lower() for _ in conf.httpHeaders) and conf.csrfToken not in conf.paramDict.get(PLACE.COOKIE, {}):
|
||||||
errMsg = "anti-CSRF token parameter '%s' not " % conf.csrfToken
|
errMsg = "anti-CSRF token parameter '%s' not " % conf.csrfToken
|
||||||
errMsg += "found in provided GET, POST, Cookie or header values"
|
errMsg += "found in provided GET, POST, Cookie or header values"
|
||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
|
|
|
@ -61,6 +61,7 @@ from lib.core.common import unicodeencode
|
||||||
from lib.core.common import unsafeVariableNaming
|
from lib.core.common import unsafeVariableNaming
|
||||||
from lib.core.common import urldecode
|
from lib.core.common import urldecode
|
||||||
from lib.core.common import urlencode
|
from lib.core.common import urlencode
|
||||||
|
from lib.core.common import paramToDict
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
|
@ -228,7 +229,6 @@ class Connect(object):
|
||||||
This method connects to the target URL or proxy and returns
|
This method connects to the target URL or proxy and returns
|
||||||
the target URL page content
|
the target URL page content
|
||||||
"""
|
"""
|
||||||
|
|
||||||
start = time.time()
|
start = time.time()
|
||||||
|
|
||||||
if isinstance(conf.delay, (int, float)) and conf.delay > 0:
|
if isinstance(conf.delay, (int, float)) and conf.delay > 0:
|
||||||
|
@ -771,6 +771,11 @@ class Connect(object):
|
||||||
if not multipart:
|
if not multipart:
|
||||||
logger.log(CUSTOM_LOGGING.TRAFFIC_IN, responseMsg)
|
logger.log(CUSTOM_LOGGING.TRAFFIC_IN, responseMsg)
|
||||||
|
|
||||||
|
#if "Invalid csrf token." in page:
|
||||||
|
# print "INVALID CSRF TOKEN"
|
||||||
|
#else:
|
||||||
|
# print "Valid CSRF Token"
|
||||||
|
|
||||||
return page, responseHeaders, code
|
return page, responseHeaders, code
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -781,7 +786,7 @@ class Connect(object):
|
||||||
and returns its page ratio (0 <= ratio <= 1) or a boolean value
|
and returns its page ratio (0 <= ratio <= 1) or a boolean value
|
||||||
representing False/True match in case of !getRatioValue
|
representing False/True match in case of !getRatioValue
|
||||||
"""
|
"""
|
||||||
|
#print "queryPage()"
|
||||||
if conf.direct:
|
if conf.direct:
|
||||||
return direct(value, content)
|
return direct(value, content)
|
||||||
|
|
||||||
|
@ -970,7 +975,99 @@ class Connect(object):
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=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))
|
page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=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))
|
||||||
token = extractRegexResult(r"(?i)<input[^>]+\bname=[\"']?%s\b[^>]*\bvalue=[\"']?(?P<result>[^>'\"]*)" % re.escape(conf.csrfToken), page or "")
|
|
||||||
|
# Adjustments for csrf tokens with the star wildcard
|
||||||
|
conf.csrfToken = conf.originalCsrfToken
|
||||||
|
if "*" in conf.csrfToken:
|
||||||
|
csrfTokenPattern = r""
|
||||||
|
strings = conf.csrfToken.split("*")
|
||||||
|
for index, string in enumerate(strings):
|
||||||
|
csrfTokenPattern += re.escape(string)
|
||||||
|
if index < len(strings) - 1:
|
||||||
|
csrfTokenPattern += ".*"
|
||||||
|
|
||||||
|
csrfTokenKey = extractRegexResult(
|
||||||
|
r"(?i)<input[^>]+\bname=[\"']?(?P<result>%s)\b[^>]*\bvalue=[\"']?[^>'\"]*" % csrfTokenPattern,
|
||||||
|
page or "")[:-2]
|
||||||
|
|
||||||
|
if not csrfTokenKey:
|
||||||
|
if get:
|
||||||
|
for key, value in urlparse.parse_qs(conf.parameters[PLACE.GET]).items():
|
||||||
|
if re.search(r"\b%s\b" % csrfTokenPattern, key):
|
||||||
|
csrfTokenKey = key
|
||||||
|
break
|
||||||
|
elif post:
|
||||||
|
for key, value in urlparse.parse_qs(conf.parameters[PLACE.POST]).items():
|
||||||
|
if re.search(r"\b%s\b" % csrfTokenPattern, key):
|
||||||
|
csrfTokenKey = key
|
||||||
|
break
|
||||||
|
|
||||||
|
if csrfTokenKey:
|
||||||
|
conf.csrfToken = csrfTokenKey
|
||||||
|
|
||||||
|
token = extractRegexResult(r"(?i)<input[^>]+\bname=[\"']?%s\b[^>]*\bvalue=[\"']?(?P<result>[^>'\"]*)" % re.escape(conf.csrfToken), page or "")
|
||||||
|
|
||||||
|
# A fix for urlencoder to give %20
|
||||||
|
# See: https://bugs.python.org/issue13866
|
||||||
|
urllib.quote_plus = urllib.quote
|
||||||
|
|
||||||
|
# Overwriting parameters for new csrf token key/ value...
|
||||||
|
if PLACE.GET in conf.parameters:
|
||||||
|
getParamsDict = dict(urlparse.parse_qsl(conf.parameters[PLACE.GET]))
|
||||||
|
for key, value in getParamsDict.iteritems():
|
||||||
|
if re.search(r"\b%s\b" % csrfTokenPattern, key):
|
||||||
|
getParamsDict[conf.csrfToken] = token
|
||||||
|
if key != conf.csrfToken:
|
||||||
|
del getParamsDict[key]
|
||||||
|
break
|
||||||
|
conf.parameters[PLACE.GET] = urllib.urlencode(getParamsDict)
|
||||||
|
|
||||||
|
for key, value in conf.paramDict[PLACE.GET].items():
|
||||||
|
if re.search(r"\b%s\b" % csrfTokenPattern, key):
|
||||||
|
conf.paramDict[PLACE.GET][conf.csrfToken] = token
|
||||||
|
if key != conf.csrfToken:
|
||||||
|
del conf.paramDict[PLACE.GET][key]
|
||||||
|
break
|
||||||
|
|
||||||
|
getDict = dict(urlparse.parse_qsl(get))
|
||||||
|
for key, value in getDict.iteritems():
|
||||||
|
if re.search(r"\b%s\b" % csrfTokenPattern, key):
|
||||||
|
getDict[conf.csrfToken] = token
|
||||||
|
if key != conf.csrfToken:
|
||||||
|
del getDict[key]
|
||||||
|
break
|
||||||
|
get = urllib.urlencode(getDict)
|
||||||
|
|
||||||
|
if PLACE.POST in conf.parameters:
|
||||||
|
postParamsDict = dict(urlparse.parse_qsl(conf.parameters[PLACE.POST]))
|
||||||
|
for key, value in postParamsDict.iteritems():
|
||||||
|
if re.search(r"\b%s\b" % csrfTokenPattern, key):
|
||||||
|
postParamsDict[conf.csrfToken] = token
|
||||||
|
if key != conf.csrfToken:
|
||||||
|
del postParamsDict[key]
|
||||||
|
break
|
||||||
|
conf.parameters[PLACE.POST] = urllib.urlencode(postParamsDict)
|
||||||
|
|
||||||
|
for key, value in conf.paramDict[PLACE.POST].items():
|
||||||
|
if re.search(r"\b%s\b" % csrfTokenPattern, key):
|
||||||
|
conf.paramDict[PLACE.POST][conf.csrfToken] = token
|
||||||
|
if key != conf.csrfToken:
|
||||||
|
del conf.paramDict[PLACE.POST][key]
|
||||||
|
break
|
||||||
|
|
||||||
|
postDict = dict(urlparse.parse_qsl(post))
|
||||||
|
for key, value in postDict.iteritems():
|
||||||
|
if re.search(r"\b%s\b" % csrfTokenPattern, key):
|
||||||
|
postDict[conf.csrfToken] = token
|
||||||
|
if key != conf.csrfToken:
|
||||||
|
del postDict[key]
|
||||||
|
break
|
||||||
|
post = urllib.urlencode(postDict)
|
||||||
|
else:
|
||||||
|
token = extractRegexResult(
|
||||||
|
r"(?i)<input[^>]+\bname=[\"']?%s\b[^>]*\bvalue=[\"']?(?P<result>[^>'\"]*)" % re.escape(conf.csrfToken),
|
||||||
|
page or "")
|
||||||
|
|
||||||
|
|
||||||
if not token:
|
if not token:
|
||||||
token = extractRegexResult(r"(?i)<input[^>]+\bvalue=[\"']?(?P<result>[^>'\"]*)[\"']?[^>]*\bname=[\"']?%s\b" % re.escape(conf.csrfToken), page or "")
|
token = extractRegexResult(r"(?i)<input[^>]+\bvalue=[\"']?(?P<result>[^>'\"]*)[\"']?[^>]*\bname=[\"']?%s\b" % re.escape(conf.csrfToken), page or "")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user