Implementation for an Issue #2

This commit is contained in:
Miroslav Stampar 2014-10-23 11:23:53 +02:00
parent 8dcad46805
commit fc1b05bec9
6 changed files with 51 additions and 1 deletions

View File

@ -457,6 +457,12 @@ def start():
infoMsg = "skipping %s parameter '%s'" % (place, parameter)
logger.info(infoMsg)
elif parameter == conf.csrfToken:
testSqlInj = False
infoMsg = "skipping CSRF protection token parameter '%s'" % parameter
logger.info(infoMsg)
# Ignore session-like parameters for --level < 4
elif conf.level < 4 and (parameter.upper() in IGNORE_PARAMETERS or parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX)):
testSqlInj = False

View File

@ -53,6 +53,9 @@ class SqlmapSyntaxException(SqlmapBaseException):
class SqlmapThreadException(SqlmapBaseException):
pass
class SqlmapTokenException(SqlmapBaseException):
pass
class SqlmapUndefinedMethod(SqlmapBaseException):
pass

View File

@ -344,6 +344,12 @@ def _setRequestParams():
errMsg += "within the given request data"
raise SqlmapGenericException(errMsg)
if conf.csrfToken:
if not any(conf.csrfToken in _ for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))):
errMsg = "CSRF protection token parameter '%s' not " % conf.csrfToken
errMsg += "found in provided GET and/or POST values"
raise SqlmapGenericException(errMsg)
def _setHashDB():
"""
Check and set the HashDB SQLite file for query resume functionality.

View File

@ -190,6 +190,12 @@ def cmdLineParser():
action="store_true",
help="Skip URL encoding of payload data")
request.add_option("--csrf-token", dest="csrfToken",
help="Parameter used as a CSRF protection token")
request.add_option("--csrf-url", dest="csrfUrl",
help="URL address to visit to extract CSRF protection token")
request.add_option("--force-ssl", dest="forceSSL",
action="store_true",
help="Force usage of SSL/HTTPS")

View File

@ -106,7 +106,7 @@ def forgeHeaders(items=None):
elif not kb.testMode:
headers[HTTP_HEADER.COOKIE] += "%s %s=%s" % (conf.cookieDel or DEFAULT_COOKIE_DELIMITER, cookie.name, getUnicode(cookie.value))
if kb.testMode:
if kb.testMode and not conf.csrfToken:
resetCookieJar(conf.cj)
return headers

View File

@ -63,6 +63,7 @@ from lib.core.enums import WEB_API
from lib.core.exception import SqlmapCompressionException
from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapSyntaxException
from lib.core.exception import SqlmapTokenException
from lib.core.exception import SqlmapValueException
from lib.core.settings import ASTERISK_MARKER
from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR
@ -748,6 +749,34 @@ class Connect(object):
if value and place == PLACE.CUSTOM_HEADER:
auxHeaders[value.split(',')[0]] = value.split(',', 1)[1]
if conf.csrfToken:
def _adjustParameter(paramString, parameter, newValue):
retVal = paramString
match = re.search("%s=(?P<value>[^&]*)" % parameter, paramString)
if match:
origValue = match.group("value")
retVal = re.sub("%s=[^&]*" % parameter, "%s=%s" % (parameter, newValue), paramString)
return retVal
page, _, _ = Connect.getPage(url=conf.csrfUrl or conf.url, 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"<input[^>]+name=[\"']?%s[\"']?\s[^>]*value=(\"([^\"]+)|'([^']+)|([^ >]+))" % conf.csrfToken, page)
token = (match.group(2) or match.group(3) or match.group(4)) if match else None
if not token:
errMsg = "CSRF token value '%s' can't be found at '%s'" % (conf.csrfToken, 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:
for item in (PLACE.GET, PLACE.POST):
if item in conf.parameters:
if item == PLACE.GET and get:
get = _adjustParameter(get, conf.csrfToken, token)
elif item == PLACE.POST and post:
post = _adjustParameter(post, conf.csrfToken, token)
if conf.rParam:
def _randomizeParameter(paramString, randomParameter):
retVal = paramString