Merge branch 'master' of github.com:sqlmapproject/sqlmap

This commit is contained in:
Bernardo Damele 2013-01-30 10:34:51 +00:00
commit 6dfe91165d
10 changed files with 127 additions and 31 deletions

View File

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

View File

@ -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 = []

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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