Code refactoring and cosmetics

This commit is contained in:
Bernardo Damele 2011-01-07 15:41:09 +00:00
parent a8d660db54
commit 1c86ec374e
7 changed files with 76 additions and 83 deletions

View File

@ -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)

View File

@ -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)

View File

@ -98,6 +98,7 @@ class PAYLOAD:
COMPARISON = "comparison"
GREP = "grep"
TIME = "time"
UNION = "union"
class TECHNIQUE:
HEURISTIC = 0

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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&lt;result&gt;.*?)[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&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
</test>
-->
<!-- End of UNION query tests -->
</root>