mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-22 17:46:37 +03:00
Merge branch 'master' of github.com:sqlmapproject/sqlmap
This commit is contained in:
commit
6dfe91165d
|
@ -36,8 +36,8 @@ from lib.core.common import readInput
|
||||||
from lib.core.common import showStaticWords
|
from lib.core.common import showStaticWords
|
||||||
from lib.core.common import singleTimeLogMessage
|
from lib.core.common import singleTimeLogMessage
|
||||||
from lib.core.common import singleTimeWarnMessage
|
from lib.core.common import singleTimeWarnMessage
|
||||||
from lib.core.common import wasLastRequestDBMSError
|
from lib.core.common import wasLastResponseDBMSError
|
||||||
from lib.core.common import wasLastRequestHTTPError
|
from lib.core.common import wasLastResponseHTTPError
|
||||||
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
|
||||||
|
@ -695,7 +695,7 @@ def heuristicCheckSqlInjection(place, parameter):
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if wasLastRequestDBMSError():
|
if wasLastResponseDBMSError():
|
||||||
debugMsg = "heuristic checking skipped "
|
debugMsg = "heuristic checking skipped "
|
||||||
debugMsg += "because original page content "
|
debugMsg += "because original page content "
|
||||||
debugMsg += "contains DBMS error"
|
debugMsg += "contains DBMS error"
|
||||||
|
@ -723,7 +723,7 @@ def heuristicCheckSqlInjection(place, parameter):
|
||||||
page, _ = Request.queryPage(payload, place, content=True, raise404=False)
|
page, _ = Request.queryPage(payload, place, content=True, raise404=False)
|
||||||
|
|
||||||
parseFilePaths(page)
|
parseFilePaths(page)
|
||||||
result = wasLastRequestDBMSError()
|
result = wasLastResponseDBMSError()
|
||||||
|
|
||||||
infoMsg = "heuristic test shows that %s " % place
|
infoMsg = "heuristic test shows that %s " % place
|
||||||
infoMsg += "parameter '%s' might " % parameter
|
infoMsg += "parameter '%s' might " % parameter
|
||||||
|
@ -1083,14 +1083,14 @@ def checkConnection(suppressOutput=False):
|
||||||
|
|
||||||
kb.errorIsNone = False
|
kb.errorIsNone = False
|
||||||
|
|
||||||
if not kb.originalPage and wasLastRequestHTTPError():
|
if not kb.originalPage and wasLastResponseHTTPError():
|
||||||
errMsg = "unable to retrieve page content"
|
errMsg = "unable to retrieve page content"
|
||||||
raise SqlmapConnectionException(errMsg)
|
raise SqlmapConnectionException(errMsg)
|
||||||
elif wasLastRequestDBMSError():
|
elif wasLastResponseDBMSError():
|
||||||
warnMsg = "there is a DBMS error found in the HTTP response body "
|
warnMsg = "there is a DBMS error found in the HTTP response body "
|
||||||
warnMsg += "which could interfere with the results of the tests"
|
warnMsg += "which could interfere with the results of the tests"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
elif wasLastRequestHTTPError():
|
elif wasLastResponseHTTPError():
|
||||||
warnMsg = "the web server responded with an HTTP error code (%d) " % getLastRequestHTTPError()
|
warnMsg = "the web server responded with an HTTP error code (%d) " % getLastRequestHTTPError()
|
||||||
warnMsg += "which could interfere with the results of the tests"
|
warnMsg += "which could interfere with the results of the tests"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
|
@ -100,6 +100,7 @@ from lib.core.settings import IS_WIN
|
||||||
from lib.core.settings import LARGE_OUTPUT_THRESHOLD
|
from lib.core.settings import LARGE_OUTPUT_THRESHOLD
|
||||||
from lib.core.settings import MIN_ENCODED_LEN_CHECK
|
from lib.core.settings import MIN_ENCODED_LEN_CHECK
|
||||||
from lib.core.settings import MIN_TIME_RESPONSES
|
from lib.core.settings import MIN_TIME_RESPONSES
|
||||||
|
from lib.core.settings import MIN_VALID_DELAYED_RESPONSE
|
||||||
from lib.core.settings import ML
|
from lib.core.settings import ML
|
||||||
from lib.core.settings import NULL
|
from lib.core.settings import NULL
|
||||||
from lib.core.settings import PARAMETER_AMP_MARKER
|
from lib.core.settings import PARAMETER_AMP_MARKER
|
||||||
|
@ -1878,7 +1879,7 @@ def popValue():
|
||||||
|
|
||||||
return getCurrentThreadData().valueStack.pop()
|
return getCurrentThreadData().valueStack.pop()
|
||||||
|
|
||||||
def wasLastRequestDBMSError():
|
def wasLastResponseDBMSError():
|
||||||
"""
|
"""
|
||||||
Returns True if the last web request resulted in a (recognized) DBMS error page
|
Returns True if the last web request resulted in a (recognized) DBMS error page
|
||||||
"""
|
"""
|
||||||
|
@ -1886,7 +1887,7 @@ def wasLastRequestDBMSError():
|
||||||
threadData = getCurrentThreadData()
|
threadData = getCurrentThreadData()
|
||||||
return threadData.lastErrorPage and threadData.lastErrorPage[0] == threadData.lastRequestUID
|
return threadData.lastErrorPage and threadData.lastErrorPage[0] == threadData.lastRequestUID
|
||||||
|
|
||||||
def wasLastRequestHTTPError():
|
def wasLastResponseHTTPError():
|
||||||
"""
|
"""
|
||||||
Returns True if the last web request resulted in an errornous HTTP code (like 500)
|
Returns True if the last web request resulted in an errornous HTTP code (like 500)
|
||||||
"""
|
"""
|
||||||
|
@ -1894,7 +1895,7 @@ def wasLastRequestHTTPError():
|
||||||
threadData = getCurrentThreadData()
|
threadData = getCurrentThreadData()
|
||||||
return threadData.lastHTTPError and threadData.lastHTTPError[0] == threadData.lastRequestUID
|
return threadData.lastHTTPError and threadData.lastHTTPError[0] == threadData.lastRequestUID
|
||||||
|
|
||||||
def wasLastRequestDelayed():
|
def wasLastResponseDelayed():
|
||||||
"""
|
"""
|
||||||
Returns True if the last web request resulted in a time-delay
|
Returns True if the last web request resulted in a time-delay
|
||||||
"""
|
"""
|
||||||
|
@ -1913,7 +1914,7 @@ def wasLastRequestDelayed():
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
lowerStdLimit = average(kb.responseTimes) + TIME_STDEV_COEFF * deviation
|
lowerStdLimit = average(kb.responseTimes) + TIME_STDEV_COEFF * deviation
|
||||||
retVal = (threadData.lastQueryDuration >= lowerStdLimit)
|
retVal = (threadData.lastQueryDuration >= max(MIN_VALID_DELAYED_RESPONSE, lowerStdLimit))
|
||||||
|
|
||||||
if not kb.testMode and retVal:
|
if not kb.testMode and retVal:
|
||||||
if kb.adjustTimeDelay is None:
|
if kb.adjustTimeDelay is None:
|
||||||
|
@ -1956,6 +1957,9 @@ def getLastRequestHTTPError():
|
||||||
def extractErrorMessage(page):
|
def extractErrorMessage(page):
|
||||||
"""
|
"""
|
||||||
Returns reported error message from page if it founds one
|
Returns reported error message from page if it founds one
|
||||||
|
|
||||||
|
>>> extractErrorMessage(u'<html><title>Test</title>\\n<b>Warning</b>: oci_parse() [function.oci-parse]: ORA-01756: quoted string not properly terminated<br><p>Only a test page</p></html>')
|
||||||
|
u'oci_parse() [function.oci-parse]: ORA-01756: quoted string not properly terminated'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
retVal = None
|
retVal = None
|
||||||
|
@ -2022,7 +2026,14 @@ def urldecode(value, encoding=None, unsafe="%%&=;+%s" % CUSTOM_INJECTION_MARK_CH
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def urlencode(value, safe="%&=", convall=False, limit=False, spaceplus=False):
|
def urlencode(value, safe="%&=", convall=False, limit=False, spaceplus=False):
|
||||||
if conf.direct:
|
"""
|
||||||
|
URL encodes given value
|
||||||
|
|
||||||
|
>>> urlencode('AND 1>(2+3)#')
|
||||||
|
'AND%201%3E%282%2B3%29%23'
|
||||||
|
"""
|
||||||
|
|
||||||
|
if conf.get("direct"):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
|
@ -2104,6 +2115,9 @@ def getPageTemplate(payload, place): # Cross-linked function
|
||||||
def getPublicTypeMembers(type_, onlyValues=False):
|
def getPublicTypeMembers(type_, onlyValues=False):
|
||||||
"""
|
"""
|
||||||
Useful for getting members from types (e.g. in enums)
|
Useful for getting members from types (e.g. in enums)
|
||||||
|
|
||||||
|
>>> [_ for _ in getPublicTypeMembers(OS, True)]
|
||||||
|
['Linux', 'Windows']
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for name, value in inspect.getmembers(type_):
|
for name, value in inspect.getmembers(type_):
|
||||||
|
@ -2116,6 +2130,9 @@ def getPublicTypeMembers(type_, onlyValues=False):
|
||||||
def enumValueToNameLookup(type_, value_):
|
def enumValueToNameLookup(type_, value_):
|
||||||
"""
|
"""
|
||||||
Returns name of a enum member with a given value
|
Returns name of a enum member with a given value
|
||||||
|
|
||||||
|
>>> enumValueToNameLookup(SORT_ORDER, 100)
|
||||||
|
'LAST'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
retVal = None
|
retVal = None
|
||||||
|
@ -2131,11 +2148,14 @@ def extractRegexResult(regex, content, flags=0):
|
||||||
"""
|
"""
|
||||||
Returns 'result' group value from a possible match with regex on a given
|
Returns 'result' group value from a possible match with regex on a given
|
||||||
content
|
content
|
||||||
|
|
||||||
|
>>> extractRegexResult(r'a(?P<result>[^g]+)g', 'abcdefg')
|
||||||
|
'bcdef'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
retVal = None
|
retVal = None
|
||||||
|
|
||||||
if regex and content and '?P<result>' in regex:
|
if regex and content and "?P<result>" in regex:
|
||||||
match = re.search(regex, content, flags)
|
match = re.search(regex, content, flags)
|
||||||
|
|
||||||
if match:
|
if match:
|
||||||
|
@ -2146,6 +2166,9 @@ def extractRegexResult(regex, content, flags=0):
|
||||||
def extractTextTagContent(page):
|
def extractTextTagContent(page):
|
||||||
"""
|
"""
|
||||||
Returns list containing content from "textual" tags
|
Returns list containing content from "textual" tags
|
||||||
|
|
||||||
|
>>> extractTextTagContent(u'<html><head><title>Title</title></head><body><pre>foobar</pre><a href="#link">Link</a></body></html>')
|
||||||
|
[u'Title', u'foobar']
|
||||||
"""
|
"""
|
||||||
|
|
||||||
page = re.sub(r"(?si)[^\s>]*%s[^<]*" % REFLECTED_VALUE_MARKER, "", page or "")
|
page = re.sub(r"(?si)[^\s>]*%s[^<]*" % REFLECTED_VALUE_MARKER, "", page or "")
|
||||||
|
@ -2154,6 +2177,9 @@ def extractTextTagContent(page):
|
||||||
def trimAlphaNum(value):
|
def trimAlphaNum(value):
|
||||||
"""
|
"""
|
||||||
Trims alpha numeric characters from start and ending of a given value
|
Trims alpha numeric characters from start and ending of a given value
|
||||||
|
|
||||||
|
>>> trimAlphaNum(u'AND 1>(2+3)-- foobar')
|
||||||
|
u' 1>(2+3)-- '
|
||||||
"""
|
"""
|
||||||
|
|
||||||
while value and value[-1].isalnum():
|
while value and value[-1].isalnum():
|
||||||
|
@ -2167,14 +2193,26 @@ def trimAlphaNum(value):
|
||||||
def isNumPosStrValue(value):
|
def isNumPosStrValue(value):
|
||||||
"""
|
"""
|
||||||
Returns True if value is a string (or integer) with a positive integer representation
|
Returns True if value is a string (or integer) with a positive integer representation
|
||||||
|
|
||||||
|
>>> isNumPosStrValue(1)
|
||||||
|
True
|
||||||
|
>>> isNumPosStrValue('1')
|
||||||
|
True
|
||||||
|
>>> isNumPosStrValue(0)
|
||||||
|
False
|
||||||
|
>>> isNumPosStrValue('-2')
|
||||||
|
False
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return (value and isinstance(value, basestring) and value.isdigit() and value != "0") or (isinstance(value, int) and value != 0)
|
return (value and isinstance(value, basestring) and value.isdigit() and int(value) > 0) or (isinstance(value, int) and value > 0)
|
||||||
|
|
||||||
@cachedmethod
|
@cachedmethod
|
||||||
def aliasToDbmsEnum(dbms):
|
def aliasToDbmsEnum(dbms):
|
||||||
"""
|
"""
|
||||||
Returns major DBMS name from a given alias
|
Returns major DBMS name from a given alias
|
||||||
|
|
||||||
|
>>> aliasToDbmsEnum('mssql')
|
||||||
|
'Microsoft SQL Server'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
retVal = None
|
retVal = None
|
||||||
|
@ -2251,22 +2289,28 @@ def removeDynamicContent(page):
|
||||||
|
|
||||||
return page
|
return page
|
||||||
|
|
||||||
def filterStringValue(value, regex, replacement=""):
|
def filterStringValue(value, charRegex, replacement=""):
|
||||||
"""
|
"""
|
||||||
Returns string value consisting only of chars satisfying supplied
|
Returns string value consisting only of chars satisfying supplied
|
||||||
regular expression (note: it has to be in form [...])
|
regular expression (note: it has to be in form [...])
|
||||||
|
|
||||||
|
>>> filterStringValue(u'wzydeadbeef0123#', r'[0-9a-f]')
|
||||||
|
u'deadbeef0123'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
retVal = value
|
retVal = value
|
||||||
|
|
||||||
if value:
|
if value:
|
||||||
retVal = re.sub(regex.replace("[", "[^") if "[^" not in regex else regex.replace("[^", "["), replacement, value)
|
retVal = re.sub(charRegex.replace("[", "[^") if "[^" not in charRegex else charRegex.replace("[^", "["), replacement, value)
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def filterControlChars(value):
|
def filterControlChars(value):
|
||||||
"""
|
"""
|
||||||
Returns string value with control chars being supstituted with ' '
|
Returns string value with control chars being supstituted with ' '
|
||||||
|
|
||||||
|
>>> filterControlChars(u'AND 1>(2+3)\\n--')
|
||||||
|
u'AND 1>(2+3) --'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return filterStringValue(value, PRINTABLE_CHAR_REGEX, ' ')
|
return filterStringValue(value, PRINTABLE_CHAR_REGEX, ' ')
|
||||||
|
@ -2397,6 +2441,9 @@ def initTechnique(technique=None):
|
||||||
def arrayizeValue(value):
|
def arrayizeValue(value):
|
||||||
"""
|
"""
|
||||||
Makes a list out of value if it is not already a list or tuple itself
|
Makes a list out of value if it is not already a list or tuple itself
|
||||||
|
|
||||||
|
>>> arrayizeValue(u'1')
|
||||||
|
[u'1']
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not isListLike(value):
|
if not isListLike(value):
|
||||||
|
@ -2407,6 +2454,9 @@ def arrayizeValue(value):
|
||||||
def unArrayizeValue(value):
|
def unArrayizeValue(value):
|
||||||
"""
|
"""
|
||||||
Makes a value out of iterable if it is a list or tuple itself
|
Makes a value out of iterable if it is a list or tuple itself
|
||||||
|
|
||||||
|
>>> unArrayizeValue([u'1'])
|
||||||
|
u'1'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if isListLike(value):
|
if isListLike(value):
|
||||||
|
@ -2417,6 +2467,9 @@ def unArrayizeValue(value):
|
||||||
def flattenValue(value):
|
def flattenValue(value):
|
||||||
"""
|
"""
|
||||||
Returns an iterator representing flat representation of a given value
|
Returns an iterator representing flat representation of a given value
|
||||||
|
|
||||||
|
>>> [_ for _ in flattenValue([[u'1'], [[u'2'], u'3']])]
|
||||||
|
[u'1', u'2', u'3']
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for i in iter(value):
|
for i in iter(value):
|
||||||
|
@ -2429,6 +2482,11 @@ def flattenValue(value):
|
||||||
def isListLike(value):
|
def isListLike(value):
|
||||||
"""
|
"""
|
||||||
Returns True if the given value is a list-like instance
|
Returns True if the given value is a list-like instance
|
||||||
|
|
||||||
|
>>> isListLike([1, 2, 3])
|
||||||
|
True
|
||||||
|
>>> isListLike(u'2')
|
||||||
|
False
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return isinstance(value, (list, tuple, set, BigArray))
|
return isinstance(value, (list, tuple, set, BigArray))
|
||||||
|
@ -2464,6 +2522,9 @@ def filterListValue(value, regex):
|
||||||
"""
|
"""
|
||||||
Returns list with items that have parts satisfying given regular
|
Returns list with items that have parts satisfying given regular
|
||||||
expression
|
expression
|
||||||
|
|
||||||
|
>>> filterListValue(['users', 'admins', 'logs'], r'(users|admins)')
|
||||||
|
['users', 'admins']
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if isinstance(value, list) and regex:
|
if isinstance(value, list) and regex:
|
||||||
|
@ -2502,6 +2563,11 @@ def openFile(filename, mode='r'):
|
||||||
def decodeIntToUnicode(value):
|
def decodeIntToUnicode(value):
|
||||||
"""
|
"""
|
||||||
Decodes inferenced integer value to an unicode character
|
Decodes inferenced integer value to an unicode character
|
||||||
|
|
||||||
|
>>> decodeIntToUnicode(35)
|
||||||
|
u'#'
|
||||||
|
>>> decodeIntToUnicode(64)
|
||||||
|
u'@'
|
||||||
"""
|
"""
|
||||||
retVal = value
|
retVal = value
|
||||||
|
|
||||||
|
@ -2592,6 +2658,9 @@ def getExceptionFrameLocals():
|
||||||
def intersect(valueA, valueB, lowerCase=False):
|
def intersect(valueA, valueB, lowerCase=False):
|
||||||
"""
|
"""
|
||||||
Returns intersection of the array-ized values
|
Returns intersection of the array-ized values
|
||||||
|
|
||||||
|
>>> intersect([1, 2, 3], set([1,3]))
|
||||||
|
[1, 3]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
retVal = None
|
retVal = None
|
||||||
|
@ -2741,6 +2810,17 @@ def unsafeSQLIdentificatorNaming(name):
|
||||||
def isNoneValue(value):
|
def isNoneValue(value):
|
||||||
"""
|
"""
|
||||||
Returns whether the value is unusable (None or '')
|
Returns whether the value is unusable (None or '')
|
||||||
|
|
||||||
|
>>> isNoneValue(None)
|
||||||
|
True
|
||||||
|
>>> isNoneValue('None')
|
||||||
|
True
|
||||||
|
>>> isNoneValue('')
|
||||||
|
True
|
||||||
|
>>> isNoneValue([])
|
||||||
|
True
|
||||||
|
>>> isNoneValue([2])
|
||||||
|
False
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if isinstance(value, basestring):
|
if isinstance(value, basestring):
|
||||||
|
@ -2755,6 +2835,9 @@ def isNoneValue(value):
|
||||||
def isNullValue(value):
|
def isNullValue(value):
|
||||||
"""
|
"""
|
||||||
Returns whether the value contains explicit 'NULL' value
|
Returns whether the value contains explicit 'NULL' value
|
||||||
|
|
||||||
|
>>> isNullValue(u'NULL')
|
||||||
|
True
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return isinstance(value, basestring) and value.upper() == NULL
|
return isinstance(value, basestring) and value.upper() == NULL
|
||||||
|
@ -2846,13 +2929,18 @@ def safeCSValue(value):
|
||||||
"""
|
"""
|
||||||
Returns value safe for CSV dumping
|
Returns value safe for CSV dumping
|
||||||
Reference: http://tools.ietf.org/html/rfc4180
|
Reference: http://tools.ietf.org/html/rfc4180
|
||||||
|
|
||||||
|
>>> safeCSValue(u'foo, bar')
|
||||||
|
u'"foo, bar"'
|
||||||
|
>>> safeCSValue(u'foobar')
|
||||||
|
u'foobar'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
retVal = value
|
retVal = value
|
||||||
|
|
||||||
if retVal and isinstance(retVal, basestring):
|
if retVal and isinstance(retVal, basestring):
|
||||||
if not (retVal[0] == retVal[-1] == '"'):
|
if not (retVal[0] == retVal[-1] == '"'):
|
||||||
if any(_ in retVal for _ in (conf.csvDel, '"', '\n')):
|
if any(_ in retVal for _ in (conf.get("csvDel", ','), '"', '\n')):
|
||||||
retVal = '"%s"' % retVal.replace('"', '""')
|
retVal = '"%s"' % retVal.replace('"', '""')
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
@ -2860,6 +2948,9 @@ def safeCSValue(value):
|
||||||
def filterPairValues(values):
|
def filterPairValues(values):
|
||||||
"""
|
"""
|
||||||
Returns only list-like values with length 2
|
Returns only list-like values with length 2
|
||||||
|
|
||||||
|
>>> filterPairValues([[1, 2], [3], 1, [4, 5]])
|
||||||
|
[[1, 2], [4, 5]]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
retVal = []
|
retVal = []
|
||||||
|
|
|
@ -11,9 +11,11 @@ def cachedmethod(f, cache={}):
|
||||||
|
|
||||||
Reference: http://code.activestate.com/recipes/325205-cache-decorator-in-python-24/
|
Reference: http://code.activestate.com/recipes/325205-cache-decorator-in-python-24/
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _(*args, **kwargs):
|
def _(*args, **kwargs):
|
||||||
key = (f, tuple(args), frozenset(kwargs.items()))
|
key = (f, tuple(args), frozenset(kwargs.items()))
|
||||||
if key not in cache:
|
if key not in cache:
|
||||||
cache[key] = f(*args, **kwargs)
|
cache[key] = f(*args, **kwargs)
|
||||||
return cache[key]
|
return cache[key]
|
||||||
|
|
||||||
return _
|
return _
|
||||||
|
|
|
@ -64,6 +64,9 @@ CONCAT_VALUE_DELIMITER = '|'
|
||||||
# Coefficient used for a time-based query delay checking (must be >= 7)
|
# Coefficient used for a time-based query delay checking (must be >= 7)
|
||||||
TIME_STDEV_COEFF = 7
|
TIME_STDEV_COEFF = 7
|
||||||
|
|
||||||
|
# Minimum response time that can be even considered as delayed (not a complete requirement)
|
||||||
|
MIN_VALID_DELAYED_RESPONSE = 0.5
|
||||||
|
|
||||||
# Standard deviation after which a warning message should be displayed about connection lags
|
# Standard deviation after which a warning message should be displayed about connection lags
|
||||||
WARN_TIME_STDEV = 0.5
|
WARN_TIME_STDEV = 0.5
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ from lib.core.common import extractRegexResult
|
||||||
from lib.core.common import getFilteredPageContent
|
from lib.core.common import getFilteredPageContent
|
||||||
from lib.core.common import listToStrValue
|
from lib.core.common import listToStrValue
|
||||||
from lib.core.common import removeDynamicContent
|
from lib.core.common import removeDynamicContent
|
||||||
from lib.core.common import wasLastRequestDBMSError
|
from lib.core.common import wasLastResponseDBMSError
|
||||||
from lib.core.common import wasLastRequestHTTPError
|
from lib.core.common import wasLastResponseHTTPError
|
||||||
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
|
||||||
|
@ -77,7 +77,7 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
|
||||||
|
|
||||||
if page:
|
if page:
|
||||||
# In case of an DBMS error page return None
|
# In case of an DBMS error page return None
|
||||||
if kb.errorIsNone and (wasLastRequestDBMSError() or wasLastRequestHTTPError()):
|
if kb.errorIsNone and (wasLastResponseDBMSError() or wasLastResponseHTTPError()):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Dynamic content lines to be excluded before comparison
|
# Dynamic content lines to be excluded before comparison
|
||||||
|
|
|
@ -34,7 +34,7 @@ from lib.core.common import readInput
|
||||||
from lib.core.common import removeReflectiveValues
|
from lib.core.common import removeReflectiveValues
|
||||||
from lib.core.common import singleTimeWarnMessage
|
from lib.core.common import singleTimeWarnMessage
|
||||||
from lib.core.common import stdev
|
from lib.core.common import stdev
|
||||||
from lib.core.common import wasLastRequestDelayed
|
from lib.core.common import wasLastResponseDelayed
|
||||||
from lib.core.common import unicodeencode
|
from lib.core.common import unicodeencode
|
||||||
from lib.core.common import urlencode
|
from lib.core.common import urlencode
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
|
@ -776,7 +776,7 @@ class Connect(object):
|
||||||
|
|
||||||
elif not kb.testMode:
|
elif not kb.testMode:
|
||||||
warnMsg = "it is very important not to stress the network adapter's "
|
warnMsg = "it is very important not to stress the network adapter's "
|
||||||
warnMsg += "bandwidth during usage of time-based queries"
|
warnMsg += "bandwidth during usage of time-based payloads"
|
||||||
singleTimeWarnMessage(warnMsg)
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
|
||||||
if conf.safUrl and conf.saFreq > 0:
|
if conf.safUrl and conf.saFreq > 0:
|
||||||
|
@ -827,7 +827,7 @@ class Connect(object):
|
||||||
kb.testQueryCount += 1
|
kb.testQueryCount += 1
|
||||||
|
|
||||||
if timeBasedCompare:
|
if timeBasedCompare:
|
||||||
return wasLastRequestDelayed()
|
return wasLastResponseDelayed()
|
||||||
elif noteResponseTime:
|
elif noteResponseTime:
|
||||||
kb.responseTimes.append(threadData.lastQueryDuration)
|
kb.responseTimes.append(threadData.lastQueryDuration)
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ from lib.core.common import pushValue
|
||||||
from lib.core.common import popValue
|
from lib.core.common import popValue
|
||||||
from lib.core.common import randomStr
|
from lib.core.common import randomStr
|
||||||
from lib.core.common import readInput
|
from lib.core.common import readInput
|
||||||
from lib.core.common import wasLastRequestDelayed
|
from lib.core.common import wasLastResponseDelayed
|
||||||
from lib.core.convert import hexencode
|
from lib.core.convert import hexencode
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
|
@ -94,7 +94,7 @@ class Xp_cmdshell:
|
||||||
cmd = "ping -n %d 127.0.0.1" % (conf.timeSec * 2)
|
cmd = "ping -n %d 127.0.0.1" % (conf.timeSec * 2)
|
||||||
self.xpCmdshellExecCmd(cmd)
|
self.xpCmdshellExecCmd(cmd)
|
||||||
|
|
||||||
return wasLastRequestDelayed()
|
return wasLastResponseDelayed()
|
||||||
|
|
||||||
def _xpCmdshellTest(self):
|
def _xpCmdshellTest(self):
|
||||||
threadData = getCurrentThreadData()
|
threadData = getCurrentThreadData()
|
||||||
|
|
|
@ -22,7 +22,7 @@ from lib.core.common import removeReflectiveValues
|
||||||
from lib.core.common import singleTimeLogMessage
|
from lib.core.common import singleTimeLogMessage
|
||||||
from lib.core.common import singleTimeWarnMessage
|
from lib.core.common import singleTimeWarnMessage
|
||||||
from lib.core.common import stdev
|
from lib.core.common import stdev
|
||||||
from lib.core.common import wasLastRequestDBMSError
|
from lib.core.common import wasLastResponseDBMSError
|
||||||
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
|
||||||
|
@ -223,7 +223,7 @@ def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLO
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
vector = (position, count, comment, prefix, suffix, kb.uChar, PAYLOAD.WHERE.NEGATIVE, kb.unionDuplicates)
|
vector = (position, count, comment, prefix, suffix, kb.uChar, PAYLOAD.WHERE.NEGATIVE, kb.unionDuplicates)
|
||||||
|
|
||||||
unionErrorCase = kb.errorIsNone and wasLastRequestDBMSError()
|
unionErrorCase = kb.errorIsNone and wasLastResponseDBMSError()
|
||||||
|
|
||||||
if unionErrorCase and count > 1:
|
if unionErrorCase and count > 1:
|
||||||
warnMsg = "combined UNION/error-based SQL injection case found on "
|
warnMsg = "combined UNION/error-based SQL injection case found on "
|
||||||
|
|
|
@ -33,7 +33,7 @@ from lib.core.common import removeReflectiveValues
|
||||||
from lib.core.common import singleTimeDebugMessage
|
from lib.core.common import singleTimeDebugMessage
|
||||||
from lib.core.common import singleTimeWarnMessage
|
from lib.core.common import singleTimeWarnMessage
|
||||||
from lib.core.common import unArrayizeValue
|
from lib.core.common import unArrayizeValue
|
||||||
from lib.core.common import wasLastRequestDBMSError
|
from lib.core.common import wasLastResponseDBMSError
|
||||||
from lib.core.convert import htmlunescape
|
from lib.core.convert import htmlunescape
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
|
@ -94,7 +94,7 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
|
||||||
retVal = getUnicode(retVal, kb.pageEncoding)
|
retVal = getUnicode(retVal, kb.pageEncoding)
|
||||||
|
|
||||||
# Special case when DBMS is Microsoft SQL Server and error message is used as a result of union injection
|
# Special case when DBMS is Microsoft SQL Server and error message is used as a result of union injection
|
||||||
if Backend.isDbms(DBMS.MSSQL) and wasLastRequestDBMSError():
|
if Backend.isDbms(DBMS.MSSQL) and wasLastResponseDBMSError():
|
||||||
retVal = htmlunescape(retVal).replace("<br>", "\n")
|
retVal = htmlunescape(retVal).replace("<br>", "\n")
|
||||||
|
|
||||||
hashDBWrite("%s%s" % (conf.hexConvert, expression), retVal)
|
hashDBWrite("%s%s" % (conf.hexConvert, expression), retVal)
|
||||||
|
|
|
@ -12,7 +12,7 @@ from lib.core.common import Format
|
||||||
from lib.core.common import getCurrentThreadData
|
from lib.core.common import getCurrentThreadData
|
||||||
from lib.core.common import randomInt
|
from lib.core.common import randomInt
|
||||||
from lib.core.common import randomStr
|
from lib.core.common import randomStr
|
||||||
from lib.core.common import wasLastRequestDBMSError
|
from lib.core.common import wasLastResponseDBMSError
|
||||||
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
|
||||||
|
@ -95,7 +95,7 @@ class Fingerprint(GenericFingerprint):
|
||||||
randStr = randomStr()
|
randStr = randomStr()
|
||||||
inject.checkBooleanExpression("EXISTS(SELECT * FROM %s.%s WHERE %d=%d)" % (randStr, randStr, randInt, randInt))
|
inject.checkBooleanExpression("EXISTS(SELECT * FROM %s.%s WHERE %d=%d)" % (randStr, randStr, randInt, randInt))
|
||||||
|
|
||||||
if wasLastRequestDBMSError():
|
if wasLastResponseDBMSError():
|
||||||
threadData = getCurrentThreadData()
|
threadData = getCurrentThreadData()
|
||||||
match = re.search("Could not find file\s+'([^']+?)'", threadData.lastErrorPage[1])
|
match = re.search("Could not find file\s+'([^']+?)'", threadData.lastErrorPage[1])
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user