def parseXmlNode(node): for element in node.getiterator('boundary'): boundary = advancedDict() for child in element.getchildren(): if child.text: values = cleanupVals(child.text, child.tag) boundary[child.tag] = values else: boundary[child.tag] = None conf.boundaries.append(boundary) for element in node.getiterator('test'): test = advancedDict() for child in element.getchildren(): if child.text and child.text.strip(): values = cleanupVals(child.text, child.tag) test[child.tag] = values else: if len(child.getchildren()) == 0: test[child.tag] = None continue else: test[child.tag] = advancedDict() for gchild in child.getchildren(): if gchild.tag in test[child.tag]: prevtext = test[child.tag][gchild.tag] test[child.tag][gchild.tag] = [prevtext, gchild.text] else: test[child.tag][gchild.tag] = gchild.text conf.tests.append(test)
def init(inputOptions=advancedDict()): """ Set attributes into both configuration and knowledge base singletons based upon command line and configuration file options. """ __mergeOptions(inputOptions) __setVerbosity() __saveCmdline() __setConfAttributes() __setKnowledgeBaseAttributes() __cleanupOptions() __setHTTPTimeout() __setHTTPCookies() __setHTTPReferer() __setHTTPUserAgent() __setHTTPExtraHeaders() __setHTTPMethod() __setHTTPAuthentication() __setHTTPProxy() __setThreads() __setDBMS() __setGoogleDorking() __setMultipleTargets() __urllib2Opener() update() queriesParser()
def endElement(self, name): if name == "dbms": queries[self.__dbms] = self.__queries self.__queries = advancedDict() elif name == "users": self.__users = {} self.__users["inband"] = { "query": self.__inband, "query2": self.__inband2 } self.__users["blind"] = { "query": self.__blind, "query2": self.__blind2, "count": self.__count, "count2": self.__count2 } self.__queries.users = self.__users elif name == "passwords": self.__passwords = {} self.__passwords["inband"] = { "query": self.__inband, "query2": self.__inband2, "condition": self.__condition } self.__passwords["blind"] = { "query": self.__blind, "query2": self.__blind2, "count": self.__count, "count2": self.__count2 } self.__queries.passwords = self.__passwords elif name == "privileges": self.__privileges = {} self.__privileges["inband"] = { "query": self.__inband, "query2": self.__inband2, "condition": self.__condition, "condition2": self.__condition2 } self.__privileges["blind"] = { "query": self.__blind, "query2": self.__blind2, "count": self.__count, "count2": self.__count2 } self.__queries.privileges = self.__privileges elif name == "dbs": self.__dbs = {} self.__dbs["inband"] = { "query": self.__inband, "query2": self.__inband2 } self.__dbs["blind"] = { "query": self.__blind, "query2": self.__blind2, "count": self.__count, "count2": self.__count2 } self.__queries.dbs = self.__dbs elif name == "tables": self.__tables = {} self.__tables["inband"] = { "query": self.__inband, "condition": self.__condition } self.__tables["blind"] = { "query": self.__blind, "count": self.__count } self.__queries.tables = self.__tables elif name == "columns": self.__columns = {} self.__columns["inband"] = { "query": self.__inband } self.__columns["blind"] = { "query": self.__blind, "query2": self.__blind2, "count": self.__count } self.__queries.columns = self.__columns elif name == "dump_table": self.__dumpTable = {} self.__dumpTable["inband"] = { "query": self.__inband } self.__dumpTable["blind"] = { "query": self.__blind, "count": self.__count } self.__queries.dumpTable = self.__dumpTable
def __setKnowledgeBaseAttributes(): """ This function set some needed attributes into the knowledge base singleton. """ debugMsg = "initializing the knowledge base" logger.debug(debugMsg) kb.absFilePaths = set() kb.bannerFp = advancedDict() kb.data = advancedDict() # Basic back-end DBMS fingerprint kb.dbms = None kb.dbmsDetected = False # Active (extensive) back-end DBMS fingerprint kb.dbmsVersion = [ "Unknown" ] kb.dep = None kb.docRoot = None kb.headersCount = 0 kb.headersFp = {} kb.htmlFp = [] kb.injParameter = None kb.injPlace = None kb.injType = None # Back-end DBMS underlying operating system fingerprint via banner (-b) # parsing kb.os = None kb.osVersion = None kb.osSP = None kb.parenthesis = None kb.resumedQueries = {} kb.stackedTest = None kb.targetUrls = set() kb.timeTest = None kb.unionComment = "" kb.unionCount = None kb.unionPosition = None
def init(inputOptions=advancedDict()): """ Set attributes into both configuration and knowledge base singletons based upon command line and configuration file options. """ __setConfAttributes() __setKnowledgeBaseAttributes() __mergeOptions(inputOptions) __setVerbosity() __saveCmdline() __cleanupOptions() __basicOptionValidation() __setRequestFromFile() __setMultipleTargets() __setTamperingFunctions() __setTrafficOutputFP() parseTargetUrl() parseTargetDirect() if conf.url or conf.list or conf.requestFile or conf.googleDork or conf.liveTest: __setHTTPTimeout() __setHTTPExtraHeaders() __setHTTPCookies() __setHTTPReferer() __setHTTPUserAgent() __setHTTPMethod() __setHTTPAuthentication() __setHTTPProxy() __setSafeUrl() __setUnion() __setGoogleDorking() __urllib2Opener() __findPageForms() __setDBMS() __setThreads() __setOS() __setWriteFile() __setMetasploit() update() __loadQueries()
def init(inputOptions = advancedDict()): __setConfAttributes() #初始化参数 setFingerConfAttributes() #初始化FingerConf if inputOptions.list: #如果有-l参数,则读取文件,保存在list中 f = open(inputOptions.list) for line in f.readlines(): print line.strip() conf.list.append(line.strip()) print(conf.list) elif not inputOptions.url: #必须存在-l或-u参数之一以确定目标地址 print("You must give one of '-l' or '-u' option") return False conf.url = inputOptions.url conf.app = inputOptions.app conf.information = inputOptions.information conf.verbose = inputOptions.verbose
def __setKnowledgeBaseAttributes(): """ This function set some needed attributes into the knowledge base singleton. """ debugMsg = "initializing the knowledge base" logger.debug(debugMsg) kb.absFilePaths = set() kb.assumeEmpty = False kb.authHeader = None kb.bannerFp = advancedDict() kb.cache = advancedDict() kb.cache.content = {} kb.cache.regex = {} kb.commonOutputs = None kb.data = advancedDict() # Basic back-end DBMS fingerprint kb.dbms = None kb.dbmsDetected = False # Active (extensive) back-end DBMS fingerprint kb.dbmsVersion = [ "Unknown" ] kb.dep = None kb.docRoot = None kb.dynamicMarkings = [] kb.errorTest = None kb.formNames = advancedDict() kb.headersCount = 0 kb.headersFp = {} kb.hintValue = None kb.htmlFp = [] kb.injParameter = None kb.injPlace = None kb.injType = None kb.injections = xmlobject.XMLFile(path=paths.INJECTIONS_XML) kb.keywords = set(getFileItems(paths.SQL_KEYWORDS)) kb.lastErrorPage = None kb.lastRequestUID = 0 kb.locks = advancedDict() kb.locks.cacheLock = threading.Lock() kb.locks.reqLock = threading.Lock() kb.locks.seqLock = None kb.nullConnection = None # Back-end DBMS underlying operating system fingerprint via banner (-b) # parsing kb.os = None kb.osVersion = None kb.osSP = None kb.pageStable = None kb.paramMatchRatio = {} kb.parenthesis = None kb.partRun = None kb.proxyAuthHeader = None kb.queryCounter = 0 kb.resumedQueries = {} kb.stackedTest = None kb.tamperFunctions = [] kb.targetUrls = set() kb.testedParams = set() kb.timeTest = None kb.unionComment = "" kb.unionCount = None kb.unionPosition = None kb.unionNegative = False kb.unionFalseCond = False kb.unionTest = None kb.userAgents = None kb.valueStack = []
def checkSqlInjection(place, parameter, value): # Store here the details about boundaries and payload used to # successfully inject injection = injectionDict() # Localized thread data needed for some methods threadData = getCurrentThreadData() # Set the flag for sql injection test mode kb.testMode = True for test in getSortedInjectionTests(): try: if kb.endDetection: break title = test.title stype = test.stype clause = test.clause if stype == 3: configUnion(test.request.char) if test.request.columns == "[COLSTART]-[COLSTOP]": if conf.uCols is None: continue else: title = title.replace("[COLSTART]", str(conf.uColsStart)) title = title.replace("[COLSTOP]", str(conf.uColsStop)) if "[CHAR]" in title: title = title.replace("[CHAR]", conf.uChar) if "[RANDNUM]" in title: title = title.replace("[RANDNUM]", "random number") # Skip test if the user's wants to test only for a specific # technique if conf.tech and isinstance(conf.tech, list) and stype not in conf.tech: debugMsg = "skipping test '%s' because the user " % title debugMsg += "specified to test only for " debugMsg += "%s" % ",".join(map(lambda x: PAYLOAD.SQLINJECTION[x], conf.tech)) logger.debug(debugMsg) continue # Skip test if it is the same SQL injection type already # identified by another test if injection.data and stype in injection.data: debugMsg = "skipping test '%s' because " % title debugMsg += "the payload for %s has " % PAYLOAD.SQLINJECTION[stype] debugMsg += "already been identified" logger.debug(debugMsg) continue # Skip test if the risk is higher than the provided (or default) # value # Parse test's <risk> if test.risk > conf.risk: debugMsg = "skipping test '%s' because the risk " % title debugMsg += "is higher than the provided" logger.debug(debugMsg) continue # Skip test if the level is higher than the provided (or default) # value # Parse test's <level> if test.level > conf.level: debugMsg = "skipping test '%s' because the level " % title debugMsg += "is higher than the provided" logger.debug(debugMsg) continue # Skip DBMS-specific test if it does not match either the # previously identified or the user's provided DBMS (either # from program switch or from parsed error message(s)) if "details" in test and "dbms" in test.details: dbms = test.details.dbms else: dbms = None if dbms is not None: if injection.dbms is not None and not intersect(injection.dbms, dbms): debugMsg = "skipping test '%s' because " % title debugMsg += "the back-end DBMS identified is " debugMsg += "%s" % injection.dbms logger.debug(debugMsg) continue if conf.dbms is not None and not intersect(conf.dbms.lower(), [value.lower() for value in arrayizeValue(dbms)]): debugMsg = "skipping test '%s' because " % title debugMsg += "the provided DBMS is %s" % conf.dbms logger.debug(debugMsg) continue if len(Backend.getErrorParsedDBMSes()) > 0 and not intersect(dbms, Backend.getErrorParsedDBMSes()) and kb.skipOthersDbms is None: msg = "parsed error message(s) showed that the " msg += "back-end DBMS could be %s. " % Format.getErrorParsedDBMSes() msg += "Do you want to skip test payloads specific for other DBMSes? [Y/n]" if conf.realTest or readInput(msg, default="Y") in ("y", "Y"): kb.skipOthersDbms = Backend.getErrorParsedDBMSes() else: kb.skipOthersDbms = [] if kb.skipOthersDbms and not intersect(dbms, kb.skipOthersDbms): debugMsg = "skipping test '%s' because " % title debugMsg += "the parsed error message(s) showed " debugMsg += "that the back-end DBMS could be " debugMsg += "%s" % Format.getErrorParsedDBMSes() logger.debug(debugMsg) continue # Skip test if it does not match the same SQL injection clause # already identified by another test clauseMatch = False for clauseTest in clause: if injection.clause is not None and clauseTest in injection.clause: clauseMatch = True break if clause != [ 0 ] and injection.clause and injection.clause != [ 0 ] and not clauseMatch: debugMsg = "skipping test '%s' because the clauses " % title debugMsg += "differs from the clause already identified" logger.debug(debugMsg) continue # Skip test if the user provided custom column # range and this is not a custom UNION test if conf.uCols is not None and hasattr(test.request, "columns") and test.request.columns != "[COLSTART]-[COLSTOP]": debugMsg = "skipping test '%s' because custom " % title debugMsg += "UNION columns range was provided" logger.debug(debugMsg) continue infoMsg = "testing '%s'" % title logger.info(infoMsg) # Flag used for signaling warning messages regarding unescaping genericWarningFlag = False # Force back-end DBMS according to the current # test value for proper payload unescaping Backend.forceDbms(dbms[0] if isinstance(dbms, list) else dbms) # Parse test's <request> comment = agent.getComment(test.request) fstPayload = agent.cleanupPayload(test.request.payload, origValue=value) for boundary in conf.boundaries: injectable = False # Skip boundary if the level is higher than the provided (or # default) value # Parse boundary's <level> if boundary.level > conf.level: continue # Skip boundary if it does not match against test's <clause> # Parse test's <clause> and boundary's <clause> clauseMatch = False for clauseTest in test.clause: if clauseTest in boundary.clause: clauseMatch = True break if test.clause != [ 0 ] and boundary.clause != [ 0 ] and not clauseMatch: continue # Skip boundary if it does not match against test's <where> # Parse test's <where> and boundary's <where> whereMatch = False for where in test.where: if where in boundary.where: whereMatch = True break if not whereMatch: continue # Parse boundary's <prefix>, <suffix> and <ptype> prefix = boundary.prefix if boundary.prefix else "" suffix = boundary.suffix if boundary.suffix else "" ptype = boundary.ptype # If the previous injections succeeded, we know which prefix, # suffix and parameter type to use for further tests, no # need to cycle through the boundaries for the following tests condBound = (injection.prefix is not None and injection.suffix is not None) condBound &= (injection.prefix != prefix or injection.suffix != suffix) condType = injection.ptype is not None and injection.ptype != ptype if condBound or condType: continue # For each test's <where> for where in test.where: templatePayload = None vector = None # Threat the parameter original value according to the # test's <where> tag if where == PAYLOAD.WHERE.ORIGINAL: origValue = value elif where == PAYLOAD.WHERE.NEGATIVE: # Use different page template than the original # one as we are changing parameters value, which # will likely result in a different content origValue = "-%s" % randomInt() templatePayload = agent.payload(place, parameter, newValue=origValue, where=where) elif where == PAYLOAD.WHERE.REPLACE: origValue = "" kb.pageTemplate, kb.errorIsNone = getPageTemplate(templatePayload, place) # Forge request payload by prepending with boundary's # prefix and appending the boundary's suffix to the # test's ' <payload><comment> ' string boundPayload = agent.prefixQuery(fstPayload, prefix, where, clause) boundPayload = agent.suffixQuery(boundPayload, comment, suffix, where) reqPayload = agent.payload(place, parameter, newValue=boundPayload, where=where) # Perform the test's request and check whether or not the # payload was successful # Parse test's <response> for method, check in test.response.items(): check = agent.cleanupPayload(check, origValue=value) # In case of boolean-based blind SQL injection if method == PAYLOAD.METHOD.COMPARISON: # Generate payload used for comparison def genCmpPayload(): sndPayload = agent.cleanupPayload(test.response.comparison, origValue=value) # Forge response payload by prepending with # boundary's prefix and appending the boundary's # suffix to the test's ' <payload><comment> ' # string boundPayload = agent.prefixQuery(sndPayload, prefix, where, clause) boundPayload = agent.suffixQuery(boundPayload, comment, suffix, where) cmpPayload = agent.payload(place, parameter, newValue=boundPayload, where=where) return cmpPayload # Useful to set kb.matchRatio at first based on # the False response content kb.matchRatio = None _ = Request.queryPage(genCmpPayload(), place, raise404=False) # If in the comparing stage there was an error # then anything non-error will be considered as True if kb.errorIsNone and kb.matchRatio is None: kb.matchRatio = LOWER_RATIO_BOUND # Perform the test's True request trueResult = Request.queryPage(reqPayload, place, raise404=False) if trueResult: falseResult = Request.queryPage(genCmpPayload(), place, raise404=False) # Perform the test's False request if not falseResult: infoMsg = "%s parameter '%s' is '%s' injectable " % (place, parameter, title) logger.info(infoMsg) injectable = True # In case of error-based SQL injection elif method == PAYLOAD.METHOD.GREP: # Perform the test's request and grep the response # body for the test's <grep> regular expression try: page, headers = Request.queryPage(reqPayload, place, content=True, raise404=False) output = extractRegexResult(check, page, re.DOTALL | re.IGNORECASE) \ or extractRegexResult(check, listToStrValue(headers.headers \ if headers else None), re.DOTALL | re.IGNORECASE) \ or extractRegexResult(check, threadData.lastRedirectMsg[1] \ if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == \ threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE) if output: result = output == "1" if result: infoMsg = "%s parameter '%s' is '%s' injectable " % (place, parameter, title) logger.info(infoMsg) injectable = True except sqlmapConnectionException, msg: debugMsg = "problem occured most likely because the " debugMsg += "server hasn't recovered as expected from the " debugMsg += "error-based payload used ('%s')" % msg logger.debug(debugMsg) # In case of time-based blind or stacked queries # SQL injections elif method == PAYLOAD.METHOD.TIME: # Perform the test's request trueResult = Request.queryPage(reqPayload, place, timeBasedCompare=True, raise404=False) if trueResult: # Confirm test's results trueResult = Request.queryPage(reqPayload, place, timeBasedCompare=True, raise404=False) if trueResult: infoMsg = "%s parameter '%s' is '%s' injectable " % (place, parameter, title) logger.info(infoMsg) injectable = True # In case of UNION query SQL injection elif method == PAYLOAD.METHOD.UNION: # Test for UNION injection and set the sample # payload as well as the vector. # NOTE: vector is set to a tuple with 6 elements, # used afterwards by Agent.forgeInbandQuery() # method to forge the UNION query payload configUnion(test.request.char, test.request.columns) if not Backend.getIdentifiedDbms() and not genericWarningFlag: warnMsg = "using unescaped version of the test " warnMsg += "because of zero knowledge of the " warnMsg += "back-end DBMS" logger.warn(warnMsg) # Set the flag preventing bulking of the message for the same test genericWarningFlag = True # Test for UNION query SQL injection reqPayload, vector = unionTest(comment, place, parameter, value, prefix, suffix) if isinstance(reqPayload, basestring): infoMsg = "%s parameter '%s' is '%s' injectable" % (place, parameter, title) logger.info(infoMsg) injectable = True # Overwrite 'where' because it can be set # by unionTest() directly where = vector[6] # If the injection test was successful feed the injection # object with the test's details if injectable is True: # Feed with the boundaries details only the first time a # test has been successful if injection.place is None or injection.parameter is None: if place in (PLACE.UA, PLACE.REFERER): injection.parameter = place else: injection.parameter = parameter injection.place = place injection.ptype = ptype injection.prefix = prefix injection.suffix = suffix injection.clause = clause # Feed with test details every time a test is successful if hasattr(test, "details"): for dKey, dValue in test.details.items(): if dKey == "dbms" and not isinstance(dValue, list): injection.dbms = Backend.setDbms(dValue) elif dKey == "dbms_version" and injection.dbms_version is None: injection.dbms_version = Backend.setVersion(dValue) elif dKey == "os" and injection.os is None: injection.os = Backend.setOs(dValue) if vector is None and "vector" in test and test.vector is not None: vector = "%s%s" % (test.vector, comment) injection.data[stype] = advancedDict() injection.data[stype].title = title injection.data[stype].payload = agent.removePayloadDelimiters(reqPayload) injection.data[stype].where = where injection.data[stype].vector = vector injection.data[stype].comment = comment injection.data[stype].templatePayload = templatePayload injection.data[stype].matchRatio = kb.matchRatio injection.conf.textOnly = conf.textOnly injection.conf.string = conf.string injection.conf.regexp = conf.regexp if conf.beep or conf.realTest: beep() # There is no need to perform this test for other # <where> tags break if injectable is True: # There is no need to perform this test with others # boundaries break
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with sqlmap; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from lib.core.datatype import advancedDict from lib.core.settings import LOGGER # sqlmap paths paths = advancedDict() # object to share within function and classes command # line options and settings conf = advancedDict() # object to share within function and classes results kb = advancedDict() # object to share within function and classes temporary data, # just for internal use temp = advancedDict() # object with each database management system specific queries queries = {}
def __init__(self): kb.misc = advancedDict() kb.misc.delimiter = randomStr(6) kb.misc.start = randomStr(6) kb.misc.stop = randomStr(6)
from lib.core.datatype import advancedDict from lib.core.enums import DBMS from lib.core.settings import LOGGER from lib.core.settings import MSSQL_ALIASES from lib.core.settings import MYSQL_ALIASES from lib.core.settings import PGSQL_ALIASES from lib.core.settings import ORACLE_ALIASES from lib.core.settings import SQLITE_ALIASES from lib.core.settings import ACCESS_ALIASES from lib.core.settings import FIREBIRD_ALIASES from lib.core.settings import MAXDB_ALIASES from lib.core.settings import SYBASE_ALIASES # sqlmap paths paths = advancedDict() # object to store original command line options cmdLineOptions = advancedDict() # object to share within function and classes command # line options and settings conf = advancedDict() # object to share within function and classes results kb = advancedDict() # object with each database management system specific queries queries = {} # logger
# -*- coding: utf-8 -* from lib.core.datatype import advancedDict conf = advancedDict() #实例化conf字典 fingerInfo = advancedDict() #实例化fingerInfo字典 fingerConf = advancedDict() #实例化fingerConf字典 versionInfo = advancedDict() #实例化fingerConf字典
def __init__(self): self.__dbms = '' self.__queries = advancedDict()
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with sqlmap; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from lib.core.datatype import advancedDict from lib.core.settings import LOGGER # sqlmap paths paths = advancedDict() # object to share within function and classes command # line options and settings conf = advancedDict() # object to share within function and classes results kb = advancedDict() # object to share within function and classes temporary data, # just for internal use temp = advancedDict() # object with each database management system specific queries queries = {}