def setInjection(inj): """ Save information retrieved about injection place and parameter in the session file. """ try: condition = ( not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and not kb.resumedQueries[conf.url].has_key("Injection data")) or ( kb.resumedQueries[conf.url].has_key("Injection data") and intersect(base64unpickle(kb.resumedQueries[conf.url]["Injection data"][:-1]).data.keys(),\ inj.data.keys()) != inj.data.keys() ) ) except AttributeError: warnMsg = "there were some changes in data model " warnMsg += "preventing normal resume of previously stored " warnMsg += "injection data. please use the --flush-session " warnMsg += "to have it fixed" singleTimeWarnMessage(warnMsg) condition = False if condition: dataToSessionFile("[%s][%s][%s][Injection data][%s]\n" % (conf.url, inj.place, safeFormatString(conf.parameters[inj.place]), base64pickle(inj)))
def direct(query, content=True): output = None select = True query = agent.payloadDirect(query) if Backend.isDbms(DBMS.ORACLE) and query.startswith("SELECT ") and " FROM " not in query: query = "%s FROM DUAL" % query for sqlTitle, sqlStatements in SQL_STATEMENTS.items(): for sqlStatement in sqlStatements: if query.lower().startswith(sqlStatement) and sqlTitle != "SQL SELECT statement": select = False break if select and not query.upper().startswith("SELECT "): query = "SELECT " + query logger.log(9, query) if not select: output = timeout(func=conf.dbmsConnector.execute, args=(query,), duration=conf.timeout, default=None) elif conf.hostname in kb.resumedQueries and query in kb.resumedQueries[conf.hostname] and "sqlmapoutput" not in query and "sqlmapfile" not in query: try: output = base64unpickle(kb.resumedQueries[conf.hostname][query][:-1]) except: output = timeout(func=conf.dbmsConnector.select, args=(query,), duration=conf.timeout, default=None) infoMsg = "resumed from file '%s': " % conf.sessionFile infoMsg += "%s..." % getUnicode(output, UNICODE_ENCODING)[:20] logger.info(infoMsg) else: output = timeout(func=conf.dbmsConnector.select, args=(query,), duration=conf.timeout, default=None) if output is None or len(output) == 0: return None elif content: if conf.hostname not in kb.resumedQueries or ( conf.hostname in kb.resumedQueries and query not in kb.resumedQueries[conf.hostname] ): dataToSessionFile("[%s][%s][%s][%s][%s]\n" % (conf.hostname, kb.injection.place, conf.parameters[kb.injection.place], query, base64pickle(output))) if len(output) == 1: if len(output[0]) == 1: out = list(output)[0][0] if isinstance(out, str): out = utf8decode(out) return getUnicode(out, UNICODE_ENCODING) else: return list(output) else: return output else: for line in output: if line[0] in (1, -1): return True else: return False
def scan_log(taskid): """ Retrieve the log messages """ log = None if taskid not in tasks: abort(500, "Invalid task ID") pickledLog = os.read(pipes[taskid][0], 100000) try: log = base64unpickle(pickledLog) except (KeyError, IndexError, TypeError), e: logger.error("handled exception when trying to unpickle logger dictionary in scan_log(): %s" % str(e))
def scan_log(taskid): """ Retrieve the log messages """ log = None if taskid not in tasks: abort(500, "Invalid task ID") pickledLog = os.read(pipes[taskid][0], 100000) try: log = base64unpickle(pickledLog) except (KeyError, IndexError, TypeError), e: logger.error( "handled exception when trying to unpickle logger dictionary in scan_log(): %s" % str(e))
def setInjection(inj): """ Save information retrieved about injection place and parameter in the session file. """ condition = ( not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and not kb.resumedQueries[conf.url].has_key("Injection data")) or ( kb.resumedQueries[conf.url].has_key("Injection data") and intersect(base64unpickle(kb.resumedQueries[conf.url]["Injection data"][:-1]).data.keys(),\ inj.data.keys()) != inj.data.keys() ) ) if condition: dataToSessionFile( "[%s][%s][%s][Injection data][%s]\n" % (conf.url, inj.place, safeFormatString( conf.parameters[inj.place]), base64pickle(inj)))
def scan_log_limited(taskid, start, end): """ Retrieve the log messages """ log = None if taskid not in tasks: abort(500, "Invalid task ID") if not start.isdigit() or not end.isdigit() or end <= start: abort(500, "Invalid start or end value, must be digits") start = max(0, int(start) - 1) end = max(1, int(end)) pickledLog = os.read(pipes[taskid][0], 100000) try: log = base64unpickle(pickledLog) log = log[slice(start, end)] except (KeyError, IndexError, TypeError), e: logger.error("handled exception when trying to unpickle logger dictionary in scan_log_limited(): %s" % str(e))
def scan_log_limited(taskid, start, end): """ Retrieve the log messages """ log = None if taskid not in tasks: abort(500, "Invalid task ID") if not start.isdigit() or not end.isdigit() or end <= start: abort(500, "Invalid start or end value, must be digits") start = max(0, int(start) - 1) end = max(1, int(end)) pickledLog = os.read(pipes[taskid][0], 100000) try: log = base64unpickle(pickledLog) log = log[slice(start, end)] except (KeyError, IndexError, TypeError), e: logger.error( "handled exception when trying to unpickle logger dictionary in scan_log_limited(): %s" % str(e))
def resumeConfKb(expression, url, value): if expression == "Injection data" and url == conf.url: injection = base64unpickle(value[:-1]) logMsg = "resuming injection data from session file" logger.info(logMsg) if injection.place in conf.paramDict and \ injection.parameter in conf.paramDict[injection.place]: if not conf.tech or intersect(conf.tech, injection.data.keys()): if intersect(conf.tech, injection.data.keys()): injection.data = dict( filter(lambda (key, item): key in conf.tech, injection.data.items())) if injection not in kb.injections: kb.injections.append(injection) else: warnMsg = "there is an injection in %s parameter '%s' " % ( injection.place, injection.parameter) warnMsg += "but you did not provided it this time" logger.warn(warnMsg) elif expression == "Dynamic markings" and url == conf.url: kb.dynamicMarkings = base64unpickle(value[:-1]) logMsg = "resuming dynamic markings from session file" logger.info(logMsg) elif expression == "DBMS" and url == conf.url: dbms = unSafeFormatString(value[:-1]) dbms = dbms.lower() dbmsVersion = [UNKNOWN_DBMS_VERSION] logMsg = "resuming back-end DBMS '%s' " % dbms logMsg += "from session file" logger.info(logMsg) firstRegExp = "(%s)" % ("|".join([alias for alias in SUPPORTED_DBMS])) dbmsRegExp = re.search("%s ([\d\.]+)" % firstRegExp, dbms) if dbmsRegExp: dbms = dbmsRegExp.group(1) dbmsVersion = [dbmsRegExp.group(2)] if conf.dbms and conf.dbms.lower() != dbms: message = "you provided '%s' as back-end DBMS, " % conf.dbms message += "but from a past scan information on the target URL " message += "sqlmap assumes the back-end DBMS is %s. " % dbms message += "Do you really want to force the back-end " message += "DBMS value? [y/N] " test = readInput(message, default="N") if not test or test[0] in ("n", "N"): Backend.setDbms(dbms) Backend.setVersionList(dbmsVersion) else: Backend.setDbms(dbms) Backend.setVersionList(dbmsVersion) elif expression == "OS" and url == conf.url: os = unSafeFormatString(value[:-1]) if os and os != 'None': logMsg = "resuming back-end DBMS operating system '%s' " % os logMsg += "from session file" logger.info(logMsg) if conf.os and conf.os.lower() != os.lower(): message = "you provided '%s' as back-end DBMS operating " % conf.os message += "system, but from a past scan information on the " message += "target URL sqlmap assumes the back-end DBMS " message += "operating system is %s. " % os message += "Do you really want to force the back-end DBMS " message += "OS value? [y/N] " test = readInput(message, default="N") if not test or test[0] in ("n", "N"): conf.os = os else: conf.os = os elif expression == "Remote temp path" and url == conf.url: conf.tmpPath = unSafeFormatString(value[:-1]) logMsg = "resuming remote absolute path of temporary " logMsg += "files directory '%s' from session file" % conf.tmpPath logger.info(logMsg) elif expression == "TABLE_EXISTS" and url == conf.url: table = unSafeFormatString(value[:-1]) split = '..' if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) else '.' if split in table: db, table = table.split(split) else: db = "%s%s" % (Backend.getIdentifiedDbms(), METADB_SUFFIX) logMsg = "resuming brute forced table name " logMsg += "'%s' from session file" % table logger.info(logMsg) kb.brute.tables.append((db, table)) elif expression == "COLUMN_EXISTS" and url == conf.url: table, column = unSafeFormatString(value[:-1]).split('|') colName, colType = column.split(' ') split = '..' if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) else '.' if split in table: db, table = table.split(split) else: db = "%s%s" % (Backend.getIdentifiedDbms(), METADB_SUFFIX) logMsg = "resuming brute forced column name " logMsg += "'%s' for table '%s' from session file" % (colName, table) logger.info(logMsg) kb.brute.columns.append((db, table, colName, colType))
def resumeConfKb(expression, url, value): if expression == "Injection data" and url == conf.url: try: injection = base64unpickle(value[:-1]) except AttributeError: warnMsg = "there were some changes in data model " warnMsg += "preventing normal resume of previously stored " warnMsg += "injection data. please use the --flush-session " warnMsg += "to have it fixed" singleTimeWarnMessage(warnMsg) return infoMsg = "resuming injection data from session file" logger.info(infoMsg) if injection.place in conf.paramDict and \ injection.parameter in conf.paramDict[injection.place]: if not conf.tech or intersect(conf.tech, injection.data.keys()): if intersect(conf.tech, injection.data.keys()): injection.data = dict(filter(lambda (key, item): key in conf.tech, injection.data.items())) if injection not in kb.injections: kb.injections.append(injection) else: warnMsg = "there is an injection in %s parameter '%s' " % (injection.place, injection.parameter) warnMsg += "but you did not provided it this time" logger.warn(warnMsg) elif expression == "Dynamic markings" and url == conf.url: kb.dynamicMarkings = base64unpickle(value[:-1]) infoMsg = "resuming dynamic markings from session file" logger.info(infoMsg) elif expression == "DBMS" and url == conf.url: dbms = unSafeFormatString(value[:-1]) dbms = dbms.lower() dbmsVersion = [UNKNOWN_DBMS_VERSION] infoMsg = "resuming back-end DBMS '%s' " % dbms infoMsg += "from session file" logger.info(infoMsg) firstRegExp = "(%s)" % ("|".join([alias for alias in SUPPORTED_DBMS])) dbmsRegExp = re.search("%s ([\d\.]+)" % firstRegExp, dbms) if dbmsRegExp: dbms = dbmsRegExp.group(1) dbmsVersion = [ dbmsRegExp.group(2) ] if conf.dbms and conf.dbms.lower() != dbms: message = "you provided '%s' as back-end DBMS, " % conf.dbms message += "but from a past scan information on the target URL " message += "sqlmap assumes the back-end DBMS is %s. " % dbms message += "Do you really want to force the back-end " message += "DBMS value? [y/N] " test = readInput(message, default="N") if not test or test[0] in ("n", "N"): conf.dbms = None Backend.setDbms(dbms) Backend.setVersionList(dbmsVersion) else: Backend.setDbms(dbms) Backend.setVersionList(dbmsVersion) elif expression == "OS" and url == conf.url: os = unSafeFormatString(value[:-1]) if os and os != 'None': infoMsg = "resuming back-end DBMS operating system '%s' " % os infoMsg += "from session file" logger.info(infoMsg) if conf.os and conf.os.lower() != os.lower(): message = "you provided '%s' as back-end DBMS operating " % conf.os message += "system, but from a past scan information on the " message += "target URL sqlmap assumes the back-end DBMS " message += "operating system is %s. " % os message += "Do you really want to force the back-end DBMS " message += "OS value? [y/N] " test = readInput(message, default="N") if not test or test[0] in ("n", "N"): conf.os = os else: conf.os = os Backend.setOs(conf.os) elif expression == "Remote temp path" and url == conf.url and conf.tmpPath is None: conf.tmpPath = unSafeFormatString(value[:-1]) infoMsg = "resuming remote absolute path of temporary " infoMsg += "files directory '%s' from session file" % conf.tmpPath logger.info(infoMsg) elif conf.freshQueries: pass elif expression == "TABLE_EXISTS" and url == conf.url: table = unSafeFormatString(value[:-1]) split = '..' if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) else '.' if split in table: db, table = table.split(split) else: db = "%s%s" % (Backend.getIdentifiedDbms(), METADB_SUFFIX) infoMsg = "resuming brute forced table name " infoMsg += "'%s' from session file" % table logger.info(infoMsg) kb.brute.tables.append((db, table)) elif expression == "COLUMN_EXISTS" and url == conf.url: table, column = unSafeFormatString(value[:-1]).split('|') colName, colType = column.split(' ') split = '..' if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) else '.' if split in table: db, table = table.split(split) else: db = "%s%s" % (Backend.getIdentifiedDbms(), METADB_SUFFIX) infoMsg = "resuming brute forced column name " infoMsg += "'%s' for table '%s' from session file" % (colName, table) logger.info(infoMsg) kb.brute.columns.append((db, table, colName, colType)) elif expression == "xp_cmdshell availability" and url == conf.url: kb.xpCmdshellAvailable = True if unSafeFormatString(value[:-1]).lower() == "true" else False infoMsg = "resuming xp_cmdshell availability" logger.info(infoMsg)