diff --git a/lib/core/common.py b/lib/core/common.py index ce2d8fd09..113cba5d6 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -1221,7 +1221,13 @@ def initCommonOutputs(): cfile.close() def getGoodSamaritanParameters(part, prevValue, originalCharset): - ###wild card . (dot) is supported for compatibility with threading + """ + Function for retrieving parameters needed for good samaritan (common outputs) feature. + Returns singleValue if there is a complete single match (in part of common-outputs.txt set by parameter 'part') + regarding parameter prevValue. If there is no single value match, but multiple, predictedCharset is returned + containing more probable characters (retrieved from matched items in common-outputs.txt) together with the + rest of charset as otherCharset + """ if kb.commonOutputs is None: initCommonOutputs() @@ -1272,6 +1278,9 @@ def getGoodSamaritanParameters(part, prevValue, originalCharset): return None, None, originalCharset def getCompiledRegex(regex, args=()): + """ + Returns compiled regular expression and stores it in cache for further usage + """ if regex in __compiledRegularExpressions: return __compiledRegularExpressions[regex] else: @@ -1279,8 +1288,10 @@ def getCompiledRegex(regex, args=()): __compiledRegularExpressions[regex] = retVal return retVal -#dumper.dbTableValues(conf.dbmsHandler.dumpTable()) -> dumpTable def getPartRun(): + """ + Goes through call stack and finds constructs matching conf.dmbsHandler.*. Returns it or it's alias used in common-outputs.txt + """ commonPartsDict = { "getTables":"Tables", "getColumns":"Columns", "getUsers":"Users", "getBanner":"Banners", "getDbs":"Databases" } retVal = None stack = [item[4][0] if isinstance(item[4], list) else '' for item in inspect.stack()] diff --git a/lib/techniques/blind/inference.py b/lib/techniques/blind/inference.py index 8f4514dac..696d1d4ab 100644 --- a/lib/techniques/blind/inference.py +++ b/lib/techniques/blind/inference.py @@ -57,7 +57,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None asciiTbl = getCharset(charsetType) - kb.partRun = getPartRun() if conf.useCommonPrediction else None + kb.partRun = getPartRun() if conf.useCommonPrediction else None #set kb.partRun in case common-prediction used if "LENGTH(" in expression or "LEN(" in expression: firstChar = 0 @@ -372,16 +372,20 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None index += 1 charStart = time.time() + #common prediction (a.k.a. good samaritan) if conf.useCommonPrediction: singleValue, predictedCharset, otherCharset = getGoodSamaritanParameters(kb.partRun, finalValue, asciiTbl) val = None + #if there is no singleValue (single match from common-outputs.txt) use the returned predictedCharset if singleValue is None: val = getChar(index, predictedCharset, False) if predictedCharset else None else: + #one shot query containing equals singleValue query = agent.prefixQuery(" %s" % safeStringFormat('AND (%s) = %s', (expressionUnescaped, unescaper.unescape('\'%s\'' % singleValue)))) query = agent.postfixQuery(query) result = Request.queryPage(urlencode(agent.payload(newValue=query))) + #did we have luck? if result: dataToSessionFile(replaceNewlineTabs(singleValue[index-1:])) if showEta: @@ -390,6 +394,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None dataToStdout(singleValue[index-1:]) finalValue = singleValue break + #if we had no luck with singleValue and predictedCharset use the returned otherCharset if not val: val = getChar(index, otherCharset) else: