mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-22 09:36:35 +03:00
some refactoring/speedup around UNION technique
This commit is contained in:
parent
b77e2042f2
commit
1ae413a206
|
@ -1328,7 +1328,7 @@ def getRange(count, dump=False, plusOne=False):
|
||||||
|
|
||||||
return indexRange
|
return indexRange
|
||||||
|
|
||||||
def parseUnionPage(output, expression, partial=False, sort=True):
|
def parseUnionPage(output, expression, partial=False, unique=True):
|
||||||
if output is None:
|
if output is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -1336,31 +1336,21 @@ def parseUnionPage(output, expression, partial=False, sort=True):
|
||||||
|
|
||||||
if output.startswith(kb.chars.start) and output.endswith(kb.chars.stop):
|
if output.startswith(kb.chars.start) and output.endswith(kb.chars.stop):
|
||||||
regExpr = '%s(.*?)%s' % (kb.chars.start, kb.chars.stop)
|
regExpr = '%s(.*?)%s' % (kb.chars.start, kb.chars.stop)
|
||||||
|
|
||||||
output = re.findall(regExpr, output, re.DOTALL | re.IGNORECASE)
|
output = re.findall(regExpr, output, re.DOTALL | re.IGNORECASE)
|
||||||
|
_ = set()
|
||||||
if sort:
|
|
||||||
_ = []
|
|
||||||
unique = set()
|
|
||||||
for entry in output:
|
|
||||||
key = entry.lower()
|
|
||||||
if key not in unique:
|
|
||||||
unique.add(key)
|
|
||||||
_.append(entry)
|
|
||||||
output = _
|
|
||||||
|
|
||||||
for entry in output:
|
for entry in output:
|
||||||
|
if unique:
|
||||||
|
key = entry.lower()
|
||||||
|
if key not in _:
|
||||||
|
_.add(key)
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
entry = safecharencode(entry) if kb.safeCharEncode else entry
|
entry = safecharencode(entry) if kb.safeCharEncode else entry
|
||||||
|
entry = entry.split(DUMP_DEL_MARKER if DUMP_DEL_MARKER in entry else kb.chars.delimiter)
|
||||||
|
|
||||||
if DUMP_DEL_MARKER in entry:
|
data.append(entry[0] if len(entry) == 1 else entry)
|
||||||
entry = entry.split(DUMP_DEL_MARKER)
|
|
||||||
else:
|
|
||||||
entry = entry.split(kb.chars.delimiter)
|
|
||||||
|
|
||||||
if len(entry) == 1:
|
|
||||||
data.append(entry[0])
|
|
||||||
else:
|
|
||||||
data.append(entry)
|
|
||||||
else:
|
else:
|
||||||
data = output
|
data = output
|
||||||
|
|
||||||
|
|
|
@ -368,7 +368,7 @@ def __goError(expression, expected=None, resumeValue=True, dump=False):
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=True, dump=False):
|
def __goInband(expression, expected=None, unique=True, resumeValue=True, unpack=True, dump=False):
|
||||||
"""
|
"""
|
||||||
Retrieve the output of a SQL query taking advantage of an inband SQL
|
Retrieve the output of a SQL query taking advantage of an inband SQL
|
||||||
injection vulnerability on the affected parameter.
|
injection vulnerability on the affected parameter.
|
||||||
|
@ -384,11 +384,11 @@ def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=Tr
|
||||||
if isinstance(output, list):
|
if isinstance(output, list):
|
||||||
data = output
|
data = output
|
||||||
else:
|
else:
|
||||||
data = parseUnionPage(output, expression, partial, sort)
|
data = parseUnionPage(output, expression, partial, unique)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def getValue(expression, blind=True, inband=True, error=True, time=True, fromUser=False, expected=None, batch=False, unpack=True, sort=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None, dump=False, suppressOutput=None, expectingNone=False, safeCharEncode=True):
|
def getValue(expression, blind=True, inband=True, error=True, time=True, fromUser=False, expected=None, batch=False, unpack=True, unique=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None, dump=False, suppressOutput=None, expectingNone=False, safeCharEncode=True):
|
||||||
"""
|
"""
|
||||||
Called each time sqlmap inject a SQL query on the SQL injection
|
Called each time sqlmap inject a SQL query on the SQL injection
|
||||||
affected parameter. It can call a function to retrieve the output
|
affected parameter. It can call a function to retrieve the output
|
||||||
|
@ -429,9 +429,9 @@ def getValue(expression, blind=True, inband=True, error=True, time=True, fromUse
|
||||||
kb.technique = PAYLOAD.TECHNIQUE.UNION
|
kb.technique = PAYLOAD.TECHNIQUE.UNION
|
||||||
|
|
||||||
if expected == EXPECTED.BOOL:
|
if expected == EXPECTED.BOOL:
|
||||||
value = __goInband(forgeCaseExpression, expected, sort, resumeValue, unpack, dump)
|
value = __goInband(forgeCaseExpression, expected, unique, resumeValue, unpack, dump)
|
||||||
else:
|
else:
|
||||||
value = __goInband(query, expected, sort, resumeValue, unpack, dump)
|
value = __goInband(query, expected, unique, resumeValue, unpack, dump)
|
||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
found = (value is not None) or (value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE
|
found = (value is not None) or (value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE
|
||||||
|
|
|
@ -121,7 +121,7 @@ class xp_cmdshell:
|
||||||
|
|
||||||
self.delRemoteFile(tmpFile)
|
self.delRemoteFile(tmpFile)
|
||||||
|
|
||||||
output = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.cmdTblName), resumeValue=False, sort=False, firstChar=first, lastChar=last, safeCharEncode=False)
|
output = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.cmdTblName), resumeValue=False, unique=False, firstChar=first, lastChar=last, safeCharEncode=False)
|
||||||
inject.goStacked("DELETE FROM %s" % self.cmdTblName)
|
inject.goStacked("DELETE FROM %s" % self.cmdTblName)
|
||||||
|
|
||||||
if output and isinstance(output, (list, tuple)):
|
if output and isinstance(output, (list, tuple)):
|
||||||
|
|
|
@ -94,7 +94,7 @@ class Filesystem(GenericFilesystem):
|
||||||
inject.goStacked(binToHexQuery)
|
inject.goStacked(binToHexQuery)
|
||||||
|
|
||||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION):
|
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION):
|
||||||
result = inject.getValue("SELECT %s FROM %s ORDER BY id ASC" % (self.tblField, hexTbl), sort=False, resumeValue=False, blind=False, error=False)
|
result = inject.getValue("SELECT %s FROM %s ORDER BY id ASC" % (self.tblField, hexTbl), unique=False, resumeValue=False, blind=False, error=False)
|
||||||
|
|
||||||
if not result:
|
if not result:
|
||||||
result = []
|
result = []
|
||||||
|
@ -108,7 +108,7 @@ class Filesystem(GenericFilesystem):
|
||||||
indexRange = getRange(count)
|
indexRange = getRange(count)
|
||||||
|
|
||||||
for index in indexRange:
|
for index in indexRange:
|
||||||
chunk = inject.getValue("SELECT TOP 1 %s FROM %s WHERE %s NOT IN (SELECT TOP %d %s FROM %s ORDER BY id ASC) ORDER BY id ASC" % (self.tblField, hexTbl, self.tblField, index, self.tblField, hexTbl), unpack=False, resumeValue=False, sort=False, charsetType=3)
|
chunk = inject.getValue("SELECT TOP 1 %s FROM %s WHERE %s NOT IN (SELECT TOP %d %s FROM %s ORDER BY id ASC) ORDER BY id ASC" % (self.tblField, hexTbl, self.tblField, index, self.tblField, hexTbl), unpack=False, resumeValue=False, unique=False, charsetType=3)
|
||||||
result.append(chunk)
|
result.append(chunk)
|
||||||
|
|
||||||
inject.goStacked("DROP TABLE %s" % hexTbl)
|
inject.goStacked("DROP TABLE %s" % hexTbl)
|
||||||
|
|
|
@ -52,7 +52,7 @@ class Filesystem(GenericFilesystem):
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
inject.goStacked("LOAD DATA INFILE '%s' INTO TABLE %s FIELDS TERMINATED BY '%s' (%s)" % (tmpFile, self.fileTblName, randomStr(10), self.tblField))
|
inject.goStacked("LOAD DATA INFILE '%s' INTO TABLE %s FIELDS TERMINATED BY '%s' (%s)" % (tmpFile, self.fileTblName, randomStr(10), self.tblField))
|
||||||
|
|
||||||
length = unArrayizeValue(inject.getValue("SELECT LENGTH(%s) FROM %s" % (self.tblField, self.fileTblName), sort=False, resumeValue=False, charsetType=2))
|
length = unArrayizeValue(inject.getValue("SELECT LENGTH(%s) FROM %s" % (self.tblField, self.fileTblName), unique=False, resumeValue=False, charsetType=2))
|
||||||
|
|
||||||
if not isNumPosStrValue(length):
|
if not isNumPosStrValue(length):
|
||||||
errMsg = "unable to retrieve the content of the "
|
errMsg = "unable to retrieve the content of the "
|
||||||
|
@ -66,11 +66,11 @@ class Filesystem(GenericFilesystem):
|
||||||
result = []
|
result = []
|
||||||
|
|
||||||
for i in xrange(1, length, sustrLen):
|
for i in xrange(1, length, sustrLen):
|
||||||
chunk = inject.getValue("SELECT MID(%s, %d, %d) FROM %s" % (self.tblField, i, sustrLen, self.fileTblName), unpack=False, sort=False, resumeValue=False, charsetType=3)
|
chunk = inject.getValue("SELECT MID(%s, %d, %d) FROM %s" % (self.tblField, i, sustrLen, self.fileTblName), unpack=False, unique=False, resumeValue=False, charsetType=3)
|
||||||
|
|
||||||
result.append(chunk)
|
result.append(chunk)
|
||||||
else:
|
else:
|
||||||
result = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.fileTblName), sort=False, resumeValue=False, charsetType=3)
|
result = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.fileTblName), unique=False, resumeValue=False, charsetType=3)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user