few just in case fixes (unarrayizeValue in dumpTable entries) and and some refactoring (unique is now not done for every union case but only if detected that there are duplicates in union test)

This commit is contained in:
Miroslav Stampar 2012-06-15 20:41:53 +00:00
parent 76c873a222
commit 06be7bbb18
10 changed files with 19 additions and 20 deletions

View File

@ -1189,7 +1189,7 @@ def getLimitRange(count, dump=False, plusOne=False):
return retVal return retVal
def parseUnionPage(page, unique=True): def parseUnionPage(page):
""" """
Returns resulting items from inband query inside provided page content Returns resulting items from inband query inside provided page content
""" """
@ -1211,7 +1211,7 @@ def parseUnionPage(page, unique=True):
if kb.chars.start in entry: if kb.chars.start in entry:
entry = entry.split(kb.chars.start)[-1] entry = entry.split(kb.chars.start)[-1]
if unique: if kb.unionDuplicates:
key = entry.lower() key = entry.lower()
if key not in _: if key not in _:
_.append(key) _.append(key)

View File

@ -1512,6 +1512,7 @@ def __setKnowledgeBaseAttributes(flushAll=True):
kb.threadException = False kb.threadException = False
kb.timeValidCharsRun = 0 kb.timeValidCharsRun = 0
kb.uChar = NULL kb.uChar = NULL
kb.unionDuplicates = False
kb.xpCmdshellAvailable = False kb.xpCmdshellAvailable = False
kb.chars = AttribDict() kb.chars = AttribDict()

View File

@ -456,7 +456,7 @@ DEFAULT_COOKIE_DELIMITER = ';'
HASHDB_FLUSH_THRESHOLD = 32 HASHDB_FLUSH_THRESHOLD = 32
# Unique milestone value used for forced deprecation of old HashDB values (e.g. when changing hash/pickle mechanism) # Unique milestone value used for forced deprecation of old HashDB values (e.g. when changing hash/pickle mechanism)
HASHDB_MILESTONE_VALUE = "EfjamfhMVw" # r4856 HASHDB_MILESTONE_VALUE = "ZTuyinSUvN" # r5125 "".join(random.sample(string.letters, 10))
# Warn user of possible delay due to large page dump in full UNION query injections # Warn user of possible delay due to large page dump in full UNION query injections
LARGE_OUTPUT_THRESHOLD = 1024**2 LARGE_OUTPUT_THRESHOLD = 1024**2

View File

@ -356,7 +356,7 @@ def __goError(expression, expected=None, dump=False):
return output return output
def __goInband(expression, expected=None, unique=True, unpack=True, dump=False): def __goInband(expression, expected=None, 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.
@ -364,11 +364,11 @@ def __goInband(expression, expected=None, unique=True, unpack=True, dump=False):
output = unionUse(expression, unpack=unpack, dump=dump) output = unionUse(expression, unpack=unpack, dump=dump)
if isinstance(output, basestring): if isinstance(output, basestring):
output = parseUnionPage(output, unique) output = parseUnionPage(output)
return output return output
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): def getValue(expression, blind=True, inband=True, error=True, time=True, fromUser=False, expected=None, batch=False, unpack=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
@ -413,9 +413,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, unique, unpack, dump) value = __goInband(forgeCaseExpression, expected, unpack, dump)
else: else:
value = __goInband(query, expected, unique, unpack, dump) value = __goInband(query, expected, 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

View File

@ -188,7 +188,7 @@ class xp_cmdshell:
self.delRemoteFile(tmpFile) self.delRemoteFile(tmpFile)
output = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.cmdTblName), resumeValue=False, unique=False, firstChar=first, lastChar=last, safeCharEncode=False) output = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.cmdTblName), resumeValue=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)):

View File

@ -186,7 +186,7 @@ def __unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYL
if content and phrase in content: if content and phrase in content:
validPayload = payload validPayload = payload
vector = (position, count, comment, prefix, suffix, kb.uChar, where) vector = (position, count, comment, prefix, suffix, kb.uChar, where, content.count(phrase) > 1)
if where == PAYLOAD.WHERE.ORIGINAL: if where == PAYLOAD.WHERE.ORIGINAL:
# Prepare expression with delimiters # Prepare expression with delimiters

View File

@ -66,6 +66,7 @@ def __oneShotUnionUse(expression, unpack=True, limited=False):
# Forge the inband SQL injection request # Forge the inband SQL injection request
vector = kb.injection.data[PAYLOAD.TECHNIQUE.UNION].vector vector = kb.injection.data[PAYLOAD.TECHNIQUE.UNION].vector
kb.unionDuplicates = vector[7]
query = agent.forgeInbandQuery(injExpression, vector[0], vector[1], vector[2], vector[3], vector[4], vector[5], vector[6], None, limited) query = agent.forgeInbandQuery(injExpression, vector[0], vector[1], vector[2], vector[3], vector[4], vector[5], vector[6], None, limited)
payload = agent.payload(newValue=query, where=where) payload = agent.payload(newValue=query, where=where)

View File

@ -145,7 +145,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), unique=False, resumeValue=False, blind=False, error=False) result = inject.getValue("SELECT %s FROM %s ORDER BY id ASC" % (self.tblField, hexTbl), resumeValue=False, blind=False, error=False)
if not result: if not result:
result = [] result = []
@ -159,7 +159,7 @@ class Filesystem(GenericFilesystem):
indexRange = getLimitRange(count) indexRange = getLimitRange(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, unique=False, charsetType=CHARSET_TYPE.HEXADECIMAL) 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, charsetType=CHARSET_TYPE.HEXADECIMAL)
result.append(chunk) result.append(chunk)
inject.goStacked("DROP TABLE %s" % hexTbl) inject.goStacked("DROP TABLE %s" % hexTbl)

View File

@ -54,7 +54,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 = inject.getValue("SELECT LENGTH(%s) FROM %s" % (self.tblField, self.fileTblName), unique=False, resumeValue=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) length = inject.getValue("SELECT LENGTH(%s) FROM %s" % (self.tblField, self.fileTblName), resumeValue=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
if not isNumPosStrValue(length): if not isNumPosStrValue(length):
warnMsg = "unable to retrieve the content of the " warnMsg = "unable to retrieve the content of the "
@ -74,11 +74,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, unique=False, resumeValue=False, charsetType=CHARSET_TYPE.HEXADECIMAL) chunk = inject.getValue("SELECT MID(%s, %d, %d) FROM %s" % (self.tblField, i, sustrLen, self.fileTblName), unpack=False, resumeValue=False, charsetType=CHARSET_TYPE.HEXADECIMAL)
result.append(chunk) result.append(chunk)
else: else:
result = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.fileTblName), unique=False, resumeValue=False, charsetType=CHARSET_TYPE.HEXADECIMAL) result = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.fileTblName), resumeValue=False, charsetType=CHARSET_TYPE.HEXADECIMAL)
return result return result

View File

@ -1611,9 +1611,8 @@ class Enumeration:
entries = [] entries = []
entriesCount = len(entries) entriesCount = len(entries)
index = 0
for column in colList: for index, column in enumerate(colList):
colLen = len(column) colLen = len(column)
if column not in kb.data.dumpedTable: if column not in kb.data.dumpedTable:
@ -1626,7 +1625,7 @@ class Enumeration:
if isinstance(entry, basestring): if isinstance(entry, basestring):
colEntry = entry colEntry = entry
else: else:
colEntry = entry[index] if index < len(entry) else u'' colEntry = unArrayizeValue(entry[index]) if index < len(entry) else u''
colEntryLen = len({" ": NULL, "": BLANK}.get(getUnicode(colEntry), getUnicode(colEntry))) colEntryLen = len({" ": NULL, "": BLANK}.get(getUnicode(colEntry), getUnicode(colEntry)))
maxLen = max(colLen, colEntryLen) maxLen = max(colLen, colEntryLen)
@ -1636,8 +1635,6 @@ class Enumeration:
kb.data.dumpedTable[column]["values"].append(colEntry) kb.data.dumpedTable[column]["values"].append(colEntry)
index += 1
if not kb.data.dumpedTable and isInferenceAvailable() and not conf.direct: if not kb.data.dumpedTable and isInferenceAvailable() and not conf.direct:
infoMsg = "fetching number of " infoMsg = "fetching number of "
if conf.col: if conf.col: