mirror of
				https://github.com/sqlmapproject/sqlmap.git
				synced 2025-10-31 07:57:47 +03:00 
			
		
		
		
	changes regarding EXISTS feature
This commit is contained in:
		
							parent
							
								
									51beafc32c
								
							
						
					
					
						commit
						cf8e92699c
					
				|  | @ -27,6 +27,7 @@ from lib.core.common import getHtmlErrorFp | |||
| from lib.core.common import dataToStdout | ||||
| from lib.core.data import conf | ||||
| from lib.core.data import kb | ||||
| from lib.core.data import paths | ||||
| from lib.core.exception import sqlmapUnsupportedDBMSException | ||||
| from lib.core.settings import SUPPORTED_DBMS | ||||
| from lib.techniques.blind.timebased import timeTest | ||||
|  | @ -111,6 +112,12 @@ def action(): | |||
|     if conf.getTables: | ||||
|         conf.dumper.dbTables(conf.dbmsHandler.getTables()) | ||||
| 
 | ||||
|     if conf.cExists: | ||||
|         conf.dumper.dbTables(conf.dbmsHandler.tableExists(paths.COMMON_TABLES)) | ||||
| 
 | ||||
|     if conf.tableFile: | ||||
|         conf.dumper.dbTables(conf.dbmsHandler.tableExists(conf.tableFile)) | ||||
| 
 | ||||
|     if conf.getColumns: | ||||
|         conf.dumper.dbTableColumns(conf.dbmsHandler.getColumns()) | ||||
| 
 | ||||
|  |  | |||
|  | @ -411,8 +411,8 @@ def filePathToString(filePath): | |||
| 
 | ||||
|     return strRepl | ||||
| 
 | ||||
| def dataToStdout(data): | ||||
|     if conf.verbose > 0: | ||||
| def dataToStdout(data, forceOutput=False): | ||||
|     if conf.verbose > 0 or forceOutput: | ||||
|         try: | ||||
|             sys.stdout.write(data) | ||||
|             sys.stdout.flush() | ||||
|  | @ -657,6 +657,8 @@ def setPaths(): | |||
|     # sqlmap files | ||||
|     paths.SQLMAP_HISTORY         = os.path.join(paths.SQLMAP_ROOT_PATH, ".sqlmap_history") | ||||
|     paths.SQLMAP_CONFIG          = os.path.join(paths.SQLMAP_ROOT_PATH, "sqlmap-%s.conf" % randomStr()) | ||||
|     paths.COMMON_OUTPUTS         = os.path.join(paths.SQLMAP_TXT_PATH, 'common-outputs.txt') | ||||
|     paths.COMMON_TABLES          = os.path.join(paths.SQLMAP_TXT_PATH, "common-tables.txt") | ||||
|     paths.FUZZ_VECTORS           = os.path.join(paths.SQLMAP_TXT_PATH, "fuzz_vectors.txt") | ||||
|     paths.DETECTION_RULES_XML    = os.path.join(paths.SQLMAP_XML_PATH, "detection.xml") | ||||
|     paths.ERRORS_XML             = os.path.join(paths.SQLMAP_XML_PATH, "errors.xml") | ||||
|  | @ -1233,8 +1235,7 @@ def initCommonOutputs(): | |||
|     kb.commonOutputs = {} | ||||
|     key = None | ||||
| 
 | ||||
|     fileName = os.path.join(paths.SQLMAP_TXT_PATH, 'common-outputs.txt') | ||||
|     cfile = codecs.open(fileName, 'r', conf.dataEncoding) | ||||
|     cfile = codecs.open(paths.COMMON_OUTPUTS, 'r', conf.dataEncoding) | ||||
| 
 | ||||
|     for line in cfile.readlines(): # xreadlines doesn't return unicode strings when codec.open() is used | ||||
|         if line.find('#') != -1: | ||||
|  | @ -1254,6 +1255,21 @@ def initCommonOutputs(): | |||
| 
 | ||||
|     cfile.close() | ||||
| 
 | ||||
| def getFileItems(filename): | ||||
|     retVal = [] | ||||
| 
 | ||||
|     checkFile(filename) | ||||
|     file = codecs.open(filename, 'r', conf.dataEncoding) | ||||
| 
 | ||||
|     for line in file.readlines(): # xreadlines doesn't return unicode strings when codec.open() is used | ||||
|         if line.find('#') != -1: | ||||
|             line = line[:line.find('#')] | ||||
|         line = line.strip() | ||||
|         if line: | ||||
|             retVal.append(line) | ||||
| 
 | ||||
|     return retVal | ||||
| 
 | ||||
| def goGoodSamaritan(prevValue, originalCharset): | ||||
|     """ | ||||
|     Function for retrieving parameters needed for common prediction (good | ||||
|  | @ -1411,4 +1427,10 @@ def replaceSpaces(query): | |||
|     if query: | ||||
|         return query if conf.space is None else query.replace(' ', conf.space) | ||||
|     else: | ||||
|         return query | ||||
|         return query | ||||
| 
 | ||||
| def pushValue(value): | ||||
|     kb.valueStack.append(value) | ||||
| 
 | ||||
| def popValue(): | ||||
|     return kb.valueStack.pop() | ||||
|  |  | |||
|  | @ -157,37 +157,58 @@ class Dump: | |||
|         self.lister("available databases", dbs) | ||||
| 
 | ||||
|     def dbTables(self, dbTables): | ||||
|         if not isinstance(dbTables, dict): | ||||
|             self.string("tables", dbTables) | ||||
|         if isinstance(dbTables, list): | ||||
|             maxlength = 0 | ||||
| 
 | ||||
|             return | ||||
| 
 | ||||
|         maxlength = 0 | ||||
| 
 | ||||
|         for tables in dbTables.values(): | ||||
|             for table in tables: | ||||
|             for table in dbTables: | ||||
|                 maxlength = max(maxlength, len(table)) | ||||
| 
 | ||||
|         lines = "-" * (int(maxlength) + 2) | ||||
|             lines = "-" * (int(maxlength) + 2) | ||||
| 
 | ||||
|         for db, tables in dbTables.items(): | ||||
|             tables.sort(key=lambda x: x.lower()) | ||||
|             dbTables.sort(key=lambda x: x.lower()) | ||||
| 
 | ||||
|             self.__write("Database: %s" % db) | ||||
| 
 | ||||
|             if len(tables) == 1: | ||||
|             if len(dbTables) == 1: | ||||
|                 self.__write("[1 table]") | ||||
|             else: | ||||
|                 self.__write("[%d tables]" % len(tables)) | ||||
|                 self.__write("[%d tables]" % len(dbTables)) | ||||
| 
 | ||||
|             self.__write("+%s+" % lines) | ||||
| 
 | ||||
|             for table in tables: | ||||
|             for table in dbTables: | ||||
|                 blank = " " * (maxlength - len(table)) | ||||
|                 self.__write("| %s%s |" % (table, blank)) | ||||
| 
 | ||||
|             self.__write("+%s+\n" % lines) | ||||
| 
 | ||||
|         elif isinstance(dbTables, dict): | ||||
|             maxlength = 0 | ||||
| 
 | ||||
|             for tables in dbTables.values(): | ||||
|                 for table in tables: | ||||
|                     maxlength = max(maxlength, len(table)) | ||||
| 
 | ||||
|             lines = "-" * (int(maxlength) + 2) | ||||
| 
 | ||||
|             for db, tables in dbTables.items(): | ||||
|                 tables.sort(key=lambda x: x.lower()) | ||||
| 
 | ||||
|                 self.__write("Database: %s" % db) | ||||
| 
 | ||||
|                 if len(tables) == 1: | ||||
|                     self.__write("[1 table]") | ||||
|                 else: | ||||
|                     self.__write("[%d tables]" % len(tables)) | ||||
| 
 | ||||
|                 self.__write("+%s+" % lines) | ||||
| 
 | ||||
|                 for table in tables: | ||||
|                     blank = " " * (maxlength - len(table)) | ||||
|                     self.__write("| %s%s |" % (table, blank)) | ||||
| 
 | ||||
|                 self.__write("+%s+\n" % lines) | ||||
|         else: | ||||
|             self.string("tables", dbTables) | ||||
| 
 | ||||
|     def dbTableColumns(self, tableColumns): | ||||
|         for db, tables in tableColumns.items(): | ||||
|             if not db: | ||||
|  |  | |||
|  | @ -1031,6 +1031,7 @@ def __setKnowledgeBaseAttributes(): | |||
|     kb.unionPosition  = None | ||||
|     kb.unionNegative  = False | ||||
|     kb.unionFalseCond = False | ||||
|     kb.valueStack     = [] | ||||
| 
 | ||||
| def __saveCmdline(): | ||||
|     """ | ||||
|  |  | |||
|  | @ -332,6 +332,12 @@ def cmdLineParser(): | |||
|                                action="store_true", default=False, | ||||
|                                help="Prompt for an interactive SQL shell") | ||||
| 
 | ||||
|         enumeration.add_option("--common-exists", dest="cExists", action="store_true", | ||||
|                                default=False, help="Check existence of common tables") | ||||
| 
 | ||||
|         enumeration.add_option("--exists", dest="tableFile", | ||||
|                                help="Check existence of user specified tables") | ||||
| 
 | ||||
|         # User-defined function options | ||||
|         udf = OptionGroup(parser, "User-defined function injection", "These " | ||||
|                           "options can be used to create custom user-defined " | ||||
|  |  | |||
|  | @ -23,12 +23,18 @@ Franklin St, Fifth Floor, Boston, MA  02110-1301  USA | |||
| """ | ||||
| 
 | ||||
| import re | ||||
| import time | ||||
| 
 | ||||
| from lib.core.agent import agent | ||||
| from lib.core.common import dataToStdout | ||||
| from lib.core.common import getRange | ||||
| from lib.core.common import getCompiledRegex | ||||
| from lib.core.common import getConsoleWidth | ||||
| from lib.core.common import getFileItems | ||||
| from lib.core.common import getUnicode | ||||
| from lib.core.common import parsePasswordHash | ||||
| from lib.core.common import popValue | ||||
| from lib.core.common import pushValue | ||||
| from lib.core.common import readInput | ||||
| from lib.core.common import safeStringFormat | ||||
| from lib.core.convert import urlencode | ||||
|  | @ -47,6 +53,7 @@ from lib.core.shell import autoCompletion | |||
| from lib.core.unescaper import unescaper | ||||
| from lib.parse.banner import bannerParser | ||||
| from lib.request import inject | ||||
| from lib.request.connect import Connect as Request | ||||
| from lib.techniques.inband.union.test import unionTest | ||||
| from lib.techniques.outband.stacked import stackedTest | ||||
| 
 | ||||
|  | @ -801,6 +808,41 @@ class Enumeration: | |||
| 
 | ||||
|         return kb.data.cachedTables | ||||
| 
 | ||||
|     def tableExists(self, tableFile): | ||||
|         tables = getFileItems(tableFile) | ||||
|         retVal = [] | ||||
|         infoMsg = "checking tables existence using items from '%s'" % tableFile | ||||
|         logger.info(infoMsg) | ||||
| 
 | ||||
|         pushValue(conf.verbose) | ||||
|         conf.verbose = 0 | ||||
|         count = 0 | ||||
|         length = len(tables) | ||||
| 
 | ||||
|         for table in tables: | ||||
|             query = agent.prefixQuery(" %s" % safeStringFormat("AND EXISTS(SELECT 1 FROM %s)", table)) | ||||
|             query = agent.postfixQuery(query) | ||||
|             result = Request.queryPage(urlencode(agent.payload(newValue=query))) | ||||
| 
 | ||||
|             if result: | ||||
|                 infoMsg = "\r[%s] [INFO] retrieved: %s" % (time.strftime("%X"), table) | ||||
|                 infoMsg = "%s%s\n" % (infoMsg, " "*(getConsoleWidth()-1-len(infoMsg))) | ||||
|                 dataToStdout(infoMsg, True) | ||||
|                 retVal.append(table) | ||||
| 
 | ||||
|             count += 1 | ||||
|             status = '%d/%d (%d%s)' % (count, length, round(100.0*count/length), '%') | ||||
|             dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status), True) | ||||
| 
 | ||||
|         conf.verbose = popValue() | ||||
| 
 | ||||
|         dataToStdout("\r%s\n" % (" "*(getConsoleWidth()-1)), True) | ||||
|         if not retVal: | ||||
|             warnMsg = "no table found" | ||||
|             logger.warn(warnMsg) | ||||
| 
 | ||||
|         return retVal | ||||
| 
 | ||||
|     def getColumns(self, onlyColNames=False): | ||||
|         if kb.dbms == "MySQL" and not kb.data.has_information_schema: | ||||
|             errMsg  = "information_schema not available, " | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user