diff --git a/lib/core/common.py b/lib/core/common.py index 5707ea27a..cd71a676b 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -3147,7 +3147,7 @@ def hashDBRetrieve(key, unserialize=False, checkConf=False): _ = "%s%s%s" % (conf.url or "%s%s" % (conf.hostname, conf.port), key, HASHDB_MILESTONE_VALUE) _ = conf.hashDB.retrieve(_, unserialize) if kb.resumeValues and not (checkConf and any([conf.flushSession, conf.freshQueries])) else None - if not kb.inferenceMode and _ and PARTIAL_VALUE_MARKER in _: + if not kb.inferenceMode and not kb.fileReadMode and _ and PARTIAL_VALUE_MARKER in _: _ = None return _ diff --git a/lib/techniques/error/use.py b/lib/techniques/error/use.py index 8232d24c8..3611463d0 100644 --- a/lib/techniques/error/use.py +++ b/lib/techniques/error/use.py @@ -35,6 +35,7 @@ from lib.core.enums import PAYLOAD from lib.core.settings import FROM_DUMMY_TABLE from lib.core.settings import MYSQL_ERROR_CHUNK_LENGTH from lib.core.settings import MSSQL_ERROR_CHUNK_LENGTH +from lib.core.settings import PARTIAL_VALUE_MARKER from lib.core.settings import SLOW_ORDER_COUNT_THRESHOLD from lib.core.settings import SQL_SCALAR_REGEX from lib.core.settings import TURN_OFF_RESUME_INFO_LIMIT @@ -44,90 +45,93 @@ from lib.core.unescaper import unescaper from lib.request.connect import Connect as Request def __oneShotErrorUse(expression, field): + offset = 1 + partialValue = None + threadData = getCurrentThreadData() retVal = hashDBRetrieve(expression, checkConf=True) - threadData = getCurrentThreadData() - threadData.resumed = retVal is not None + if retVal and PARTIAL_VALUE_MARKER in retVal: + partialValue = retVal = retVal.replace(PARTIAL_VALUE_MARKER, "") + dataToStdout("[%s] [INFO] resuming partial value: '%s'\r\n" % (time.strftime("%X"), __formatPartialContent(partialValue))) + offset += len(partialValue) - offset = 1 + threadData.resumed = retVal is not None and not partialValue chunk_length = None - if retVal is None: - while True: - check = "%s(?P.*?)%s" % (kb.chars.start, kb.chars.stop) - trimcheck = "%s(?P.*?).*?)%s" % (kb.chars.start, kb.chars.stop) + trimcheck = "%s(?P.*?)= chunk_length: + offset += chunk_length + else: + break + + if kb.fileReadMode and output: + dataToStdout(__formatPartialContent(output).replace(r"\n", "\n")) + else: retVal = output - else: - retVal += output if output else '' - - if output and len(output) >= chunk_length: - offset += chunk_length - else: break - - if kb.fileReadMode and output: - _ = output - try: - _ = safecharencode(output.decode("hex")).replace(r"\n", "\n") - except: - pass - finally: - dataToStdout(_) - else: - retVal = output - break + except: + hashDBWrite(expression, "%s%s" % (retVal, PARTIAL_VALUE_MARKER)) + raise retVal = decodeHexValue(retVal) if conf.hexConvert else retVal @@ -194,6 +198,20 @@ def __errorReplaceChars(value): return retVal +def __formatPartialContent(value): + """ + Prepares (possibly hex) partial content for safe console output + """ + + if value and isinstance(value, basestring): + try: + value = value.decode("hex") + except: + pass + finally: + value = safecharencode(value) + return value + def errorUse(expression, expected=None, dump=False): """ Retrieve the output of a SQL query taking advantage of the error-based