diff --git a/lib/core/common.py b/lib/core/common.py index 94994463a..cfaed3eb6 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -54,10 +54,7 @@ from lib.core.data import logger from lib.core.data import paths from lib.core.data import queries from lib.core.data import temp -from lib.core.convert import md5hash -from lib.core.convert import sha1hash from lib.core.convert import urlencode -from lib.core.convert import utf8decode from lib.core.exception import sqlmapFilePathException from lib.core.exception import sqlmapNoneDataException from lib.core.exception import sqlmapMissingDependence @@ -1220,15 +1217,14 @@ def initCommonOutputs(): line = line.strip() if len(line) > 1: - if line[0] == '[' and line[-1] == ']': + if line.startswith('[') and line.endswith(']'): key = line[1:-1] elif key: if key not in kb.commonOutputs: kb.commonOutputs[key] = [] - item = line.strip() - if item not in kb.commonOutputs[key]: - kb.commonOutputs[key].append(item) + if line not in kb.commonOutputs[key]: + kb.commonOutputs[key].append(line) cfile.close() @@ -1257,15 +1253,19 @@ def goGoodSamaritan(part, prevValue, originalCharset): wildIndexes = [] singleValue = None - # If the header we are looking for has common outputs defined + # If the header (e.g. Databases) we are looking for has common + # outputs defined if part in kb.commonOutputs: + # For each common output for item in kb.commonOutputs[part]: # Check if the common output (item) starts with prevValue + # where prevValue is the enumerated character(s) so far if item.startswith(prevValue): singleValue = item if len(item) > len(prevValue): char = item[len(prevValue)] + if char not in predictionSet: predictionSet.add(char) @@ -1285,7 +1285,7 @@ def goGoodSamaritan(part, prevValue, originalCharset): if len(commonCharset) > 1: return None, commonCharset, otherCharset else: - return singleValue, None, originalCharset + return singleValue, commonCharset, originalCharset else: return None, None, originalCharset @@ -1294,6 +1294,7 @@ def getCompiledRegex(regex, *args): Returns compiled regular expression and stores it in cache for further usage """ + if (regex, args) in kb.cache.regex: return kb.cache.regex[(regex, args)] else: diff --git a/lib/techniques/blind/inference.py b/lib/techniques/blind/inference.py index 52a841270..401aae03d 100644 --- a/lib/techniques/blind/inference.py +++ b/lib/techniques/blind/inference.py @@ -157,6 +157,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None forgedPayload = safeStringFormat(payload.replace('%3E', '%3D'), (expressionUnescaped, idx, charTbl[0])) queriesCount[0] += 1 result = Request.queryPage(urlencode(forgedPayload)) + if result: return chr(charTbl[0]) if charTbl[0] < 128 else unichr(charTbl[0]) else: @@ -171,10 +172,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None if kb.dbms == "SQLite": posValueOld = posValue - if posValue < 128: - posValue = chr(posValue) - else: - posValue = unichr(posValue) + posValue = chr(posValue) if posValue < 128 else unichr(posValue) if not conf.useBetween or kb.dbms == "SQLite": forgedPayload = safeStringFormat(payload, (expressionUnescaped, idx, posValue)) @@ -189,12 +187,14 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None if result: minValue = posValue + if type(charTbl) != xrange: charTbl = charTbl[position:] else: charTbl = xrange(charTbl[position], charTbl[-1] + 1) else: maxValue = posValue + if type(charTbl) != xrange: charTbl = charTbl[:position] else: @@ -214,12 +214,15 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None else: if minValue == maxChar or maxValue == minChar: return None + for retVal in (originalTbl[originalTbl.index(minValue)], originalTbl[originalTbl.index(minValue) + 1]): forgedPayload = safeStringFormat(payload.replace('%3E', '%3D'), (expressionUnescaped, idx, retVal)) queriesCount[0] += 1 result = Request.queryPage(urlencode(forgedPayload)) + if result: return chr(retVal) if retVal < 128 else unichr(retVal) + return None def etaProgressUpdate(charTime, index): @@ -390,9 +393,8 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None val = None singleValue, commonCharset, otherCharset = goGoodSamaritan(kb.partRun, finalValue, asciiTbl) - # If there is no singleValue (single match from - # txt/common-outputs.txt) use the returned common - # charset only to retrieve the query output + # If there is one single output in common-outputs, check + # it via equal against the query output if singleValue is not None: # One-shot query containing equals singleValue query = agent.prefixQuery(" %s" % safeStringFormat('AND (%s) = %s', (expressionUnescaped, unescaper.unescape('\'%s\'' % singleValue)))) @@ -412,7 +414,11 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None finalValue = singleValue break - elif commonCharset: + + # Otherwise if there is no singleValue (single match from + # txt/common-outputs.txt) use the returned common + # charset only to retrieve the query output + if commonCharset: val = getChar(index, commonCharset, False) # If we had no luck with singleValue and common charset, diff --git a/txt/common-outputs.txt b/txt/common-outputs.txt index c57f72c77..250571847 100644 --- a/txt/common-outputs.txt +++ b/txt/common-outputs.txt @@ -1,21 +1,19 @@ [Databases] -#MySQL +# MySQL information_schema mysql -public -master phpmyadmin -#Microsoft SQL Server +# Microsoft SQL Server tempdb model master msdb -[Tables] -#MySQL +[Tables] +# MySQL CHARACTER_SETS COLLATION_CHARACTER_SET_APPLICABILITY COLLATIONS @@ -68,7 +66,7 @@ time_zone_transition time_zone_transition_type user -#PHPMyAdmin +# PHPMyAdmin pma_bookmark pma_column_info pma_designer_coords @@ -78,14 +76,14 @@ pma_relation pma_table_coords pma_table_info -#Oracle +# Oracle BONUS DEPT EMP SALGRADE USERS -#Microsoft SQL Server +# Microsoft SQL Server all_columns all_objects all_parameters @@ -472,13 +470,13 @@ systaskids [Passwords] -#MySQL -*00E247AC5F9AF26AE0194B41E1E769DEE1429A29 #testpass +# MySQL +*00E247AC5F9AF26AE0194B41E1E769DEE1429A29 # testpass [Users] -#Oracle +# Oracle SCOTT MGMT_VIEW MDDATA