mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-22 09:36:35 +03:00
Added --code switch to match in boolean-based tests against the HTTP response code
This commit is contained in:
parent
e34787db99
commit
702ed73a65
|
@ -898,7 +898,7 @@ def checkNullConnection():
|
|||
logger.info(infoMsg)
|
||||
|
||||
try:
|
||||
page, headers = Request.getPage(method=HTTPMETHOD.HEAD)
|
||||
page, headers, _ = Request.getPage(method=HTTPMETHOD.HEAD)
|
||||
|
||||
if not page and HTTPHEADER.CONTENT_LENGTH in headers:
|
||||
kb.nullConnection = NULLCONNECTION.HEAD
|
||||
|
@ -906,7 +906,7 @@ def checkNullConnection():
|
|||
infoMsg = "NULL connection is supported with HEAD header"
|
||||
logger.info(infoMsg)
|
||||
else:
|
||||
page, headers = Request.getPage(auxHeaders={HTTPHEADER.RANGE: "bytes=-1"})
|
||||
page, headers, _ = Request.getPage(auxHeaders={HTTPHEADER.RANGE: "bytes=-1"})
|
||||
|
||||
if page and len(page) == 1 and HTTPHEADER.CONTENT_RANGE in headers:
|
||||
kb.nullConnection = NULLCONNECTION.RANGE
|
||||
|
|
|
@ -1330,6 +1330,9 @@ def __cleanupOptions():
|
|||
else:
|
||||
kb.adjustTimeDelay = False
|
||||
|
||||
if conf.code:
|
||||
conf.code = int(conf.code)
|
||||
|
||||
def __setConfAttributes():
|
||||
"""
|
||||
This function set some needed attributes into the configuration
|
||||
|
|
|
@ -68,6 +68,7 @@ optDict = {
|
|||
"risk": "integer",
|
||||
"string": "string",
|
||||
"regexp": "string",
|
||||
"code": "string",
|
||||
"textOnly": "boolean",
|
||||
"titles": "boolean"
|
||||
},
|
||||
|
|
|
@ -200,13 +200,16 @@ def cmdLineParser():
|
|||
"default %d)" % defaults.level)
|
||||
|
||||
detection.add_option("--string", dest="string",
|
||||
help="String to match in page when the "
|
||||
help="String to match in the response when "
|
||||
"query is valid")
|
||||
|
||||
detection.add_option("--regexp", dest="regexp",
|
||||
help="Regexp to match in page when the "
|
||||
help="Regexp to match in the response when "
|
||||
"query is valid")
|
||||
|
||||
detection.add_option("--code", dest="code", type="int",
|
||||
help="HTTP response code to match when the query is valid")
|
||||
|
||||
detection.add_option("--text-only", dest="textOnly",
|
||||
action="store_true",
|
||||
help="Compare pages based only on the textual content")
|
||||
|
|
|
@ -28,7 +28,7 @@ from lib.core.settings import LOWER_RATIO_BOUND
|
|||
from lib.core.settings import UPPER_RATIO_BOUND
|
||||
from lib.core.threads import getCurrentThreadData
|
||||
|
||||
def comparison(page, headers, getRatioValue=False, pageLength=None):
|
||||
def comparison(page, headers, code=None, getRatioValue=False, pageLength=None):
|
||||
if page is None and pageLength is None:
|
||||
return None
|
||||
|
||||
|
@ -50,6 +50,9 @@ def comparison(page, headers, getRatioValue=False, pageLength=None):
|
|||
condition = re.search(conf.regexp, rawResponse, re.I | re.M) is not None
|
||||
return condition if not getRatioValue else (MAX_RATIO if condition else MIN_RATIO)
|
||||
|
||||
if isinstance(code, int) and conf.code:
|
||||
return code == conf.code
|
||||
|
||||
if page:
|
||||
# In case of an DBMS error page return None
|
||||
if kb.errorIsNone and (wasLastRequestDBMSError() or wasLastRequestHTTPError()):
|
||||
|
|
|
@ -306,7 +306,7 @@ class Connect:
|
|||
|
||||
# Return response object
|
||||
if response:
|
||||
return conn, None
|
||||
return conn, None, None
|
||||
|
||||
# Get HTTP response
|
||||
page = conn.read()
|
||||
|
@ -369,7 +369,7 @@ class Connect:
|
|||
warnMsg = "connection timed out while trying "
|
||||
warnMsg += "to get error page information (%d)" % e.code
|
||||
logger.warn(warnMsg)
|
||||
return None, None
|
||||
return None, None, None
|
||||
except:
|
||||
pass
|
||||
|
||||
|
@ -409,7 +409,7 @@ class Connect:
|
|||
processResponse(page, responseHeaders)
|
||||
elif e.code == 504:
|
||||
if ignoreTimeout:
|
||||
return None, None
|
||||
return None, None, None
|
||||
else:
|
||||
warnMsg = "unable to connect to the target url (%d - %s)" % (e.code, httplib.responses[e.code])
|
||||
if threadData.retriesCount < conf.retries and not kb.threadException and not conf.realTest:
|
||||
|
@ -418,14 +418,14 @@ class Connect:
|
|||
return Connect.__retryProxy(**kwargs)
|
||||
elif kb.testMode:
|
||||
logger.critical(warnMsg)
|
||||
return None, None
|
||||
return None, None, None
|
||||
else:
|
||||
raise sqlmapConnectionException, warnMsg
|
||||
else:
|
||||
debugMsg = "got HTTP error code: %d (%s)" % (code, status)
|
||||
logger.debug(debugMsg)
|
||||
processResponse(page, responseHeaders)
|
||||
return page, responseHeaders
|
||||
return page, responseHeaders, code
|
||||
|
||||
except (urllib2.URLError, socket.error, socket.timeout, httplib.BadStatusLine, httplib.IncompleteRead), e:
|
||||
tbMsg = traceback.format_exc()
|
||||
|
@ -454,16 +454,16 @@ class Connect:
|
|||
|
||||
if "forcibly closed" in tbMsg:
|
||||
logger.critical(warnMsg)
|
||||
return None, None
|
||||
return None, None, None
|
||||
elif silent or (ignoreTimeout and any(map(lambda x: x in tbMsg, ["timed out", "IncompleteRead"]))):
|
||||
return None, None
|
||||
return None, None, None
|
||||
elif threadData.retriesCount < conf.retries and not kb.threadException and not conf.realTest:
|
||||
warnMsg += ", sqlmap is going to retry the request"
|
||||
logger.critical(warnMsg)
|
||||
return Connect.__retryProxy(**kwargs)
|
||||
elif kb.testMode:
|
||||
logger.critical(warnMsg)
|
||||
return None, None
|
||||
return None, None, None
|
||||
else:
|
||||
raise sqlmapConnectionException, warnMsg
|
||||
|
||||
|
@ -485,7 +485,7 @@ class Connect:
|
|||
|
||||
logger.log(7, responseMsg)
|
||||
|
||||
return page, responseHeaders
|
||||
return page, responseHeaders, code
|
||||
|
||||
@staticmethod
|
||||
def queryPage(value=None, place=None, content=False, getRatioValue=False, silent=False, method=None, timeBasedCompare=False, noteResponseTime=True, auxHeaders=None, response=False, raise404=None):
|
||||
|
@ -613,7 +613,7 @@ class Connect:
|
|||
|
||||
auxHeaders[HTTPHEADER.RANGE] = "bytes=-1"
|
||||
|
||||
_, headers = Connect.getPage(url=uri, get=get, post=post, cookie=cookie, ua=ua, referer=referer, silent=silent, method=method, auxHeaders=auxHeaders, raise404=raise404)
|
||||
_, headers, code = Connect.getPage(url=uri, get=get, post=post, cookie=cookie, ua=ua, referer=referer, silent=silent, method=method, auxHeaders=auxHeaders, raise404=raise404)
|
||||
|
||||
if headers:
|
||||
if kb.nullConnection == NULLCONNECTION.HEAD and HTTPHEADER.CONTENT_LENGTH in headers:
|
||||
|
@ -622,7 +622,7 @@ class Connect:
|
|||
pageLength = int(headers[HTTPHEADER.CONTENT_RANGE][headers[HTTPHEADER.CONTENT_RANGE].find('/') + 1:])
|
||||
|
||||
if not pageLength:
|
||||
page, headers = Connect.getPage(url=uri, get=get, post=post, cookie=cookie, ua=ua, referer=referer, silent=silent, method=method, auxHeaders=auxHeaders, response=response, raise404=raise404, ignoreTimeout=timeBasedCompare)
|
||||
page, headers, code = Connect.getPage(url=uri, get=get, post=post, cookie=cookie, ua=ua, referer=referer, silent=silent, method=method, auxHeaders=auxHeaders, response=response, raise404=raise404, ignoreTimeout=timeBasedCompare)
|
||||
|
||||
threadData.lastQueryDuration = calculateDeltaSeconds(start)
|
||||
|
||||
|
@ -643,8 +643,8 @@ class Connect:
|
|||
page = removeReflectiveValues(page, payload)
|
||||
|
||||
if getRatioValue:
|
||||
return comparison(page, headers, getRatioValue=False, pageLength=pageLength), comparison(page, headers, getRatioValue=True, pageLength=pageLength)
|
||||
return comparison(page, headers, code, getRatioValue=False, pageLength=pageLength), comparison(page, headers, code, getRatioValue=True, pageLength=pageLength)
|
||||
elif pageLength or page:
|
||||
return comparison(page, headers, getRatioValue, pageLength)
|
||||
return comparison(page, headers, code, getRatioValue, pageLength)
|
||||
else:
|
||||
return False
|
||||
|
|
|
@ -62,7 +62,7 @@ class Web:
|
|||
cmd = conf.osCmd
|
||||
|
||||
cmdUrl = "%s?cmd=%s" % (self.webBackdoorUrl, cmd)
|
||||
page, _ = Request.getPage(url=cmdUrl, direct=True, silent=True)
|
||||
page, _, _ = Request.getPage(url=cmdUrl, direct=True, silent=True)
|
||||
|
||||
if page is not None:
|
||||
output = re.search("<pre>(.+?)</pre>", page, re.I | re.S)
|
||||
|
@ -237,7 +237,7 @@ class Web:
|
|||
self.webBaseUrl = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, uriPath)
|
||||
self.webStagerUrl = "%s/%s" % (self.webBaseUrl, stagerName)
|
||||
|
||||
uplPage, _ = Request.getPage(url=self.webStagerUrl, direct=True, raise404=False)
|
||||
uplPage, _, _ = Request.getPage(url=self.webStagerUrl, direct=True, raise404=False)
|
||||
|
||||
if "sqlmap file uploader" not in uplPage:
|
||||
if localPath not in warned:
|
||||
|
|
|
@ -109,7 +109,7 @@ def __findUnionCharCount(comment, place, parameter, value, prefix, suffix, where
|
|||
query = agent.forgeInbandQuery('', -1, count, comment, prefix, suffix, kb.uChar)
|
||||
payload = agent.payload(place=place, parameter=parameter, newValue=query, where=where)
|
||||
page, headers = Request.queryPage(payload, place=place, content=True, raise404=False)
|
||||
ratio = comparison(page, headers, True) or MIN_RATIO
|
||||
ratio = comparison(page, headers, getRatioValue=True) or MIN_RATIO
|
||||
ratios.append(ratio)
|
||||
min_, max_ = min(min_, ratio), max(max_, ratio)
|
||||
items.append((count, ratio))
|
||||
|
|
10
sqlmap.conf
10
sqlmap.conf
|
@ -204,12 +204,12 @@ level = 1
|
|||
# Default: 1
|
||||
risk = 1
|
||||
|
||||
# String to match within the page content when the query is valid, only
|
||||
# String to match within the raw response when the query is valid, only
|
||||
# needed if the page content dynamically changes at each refresh.
|
||||
# Refer to the user's manual for further details.
|
||||
string =
|
||||
|
||||
# Regular expression to match within the page content when the query is
|
||||
# Regular expression to match within the raw response when the query is
|
||||
# valid, only needed if the needed if the page content dynamically changes
|
||||
# at each refresh.
|
||||
# Refer to the user's manual for further details.
|
||||
|
@ -217,6 +217,12 @@ string =
|
|||
# (http://www.python.org/doc/2.5.2/lib/re-syntax.html)
|
||||
regexp =
|
||||
|
||||
# HTTP response code to match when the query is valid
|
||||
# Valid: True or False
|
||||
# Example: 200 (assuming any False statement returns a different response
|
||||
# code)
|
||||
code =
|
||||
|
||||
# Compare pages based only on the textual content
|
||||
# Valid: True or False
|
||||
textOnly = False
|
||||
|
|
Loading…
Reference in New Issue
Block a user