mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-01-23 15:54:24 +03:00
changes regarding dynamic content recognition
This commit is contained in:
parent
c886659f82
commit
77a53228c5
|
@ -280,32 +280,53 @@ def checkDynParam(place, parameter, value):
|
|||
|
||||
return condition
|
||||
|
||||
def checkDynamicContent(firstPage, secondPage):
|
||||
def checkDynamicContent(*pages):
|
||||
"""
|
||||
This function checks if the provided pages have dynamic content. If they
|
||||
are dynamic, their content differs at specific lines.
|
||||
"""
|
||||
infoMsg = "searching for dynamic content"
|
||||
logger.info(infoMsg)
|
||||
|
||||
linesFirst = preparePageForLineComparison(firstPage)
|
||||
linesSecond = preparePageForLineComparison(secondPage)
|
||||
for i in xrange(len(pages)):
|
||||
firstPage = pages[i]
|
||||
linesFirst = preparePageForLineComparison(firstPage)
|
||||
pageLinesNumber = len(linesFirst)
|
||||
for j in xrange(i+1, len(pages)):
|
||||
secondPage = pages[j]
|
||||
linesSecond = preparePageForLineComparison(secondPage)
|
||||
if pageLinesNumber == len(linesSecond):
|
||||
for k in xrange(0, pageLinesNumber):
|
||||
if (linesFirst[k] != linesSecond[k]):
|
||||
item = DynamicContentItem(k, pageLinesNumber, \
|
||||
linesFirst[k-1] if k > 0 else None, \
|
||||
linesFirst[k+1] if k < pageLinesNumber - 1 else None)
|
||||
|
||||
if len(linesFirst) == len(linesSecond):
|
||||
lastLineNumber = None
|
||||
pageLinesNumber = len(linesFirst)
|
||||
for i in range(0, pageLinesNumber):
|
||||
if (linesFirst[i] != linesSecond[i]):
|
||||
if lastLineNumber == i - 1:
|
||||
item = kb.dynamicContent[-1]
|
||||
if isinstance(item.lineNumber, int):
|
||||
item.lineNumber = [item.lineNumber]
|
||||
item.lineNumber.append(i)
|
||||
else:
|
||||
kb.dynamicContent.append(DynamicContentItem(i, pageLinesNumber, linesFirst[i-1] if i > 0 else None, linesFirst[i+1] if i < pageLinesNumber - 1 else None))
|
||||
lastLineNumber = i
|
||||
|
||||
randInt = getUnicode(randomInt(1))
|
||||
payload = agent.fullPayload(" AND %s=%s" % (randInt, randInt))
|
||||
result = Request.queryPage(payload)
|
||||
if result:
|
||||
pass #TODO: the same as above
|
||||
found = None
|
||||
for other in kb.dynamicContent:
|
||||
found = True
|
||||
if other.pageTotal == item.pageTotal:
|
||||
if isinstance(other.lineNumber, int):
|
||||
if other.lineNumber == item.lineNumber - 1:
|
||||
other.lineNumber = [other.lineNumber, item.lineNumber]
|
||||
other.lineContentAfter = item.lineContentAfter
|
||||
break
|
||||
elif other.lineNumber == item.lineNumber + 1:
|
||||
other.lineNumber = [item.lineNumber, other.lineNumber]
|
||||
other.lineContentBefore = item.lineContentBefore
|
||||
break
|
||||
elif item.lineNumber - 1 == other.lineNumber[-1]:
|
||||
other.lineNumber.append(item.lineNumber)
|
||||
other.lineContentAfter = item.lineContentAfter
|
||||
break
|
||||
elif item.lineNumber + 1 == other.lineNumber[0]:
|
||||
other.lineNumber.insert(0, item.lineNumber)
|
||||
other.lineContentBefore = item.lineContentBefore
|
||||
break
|
||||
found = False
|
||||
|
||||
if not found:
|
||||
kb.dynamicContent.append(item)
|
||||
|
||||
if kb.dynamicContent:
|
||||
infoMsg = "found probably removable dynamic lines"
|
||||
|
|
|
@ -163,7 +163,7 @@ def formatDBMSfp(versions=None):
|
|||
|
||||
while versions and None in versions:
|
||||
versions.remove(None)
|
||||
|
||||
|
||||
if not versions and kb.dbmsVersion and kb.dbmsVersion[0] != "Unknown" and kb.dbmsVersion[0] != None:
|
||||
versions = kb.dbmsVersion
|
||||
|
||||
|
@ -331,7 +331,7 @@ def getDirs(webApi=None):
|
|||
infoMsg = "retrieved web server full paths: "
|
||||
infoMsg += "'%s'" % ", ".join(path for path in kb.absFilePaths)
|
||||
logger.info(infoMsg)
|
||||
|
||||
|
||||
for absFilePath in kb.absFilePaths:
|
||||
if absFilePath:
|
||||
directory = directoryPath(absFilePath)
|
||||
|
@ -423,7 +423,7 @@ def strToHex(inpStr):
|
|||
hexStr += hexChar
|
||||
|
||||
return hexStr
|
||||
|
||||
|
||||
def fileToStr(fileName):
|
||||
"""
|
||||
@param fileName: file path to read the content and return as a no
|
||||
|
@ -481,7 +481,7 @@ def readInput(message, default=None):
|
|||
data = default
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def randomRange(start=0, stop=1000):
|
||||
"""
|
||||
@param start: starting number.
|
||||
|
@ -767,7 +767,7 @@ def parseTargetUrl():
|
|||
conf.parameters["GET"] = __urlSplit[3]
|
||||
|
||||
conf.url = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, conf.path)
|
||||
|
||||
|
||||
def expandAsteriskForColumns(expression):
|
||||
# If the user provided an asterisk rather than the column(s)
|
||||
# name, sqlmap will retrieve the columns itself and reprocess
|
||||
|
@ -819,7 +819,7 @@ def getRange(count, dump=False, plusOne=False):
|
|||
indexRange = range(limitStart - 1, limitStop)
|
||||
|
||||
return indexRange
|
||||
|
||||
|
||||
def parseUnionPage(output, expression, partial=False, condition=None, sort=True):
|
||||
data = []
|
||||
|
||||
|
@ -896,7 +896,7 @@ def getDelayQuery(andCond=False):
|
|||
query = "(%s)>0" % query
|
||||
|
||||
return query
|
||||
|
||||
|
||||
def getLocalIP():
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((conf.hostname, conf.port))
|
||||
|
@ -918,7 +918,7 @@ def getFileType(filePath):
|
|||
return "text"
|
||||
else:
|
||||
return "binary"
|
||||
|
||||
|
||||
def pollProcess(process):
|
||||
while True:
|
||||
dataToStdout(".")
|
||||
|
@ -935,7 +935,7 @@ def pollProcess(process):
|
|||
dataToStdout(" quit unexpectedly with return code %d\n" % returncode)
|
||||
|
||||
break
|
||||
|
||||
|
||||
def getCharset(charsetType=None):
|
||||
asciiTbl = []
|
||||
|
||||
|
@ -973,7 +973,7 @@ def getCharset(charsetType=None):
|
|||
asciiTbl.extend(range(96, 123))
|
||||
|
||||
return asciiTbl
|
||||
|
||||
|
||||
def searchEnvPath(fileName):
|
||||
envPaths = os.environ["PATH"]
|
||||
result = None
|
||||
|
@ -1137,7 +1137,7 @@ def isBase64EncodedString(subject):
|
|||
False
|
||||
"""
|
||||
return re.match(r"\A(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?\Z", subject) is not None
|
||||
|
||||
|
||||
def isHexEncodedString(subject):
|
||||
"""
|
||||
Checks if the provided string is hex encoded
|
||||
|
@ -1249,7 +1249,7 @@ def parseXmlFile(xmlFile, handler):
|
|||
|
||||
def calculateDeltaSeconds(start, epsilon=0.05):
|
||||
"""
|
||||
Returns elapsed time from start till now (including expected
|
||||
Returns elapsed time from start till now (including expected
|
||||
error set by epsilon parameter)
|
||||
"""
|
||||
return int(time.time() - start + epsilon)
|
||||
|
@ -1470,6 +1470,7 @@ def smokeTest():
|
|||
logger.error(infoMsg)
|
||||
return retVal
|
||||
|
||||
|
||||
class UnicodeRawConfigParser(RawConfigParser):
|
||||
def write(self, fp):
|
||||
"""
|
||||
|
@ -1496,6 +1497,7 @@ class UnicodeRawConfigParser(RawConfigParser):
|
|||
|
||||
fp.write("\n")
|
||||
|
||||
|
||||
class DynamicContentItem:
|
||||
"""
|
||||
Represents line in content page with dynamic properties (candidate for removal prior detection phase)
|
||||
|
|
Loading…
Reference in New Issue
Block a user