mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-01-24 08:14:24 +03:00
Code refactoring and cosmetics
This commit is contained in:
parent
a8d660db54
commit
1c86ec374e
|
@ -185,6 +185,7 @@ def start():
|
|||
testSqlInj = True
|
||||
|
||||
testSqlInj &= (conf.hostname, conf.path, None, None) not in kb.testedParams
|
||||
|
||||
if not testSqlInj:
|
||||
infoMsg = "skipping '%s'" % targetUrl
|
||||
logger.info(infoMsg)
|
||||
|
|
|
@ -1789,13 +1789,14 @@ def findDynamicContent(firstPage, secondPage):
|
|||
|
||||
def removeDynamicContent(page):
|
||||
"""
|
||||
Removing dynamic content from supplied
|
||||
page basing removal on precalculated
|
||||
dynamic markings
|
||||
Removing dynamic content from supplied page basing removal on
|
||||
precalculated dynamic markings
|
||||
"""
|
||||
|
||||
if page:
|
||||
for item in kb.dynamicMarkings:
|
||||
prefix, suffix = item
|
||||
|
||||
if prefix is None and suffix is None:
|
||||
continue
|
||||
elif prefix is None:
|
||||
|
@ -1809,10 +1810,10 @@ def removeDynamicContent(page):
|
|||
|
||||
def filterStringValue(value, regex, replace=None):
|
||||
"""
|
||||
Returns string value consisting only
|
||||
of chars satisfying supplied regular
|
||||
expressson
|
||||
Returns string value consisting only of chars satisfying supplied
|
||||
regular expression
|
||||
"""
|
||||
|
||||
retVal = ""
|
||||
|
||||
if value:
|
||||
|
@ -1826,16 +1827,17 @@ def filterStringValue(value, regex, replace=None):
|
|||
|
||||
def filterControlChars(value):
|
||||
"""
|
||||
Returns string value with control
|
||||
chars being supstituted with ' '
|
||||
Returns string value with control chars being supstituted with ' '
|
||||
"""
|
||||
|
||||
return filterStringValue(value, NON_CONTROL_CHAR_REGEX, ' ')
|
||||
|
||||
def isDBMSVersionAtLeast(version):
|
||||
"""
|
||||
Checks if the recognized DBMS version
|
||||
is at least the version specified
|
||||
Checks if the recognized DBMS version is at least the version
|
||||
specified
|
||||
"""
|
||||
|
||||
retVal = None
|
||||
|
||||
if kb.dbmsVersion and kb.dbmsVersion[0] != UNKNOWN_DBMS_VERSION and kb.dbmsVersion[0] != None:
|
||||
|
@ -1843,6 +1845,7 @@ def isDBMSVersionAtLeast(version):
|
|||
|
||||
while True:
|
||||
index = value.find('.', value.find('.') + 1)
|
||||
|
||||
if index > -1:
|
||||
value = value[0:index] + value[index + 1:]
|
||||
else:
|
||||
|
@ -1866,9 +1869,9 @@ def isDBMSVersionAtLeast(version):
|
|||
|
||||
def parseSqliteTableSchema(value):
|
||||
"""
|
||||
Parses table column names and types from
|
||||
specified SQLite table schema
|
||||
Parses table column names and types from specified SQLite table schema
|
||||
"""
|
||||
|
||||
if value:
|
||||
table = {}
|
||||
columns = {}
|
||||
|
@ -1883,6 +1886,7 @@ def getTechniqueData(technique=None):
|
|||
"""
|
||||
Returns injection data for technique specified
|
||||
"""
|
||||
|
||||
retVal = None
|
||||
|
||||
if technique and technique in kb.injection.data:
|
||||
|
@ -1892,16 +1896,17 @@ def getTechniqueData(technique=None):
|
|||
|
||||
def isTechniqueAvailable(technique=None):
|
||||
"""
|
||||
Returns True if there is injection data which
|
||||
sqlmap could use for technique specified
|
||||
Returns True if there is injection data which sqlmap could use for
|
||||
technique specified
|
||||
"""
|
||||
|
||||
return getTechniqueData(technique) is not None
|
||||
|
||||
def initTechnique(technique=None):
|
||||
"""
|
||||
Prepares proper page template and match ratio
|
||||
for technique specified
|
||||
Prepares proper page template and match ratio for technique specified
|
||||
"""
|
||||
|
||||
data = getTechniqueData(technique)
|
||||
|
||||
if data:
|
||||
|
@ -1914,77 +1919,87 @@ def initTechnique(technique=None):
|
|||
|
||||
def arrayizeValue(value):
|
||||
"""
|
||||
Makes a list out of value if it's not already
|
||||
list itself
|
||||
Makes a list out of value if it is not already a list, tuple or set
|
||||
itself
|
||||
"""
|
||||
if not isinstance(value, list):
|
||||
value = [value]
|
||||
|
||||
if not isinstance(value, (list, tuple, set)):
|
||||
value = [ value ]
|
||||
|
||||
return value
|
||||
|
||||
def getInjectionTests():
|
||||
"""
|
||||
Returns prioritized test list by eventually
|
||||
detected DBMS from error messages
|
||||
Returns prioritized test list by eventually detected DBMS from error
|
||||
messages
|
||||
"""
|
||||
|
||||
retVal = conf.tests
|
||||
|
||||
if getErrorParsedDBMSes():
|
||||
retVal = sorted(retVal, key=lambda test: False\
|
||||
if 'details' in test and 'dbms' in test.details\
|
||||
retVal = sorted(retVal, key=lambda test: False \
|
||||
if 'details' in test and 'dbms' in test.details \
|
||||
and test.details.dbms in getErrorParsedDBMSes() else True)
|
||||
|
||||
return retVal
|
||||
|
||||
def filterListValue(value, regex):
|
||||
"""
|
||||
Returns list with items that have parts
|
||||
satisfying given regular expression
|
||||
Returns list with items that have parts satisfying given regular
|
||||
expression
|
||||
"""
|
||||
|
||||
if regex:
|
||||
retVal = []
|
||||
filter = getCompiledRegex(regex, re.I)
|
||||
|
||||
for word in value:
|
||||
if filter.search(word):
|
||||
retVal.append(word)
|
||||
|
||||
return retVal
|
||||
else:
|
||||
return value
|
||||
|
||||
def unicodeToSafeHTMLValue(value):
|
||||
"""
|
||||
Returns HTML representation of unicode
|
||||
string value safe for sending over HTTP(s)
|
||||
Returns HTML representation of unicode string value safe for sending
|
||||
over HTTP(s)
|
||||
"""
|
||||
|
||||
retVal = value
|
||||
|
||||
if value:
|
||||
for char in value:
|
||||
if ord(char) > 127:
|
||||
retVal = retVal.replace(char, "&#%d;" % ord(char))
|
||||
|
||||
return retVal
|
||||
|
||||
def getErrorParsedDBMSes():
|
||||
"""
|
||||
Returns array with parsed DBMS
|
||||
names till now
|
||||
Returns array with parsed DBMS names till now
|
||||
"""
|
||||
|
||||
return kb.htmlFp
|
||||
|
||||
def showHttpErrorCodes():
|
||||
"""
|
||||
Shows all HTTP error codes
|
||||
raised till now
|
||||
Shows all HTTP error codes raised till now
|
||||
"""
|
||||
|
||||
if kb.httpErrorCodes:
|
||||
warnMsg = "HTTP error codes detected during testing:\n"
|
||||
warnMsg += ", ".join("%d (%s) - %d times" % (code, httplib.responses[code]\
|
||||
if code in httplib.responses else '?', count)\
|
||||
warnMsg += ", ".join("%d (%s) - %d times" % (code, httplib.responses[code] \
|
||||
if code in httplib.responses else '?', count) \
|
||||
for code, count in kb.httpErrorCodes.items())
|
||||
logger.warn(warnMsg)
|
||||
|
||||
def getComparePageRatio(firstPage, secondPage, filtered=False):
|
||||
"""
|
||||
Returns comparison ratio between
|
||||
two given pages
|
||||
Returns comparison ratio between two given pages
|
||||
"""
|
||||
|
||||
if filtered:
|
||||
firstPage = getFilteredPageContent(firstPage)
|
||||
secondPage = getFilteredPageContent(secondPage)
|
||||
|
|
|
@ -98,6 +98,7 @@ class PAYLOAD:
|
|||
COMPARISON = "comparison"
|
||||
GREP = "grep"
|
||||
TIME = "time"
|
||||
UNION = "union"
|
||||
|
||||
class TECHNIQUE:
|
||||
HEURISTIC = 0
|
||||
|
|
|
@ -12,6 +12,11 @@ from lib.core.datatype import advancedDict
|
|||
|
||||
class Unescaper(advancedDict):
|
||||
def unescape(self, expression, quote=True):
|
||||
return self[kb.dbms if kb.dbms else kb.misc.testedDbms](expression, quote=quote)
|
||||
if hasattr(kb, "dbms") and kb.dbms is not None:
|
||||
return self[kb.dbms if kb.dbms else kb.misc.testedDbms](expression, quote=quote)
|
||||
elif hasattr(kb.misc, "testedDbms") and kb.misc.testedDbms is not None:
|
||||
return self[kb.misc.testedDbms](expression, quote=quote)
|
||||
else:
|
||||
return expression
|
||||
|
||||
unescaper = Unescaper()
|
||||
|
|
|
@ -67,11 +67,12 @@ def parseResponse(page, headers):
|
|||
htmlParser(page)
|
||||
|
||||
# Detect injectable page absolute system path
|
||||
# NOTE: this regular expression works if the remote web application
|
||||
# is written in PHP and debug/error messages are enabled.
|
||||
|
||||
# NOTE: this regular expression works if the remote web
|
||||
# application is written in PHP and debug/error messages are
|
||||
# enabled
|
||||
for regex in ( r" in <b>(?P<result>.*?)</b> on line", r"(?:>|\s)(?P<result>[A-Za-z]:[\\/][\w.\\/]*)", r"(?:>|\s)(?P<result>/\w[/\w.]+)" ):
|
||||
regObj = getCompiledRegex(regex)
|
||||
|
||||
for match in regObj.finditer(page):
|
||||
absFilePath = match.group("result").strip()
|
||||
page = page.replace(absFilePath, "")
|
||||
|
@ -145,10 +146,13 @@ def decodePage(page, contentEncoding, contentType):
|
|||
|
||||
def processResponse(page, responseHeaders):
|
||||
page = getUnicode(page)
|
||||
|
||||
parseResponse(page, responseHeaders)
|
||||
|
||||
if conf.parseErrors:
|
||||
msg = extractErrorMessage(page)
|
||||
|
||||
if msg:
|
||||
logger.info("parsed error message: '%s'" % msg)
|
||||
|
||||
return page
|
||||
|
|
|
@ -428,7 +428,7 @@ class Connect:
|
|||
logger.warn(warnMsg)
|
||||
|
||||
while len(kb.responseTimes) < MIN_TIME_RESPONSES:
|
||||
_ = Connect.queryPage(content=True)
|
||||
Connect.queryPage(content=True)
|
||||
|
||||
if conf.safUrl and conf.saFreq > 0:
|
||||
kb.queryCounter += 1
|
||||
|
|
|
@ -151,8 +151,7 @@ Tag: <test>
|
|||
Sub-tag: <grep>
|
||||
Regular expression to grep for in the response body.
|
||||
|
||||
NOTE: useful to test for error-based and UNION query SQL
|
||||
injections.
|
||||
NOTE: useful to test for error-based SQL injection.
|
||||
|
||||
Sub-tag: <time>
|
||||
Time in seconds to wait before the response is returned.
|
||||
|
@ -160,7 +159,12 @@ Tag: <test>
|
|||
NOTE: useful to test for time-based blind and stacked queries
|
||||
SQL injections.
|
||||
|
||||
Sub-tag: <out-of-band>
|
||||
Sub-tag: <union>
|
||||
Calls unionTest() function.
|
||||
|
||||
NOTE: useful to test for UNION query (inband) SQL injection.
|
||||
|
||||
Sub-tag: <oob>
|
||||
# TODO
|
||||
|
||||
Sub-tag: <details>
|
||||
|
@ -202,6 +206,8 @@ Formats:
|
|||
<comparison></comparison>
|
||||
<grep></grep>
|
||||
<time></time>
|
||||
<union></union>
|
||||
<oob></oob>
|
||||
</response>
|
||||
<details>
|
||||
<dbms></dbms>
|
||||
|
@ -1818,43 +1824,4 @@ Formats:
|
|||
<!-- TODO: if possible, add payload for Microsoft Access and SAP MaxDB -->
|
||||
<!-- End of OR time-based blind tests -->
|
||||
|
||||
<!-- UNION query tests -->
|
||||
<!-- TODO: sure about all these clauses? Verify on every DBMS -->
|
||||
<!--
|
||||
<test>
|
||||
<title>UNION query</title>
|
||||
<stype>3</stype>
|
||||
<level>1</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,2,3,4,5</clause>
|
||||
<where>1</where>
|
||||
<vector>UNION ALL SELECT [UNION_STRING]</vector>
|
||||
<request>
|
||||
<payload>UNION ALL SELECT [UNION_TEST]</payload>
|
||||
<comment></comment>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
</response>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Single-entry UNION query</title>
|
||||
<stype>3</stype>
|
||||
<level>1</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,2,3,4,5</clause>
|
||||
<where>2</where>
|
||||
<vector>UNION ALL SELECT [UNION_STRING]</vector>
|
||||
<request>
|
||||
<payload>UNION ALL SELECT [UNION_TEST]</payload>
|
||||
<comment></comment>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
</response>
|
||||
</test>
|
||||
-->
|
||||
<!-- End of UNION query tests -->
|
||||
|
||||
</root>
|
||||
|
|
Loading…
Reference in New Issue
Block a user