mirror of
				https://github.com/sqlmapproject/sqlmap.git
				synced 2025-11-01 00:17:25 +03:00 
			
		
		
		
	Minor enhancement to fingerprint the back-end DBMS operating system (type,
version, release, distribution, codename and service pack) by parsing the
DBMS banner value when both -f and -b are provided: adapted the code and
added XML files defining regular expressions for matching.
Example of the -f -b output now on MySQL 5.0.67 running on latest Ubuntu:
--8<--
back-end DBMS:	active fingerprint: MySQL >= 5.0.38 and < 5.1.2
                comment injection fingerprint: MySQL 5.0.67
                banner parsing fingerprint: MySQL 5.0.67
                html error message fingerprint: MySQL
back-end DBMS operating system: Linux Ubuntu 8.10 (Intrepid)
--8<--
			
			
This commit is contained in:
		
							parent
							
								
									84cbc60659
								
							
						
					
					
						commit
						fa0507ab39
					
				|  | @ -1,14 +1,17 @@ | ||||||
| sqlmap (0.6.3-1) stable; urgency=low | sqlmap (0.6.3-1) stable; urgency=low | ||||||
| 
 | 
 | ||||||
|  |   * Major bug fix to correctly handle httplib.BadStatusLine exception; | ||||||
|   * Minor enhancement to support stacked queries which will be used |   * Minor enhancement to support stacked queries which will be used | ||||||
|     sometimes by takeover functionality and time based blind SQL injection |     sometimes by takeover functionality and time based blind SQL injection | ||||||
|     technique; |     technique; | ||||||
|   * Minor enhancement to be able to specify the number of seconds to wait |   * Minor enhancement to be able to specify the number of seconds to wait | ||||||
|     between each HTTP request; |     between each HTTP request; | ||||||
|   * Minor enhancement to be able to enumerate table columns and dump table |   * Minor enhancement to be able to enumerate table columns and dump table | ||||||
|     entries also if the database name is not provided by using the current |     entries, also when the database name is not provided, by using the | ||||||
|     database on MySQL and MSSQL, the 'public' scheme on PostgreSQL and the |     current database on MySQL and Microsoft SQL Server, the 'public' | ||||||
|     'USERS' TABLESPACE_NAME on Oracle; |     scheme on PostgreSQL and the 'USERS' TABLESPACE_NAME on Oracle; | ||||||
|  |   * Minor improvement to set by default in all HTTP requests the standard | ||||||
|  |     HTTP headers (Accept, Accept-Encoding, etc); | ||||||
|   * Minor improvements to sqlmap Debian package files: sqlmap uploaded |   * Minor improvements to sqlmap Debian package files: sqlmap uploaded | ||||||
|     to official Debian project repository; |     to official Debian project repository; | ||||||
|   * Minor bug fix to handle session.error and session.timeout in HTTP |   * Minor bug fix to handle session.error and session.timeout in HTTP | ||||||
|  |  | ||||||
|  | @ -55,7 +55,7 @@ def setHandler(): | ||||||
| 
 | 
 | ||||||
|     for dbmsAliases, dbmsEntry in dbmsMap: |     for dbmsAliases, dbmsEntry in dbmsMap: | ||||||
|         if conf.dbms and conf.dbms not in dbmsAliases: |         if conf.dbms and conf.dbms not in dbmsAliases: | ||||||
|             debugMsg  = "skipping to test for %s" % dbmsNames[count] |             debugMsg  = "skipping test for %s" % dbmsNames[count] | ||||||
|             logger.debug(debugMsg) |             logger.debug(debugMsg) | ||||||
|             count += 1 |             count += 1 | ||||||
|             continue |             continue | ||||||
|  |  | ||||||
|  | @ -112,7 +112,7 @@ def paramToDict(place, parameters=None): | ||||||
|     return testableParameters |     return testableParameters | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def formatFingerprint(versions=None): | def formatDBMSfp(versions=None): | ||||||
|     """ |     """ | ||||||
|     This function format the back-end DBMS fingerprint value and return its |     This function format the back-end DBMS fingerprint value and return its | ||||||
|     values formatted as a human readable string. |     values formatted as a human readable string. | ||||||
|  | @ -130,6 +130,47 @@ def formatFingerprint(versions=None): | ||||||
|         return "%s %s" % (kb.dbms, " and ".join([version for version in versions])) |         return "%s %s" % (kb.dbms, " and ".join([version for version in versions])) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | def formatOSfp(info): | ||||||
|  |     """ | ||||||
|  |     This function format the back-end operating system fingerprint value | ||||||
|  |     and return its values formatted as a human readable string. | ||||||
|  | 
 | ||||||
|  |     @return: detected back-end operating system based upon fingerprint | ||||||
|  |     techniques. | ||||||
|  |     @rtype: C{str} | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     infoStr = "" | ||||||
|  | 
 | ||||||
|  |     # Example of 'info' dictionary: | ||||||
|  |     # { | ||||||
|  |     #   'distrib': 'Ubuntu', | ||||||
|  |     #   'release': '8.10', | ||||||
|  |     #   'codename': 'Intrepid', | ||||||
|  |     #   'version': '5.0.67', | ||||||
|  |     #   'type': 'Linux' | ||||||
|  |     # } | ||||||
|  | 
 | ||||||
|  |     if not info or 'type' not in info: | ||||||
|  |         return infoStr | ||||||
|  |     elif info['type'] != "None": | ||||||
|  |         infoStr += "back-end DBMS operating system: %s" % info['type'] | ||||||
|  | 
 | ||||||
|  |     if 'distrib' in info and info['distrib'] != "None": | ||||||
|  |         infoStr += " %s" % info['distrib'] | ||||||
|  | 
 | ||||||
|  |     if 'release' in info and info['release'] != "None": | ||||||
|  |         infoStr += " %s" % info['release'] | ||||||
|  | 
 | ||||||
|  |     if 'sp' in info and info['sp'] != "None": | ||||||
|  |         infoStr += " %s" % info['sp'] | ||||||
|  | 
 | ||||||
|  |     if 'codename' in info and info['codename'] != "None": | ||||||
|  |         infoStr += " (%s)" % info['codename'] | ||||||
|  | 
 | ||||||
|  |     return infoStr | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def getHtmlErrorFp(): | def getHtmlErrorFp(): | ||||||
|     """ |     """ | ||||||
|     This function parses the knowledge base htmlFp list and return its |     This function parses the knowledge base htmlFp list and return its | ||||||
|  | @ -442,20 +483,25 @@ def cleanQuery(query): | ||||||
| 
 | 
 | ||||||
| def setPaths(): | def setPaths(): | ||||||
|     # sqlmap paths |     # sqlmap paths | ||||||
|     paths.SQLMAP_SHELL_PATH  = "%s/shell" % paths.SQLMAP_ROOT_PATH |     paths.SQLMAP_SHELL_PATH      = "%s/shell" % paths.SQLMAP_ROOT_PATH | ||||||
|     paths.SQLMAP_TXT_PATH    = "%s/txt" % paths.SQLMAP_ROOT_PATH |     paths.SQLMAP_TXT_PATH        = "%s/txt" % paths.SQLMAP_ROOT_PATH | ||||||
|     paths.SQLMAP_XML_PATH    = "%s/xml" % paths.SQLMAP_ROOT_PATH |     paths.SQLMAP_XML_PATH        = "%s/xml" % paths.SQLMAP_ROOT_PATH | ||||||
|     paths.SQLMAP_OUTPUT_PATH = "%s/output" % paths.SQLMAP_ROOT_PATH |     paths.SQLMAP_XML_BANNER_PATH = "%s/banner" % paths.SQLMAP_XML_PATH | ||||||
|     paths.SQLMAP_DUMP_PATH   = paths.SQLMAP_OUTPUT_PATH + "/%s/dump" |     paths.SQLMAP_OUTPUT_PATH     = "%s/output" % paths.SQLMAP_ROOT_PATH | ||||||
|     paths.SQLMAP_FILES_PATH  = paths.SQLMAP_OUTPUT_PATH + "/%s/files" |     paths.SQLMAP_DUMP_PATH       = paths.SQLMAP_OUTPUT_PATH + "/%s/dump" | ||||||
|  |     paths.SQLMAP_FILES_PATH      = paths.SQLMAP_OUTPUT_PATH + "/%s/files" | ||||||
| 
 | 
 | ||||||
|     # sqlmap files |     # sqlmap files | ||||||
|     paths.SQLMAP_HISTORY    = "%s/.sqlmap_history" % paths.SQLMAP_ROOT_PATH |     paths.SQLMAP_HISTORY         = "%s/.sqlmap_history" % paths.SQLMAP_ROOT_PATH | ||||||
|     paths.SQLMAP_CONFIG     = "%s/sqlmap-%s.conf" % (paths.SQLMAP_ROOT_PATH, randomStr()) |     paths.SQLMAP_CONFIG          = "%s/sqlmap-%s.conf" % (paths.SQLMAP_ROOT_PATH, randomStr()) | ||||||
|     paths.FUZZ_VECTORS      = "%s/fuzz_vectors.txt" % paths.SQLMAP_TXT_PATH |     paths.FUZZ_VECTORS           = "%s/fuzz_vectors.txt" % paths.SQLMAP_TXT_PATH | ||||||
|     paths.ERRORS_XML        = "%s/errors.xml" % paths.SQLMAP_XML_PATH |     paths.ERRORS_XML             = "%s/errors.xml" % paths.SQLMAP_XML_PATH | ||||||
|     paths.MSSQL_XML         = "%s/mssql.xml" % paths.SQLMAP_XML_PATH |     paths.QUERIES_XML            = "%s/queries.xml" % paths.SQLMAP_XML_PATH | ||||||
|     paths.QUERIES_XML       = "%s/queries.xml" % paths.SQLMAP_XML_PATH |     paths.GENERIC_XML            = "%s/generic.xml" % paths.SQLMAP_XML_BANNER_PATH | ||||||
|  |     paths.MSSQL_XML              = "%s/mssql.xml" % paths.SQLMAP_XML_BANNER_PATH | ||||||
|  |     paths.MYSQL_XML              = "%s/mysql.xml" % paths.SQLMAP_XML_BANNER_PATH | ||||||
|  |     paths.ORACLE_XML             = "%s/oracle.xml" % paths.SQLMAP_XML_BANNER_PATH | ||||||
|  |     paths.PGSQL_XML              = "%s/postgresql.xml" % paths.SQLMAP_XML_BANNER_PATH | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def weAreFrozen(): | def weAreFrozen(): | ||||||
|  |  | ||||||
|  | @ -31,25 +31,67 @@ from xml.sax.handler import ContentHandler | ||||||
| 
 | 
 | ||||||
| from lib.core.common import checkFile | from lib.core.common import checkFile | ||||||
| from lib.core.common import sanitizeStr | from lib.core.common import sanitizeStr | ||||||
|  | from lib.core.data import kb | ||||||
|  | from lib.core.data import paths | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class bannerHandler(ContentHandler): | class BannerHandler(ContentHandler): | ||||||
|     """ |     """ | ||||||
|     This class defines methods to parse and extract information from |     This class defines methods to parse and extract information from | ||||||
|     the given DBMS banner based upon the data in XML file |     the given DBMS banner based upon the data in XML file | ||||||
|     """ |     """ | ||||||
| 
 | 
 | ||||||
|  |     def __init__(self, banner): | ||||||
|  |         self.__banner   = sanitizeStr(banner) | ||||||
|  | 
 | ||||||
|  |         self.__regexp   = None | ||||||
|  |         self.__match    = None | ||||||
|  |         self.__position = None | ||||||
|  | 
 | ||||||
|  |         self.info       = {} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def startElement(self, name, attrs): | ||||||
|  |         if name == "regexp": | ||||||
|  |             self.__regexp = sanitizeStr(attrs.get("value")) | ||||||
|  |             self.__match  = re.search(self.__regexp, self.__banner, re.I | re.M) | ||||||
|  | 
 | ||||||
|  |         if name == "info" and self.__match: | ||||||
|  |             self.__position = sanitizeStr(attrs.get("version")) | ||||||
|  |             self.__sp       = sanitizeStr(attrs.get("sp")) | ||||||
|  | 
 | ||||||
|  |             self.info['type']     = sanitizeStr(attrs.get("type")) | ||||||
|  |             self.info['distrib']  = sanitizeStr(attrs.get("distrib")) | ||||||
|  |             self.info['release']  = sanitizeStr(attrs.get("release")) | ||||||
|  |             self.info['codename'] = sanitizeStr(attrs.get("codename")) | ||||||
|  | 
 | ||||||
|  |             if self.__position.isdigit(): | ||||||
|  |                 self.info['version'] = self.__match.group(int(self.__position)) | ||||||
|  | 
 | ||||||
|  |             if self.__sp.isdigit(): | ||||||
|  |                 self.info['sp'] = "Service Pack %s" % self.__match.group(int(self.__sp)) | ||||||
|  | 
 | ||||||
|  |             self.__match    = None | ||||||
|  |             self.__position = None | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class MSSQLBannerHandler(ContentHandler): | ||||||
|  |     """ | ||||||
|  |     This class defines methods to parse and extract information from the | ||||||
|  |     given Microsoft SQL Server banner based upon the data in XML file | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|     def __init__(self, banner): |     def __init__(self, banner): | ||||||
|         self.__banner        = sanitizeStr(banner) |         self.__banner        = sanitizeStr(banner) | ||||||
|         self.release         = None | 
 | ||||||
|         self.version         = None |  | ||||||
|         self.servicePack     = None |  | ||||||
|         self.__inVersion     = False |         self.__inVersion     = False | ||||||
|         self.__inServicePack = False |         self.__inServicePack = False | ||||||
|         self.__release       = None |         self.__release       = None | ||||||
|         self.__version       = "" |         self.__version       = "" | ||||||
|         self.__servicePack   = "" |         self.__servicePack   = "" | ||||||
| 
 | 
 | ||||||
|  |         self.info            = {} | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|     def startElement(self, name, attrs): |     def startElement(self, name, attrs): | ||||||
|         if name == "signatures": |         if name == "signatures": | ||||||
|  | @ -72,9 +114,9 @@ class bannerHandler(ContentHandler): | ||||||
|     def endElement(self, name): |     def endElement(self, name): | ||||||
|         if name == "signature": |         if name == "signature": | ||||||
|             if re.search(" %s[\.\ ]+" % self.__version, self.__banner): |             if re.search(" %s[\.\ ]+" % self.__version, self.__banner): | ||||||
|                 self.release     = self.__release |                 self.info['dbmsRelease']     = self.__release | ||||||
|                 self.version     = self.__version |                 self.info['dbmsVersion']     = self.__version | ||||||
|                 self.servicePack = self.__servicePack |                 self.info['dbmsServicePack'] = self.__servicePack | ||||||
| 
 | 
 | ||||||
|             self.__version     = "" |             self.__version     = "" | ||||||
|             self.__servicePack = "" |             self.__servicePack = "" | ||||||
|  | @ -89,16 +131,47 @@ class bannerHandler(ContentHandler): | ||||||
|             self.__servicePack = self.__servicePack.replace(" ", "") |             self.__servicePack = self.__servicePack.replace(" ", "") | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | def bannerParser(banner): | ||||||
| def bannerParser(banner, xmlfile): |  | ||||||
|     """ |     """ | ||||||
|     This function calls a class to extract information from the given |     This function calls a class to extract information from the given | ||||||
|     DBMS banner based upon the data in XML file |     DBMS banner based upon the data in XML file | ||||||
|     """ |     """ | ||||||
| 
 | 
 | ||||||
|     checkFile(xmlfile) |  | ||||||
|     banner = sanitizeStr(banner) |     banner = sanitizeStr(banner) | ||||||
|     handler = bannerHandler(banner) |     info   = {} | ||||||
|     parse(xmlfile, handler) |  | ||||||
| 
 | 
 | ||||||
|     return handler.release, handler.version, handler.servicePack |     if kb.dbms == "Microsoft SQL Server": | ||||||
|  |         xmlfile = paths.MSSQL_XML | ||||||
|  |     elif kb.dbms == "MySQL": | ||||||
|  |         xmlfile = paths.MYSQL_XML | ||||||
|  |     elif kb.dbms == "Oracle": | ||||||
|  |         xmlfile = paths.ORACLE_XML | ||||||
|  |     elif kb.dbms == "PostgreSQL": | ||||||
|  |         xmlfile = paths.PGSQL_XML | ||||||
|  | 
 | ||||||
|  |     checkFile(xmlfile) | ||||||
|  | 
 | ||||||
|  |     if kb.dbms == "Microsoft SQL Server": | ||||||
|  |         handler = MSSQLBannerHandler(banner) | ||||||
|  |         parse(xmlfile, handler) | ||||||
|  |         info = handler.info | ||||||
|  | 
 | ||||||
|  |         handler = BannerHandler(banner) | ||||||
|  |         parse(paths.GENERIC_XML, handler) | ||||||
|  | 
 | ||||||
|  |         for title, value in handler.info.items(): | ||||||
|  |             info[title] = value | ||||||
|  |     else: | ||||||
|  |         handler = BannerHandler(banner) | ||||||
|  |         parse(xmlfile, handler) | ||||||
|  |         info = handler.info | ||||||
|  | 
 | ||||||
|  |         if "type" not in info or info["type"] == "None": | ||||||
|  |             parse(paths.GENERIC_XML, handler) | ||||||
|  |             info["type"] = handler.info["type"] | ||||||
|  | 
 | ||||||
|  |         if "distrib" not in info or info["distrib"] == "None": | ||||||
|  |             parse(paths.GENERIC_XML, handler) | ||||||
|  |             info["distrib"] = handler.info["distrib"] | ||||||
|  | 
 | ||||||
|  |     return info | ||||||
|  |  | ||||||
|  | @ -129,7 +129,7 @@ def cmdLineParser(): | ||||||
| 
 | 
 | ||||||
|         fingerprint.add_option("-f", "--fingerprint", dest="extensiveFp", |         fingerprint.add_option("-f", "--fingerprint", dest="extensiveFp", | ||||||
|                                action="store_true", |                                action="store_true", | ||||||
|                                help="Perform an extensive database fingerprint") |                                help="Perform an extensive DBMS version fingerprint") | ||||||
| 
 | 
 | ||||||
|         # Enumeration options |         # Enumeration options | ||||||
|         enumeration = OptionGroup(parser, "Enumeration", "These options can " |         enumeration = OptionGroup(parser, "Enumeration", "These options can " | ||||||
|  |  | ||||||
|  | @ -28,14 +28,14 @@ import time | ||||||
| 
 | 
 | ||||||
| from lib.core.agent import agent | from lib.core.agent import agent | ||||||
| from lib.core.common import dataToStdout | from lib.core.common import dataToStdout | ||||||
| from lib.core.common import formatFingerprint | from lib.core.common import formatDBMSfp | ||||||
|  | from lib.core.common import formatOSfp | ||||||
| from lib.core.common import getHtmlErrorFp | from lib.core.common import getHtmlErrorFp | ||||||
| from lib.core.common import randomInt | from lib.core.common import randomInt | ||||||
| from lib.core.common import readInput | from lib.core.common import readInput | ||||||
| from lib.core.data import conf | from lib.core.data import conf | ||||||
| from lib.core.data import kb | from lib.core.data import kb | ||||||
| from lib.core.data import logger | from lib.core.data import logger | ||||||
| from lib.core.data import paths |  | ||||||
| from lib.core.data import queries | from lib.core.data import queries | ||||||
| from lib.core.exception import sqlmapNoneDataException | from lib.core.exception import sqlmapNoneDataException | ||||||
| from lib.core.exception import sqlmapSyntaxException | from lib.core.exception import sqlmapSyntaxException | ||||||
|  | @ -124,16 +124,21 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Takeover): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     def getFingerprint(self): |     def getFingerprint(self): | ||||||
|         actVer = formatFingerprint() |         actVer = formatDBMSfp() | ||||||
| 
 | 
 | ||||||
|         if not conf.extensiveFp: |         if not conf.extensiveFp: | ||||||
|             return actVer |             return actVer | ||||||
| 
 | 
 | ||||||
|         blank = " " * 16 |         blank      = " " * 16 | ||||||
|         value = "active fingerprint: %s" % actVer |         formatInfo = None | ||||||
|  |         value      = "active fingerprint: %s" % actVer | ||||||
| 
 | 
 | ||||||
|         if self.banner: |         if self.banner: | ||||||
|             release, version, servicepack = bannerParser(self.banner, paths.MSSQL_XML) |             info        = bannerParser(self.banner) | ||||||
|  |             release     = info["dbmsRelease"] | ||||||
|  |             version     = info["dbmsVersion"] | ||||||
|  |             servicepack = info["dbmsServicePack"] | ||||||
|  |             formatInfo  = formatOSfp(info) | ||||||
| 
 | 
 | ||||||
|             if release and version and servicepack: |             if release and version and servicepack: | ||||||
|                 banVer  = "Microsoft SQL Server %s " % release |                 banVer  = "Microsoft SQL Server %s " % release | ||||||
|  | @ -148,6 +153,9 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Takeover): | ||||||
|         if htmlParsed: |         if htmlParsed: | ||||||
|             value += "\n%shtml error message fingerprint: %s" % (blank, htmlParsed) |             value += "\n%shtml error message fingerprint: %s" % (blank, htmlParsed) | ||||||
| 
 | 
 | ||||||
|  |         if formatInfo: | ||||||
|  |             value += "\n%s" % formatInfo | ||||||
|  | 
 | ||||||
|         return value |         return value | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -28,7 +28,8 @@ import re | ||||||
| 
 | 
 | ||||||
| from lib.core.agent import agent | from lib.core.agent import agent | ||||||
| from lib.core.common import fileToStr | from lib.core.common import fileToStr | ||||||
| from lib.core.common import formatFingerprint | from lib.core.common import formatDBMSfp | ||||||
|  | from lib.core.common import formatOSfp | ||||||
| from lib.core.common import getDirectories | from lib.core.common import getDirectories | ||||||
| from lib.core.common import getHtmlErrorFp | from lib.core.common import getHtmlErrorFp | ||||||
| from lib.core.common import randomInt | from lib.core.common import randomInt | ||||||
|  | @ -43,6 +44,7 @@ from lib.core.settings import MYSQL_ALIASES | ||||||
| from lib.core.settings import MYSQL_SYSTEM_DBS | from lib.core.settings import MYSQL_SYSTEM_DBS | ||||||
| from lib.core.shell import autoCompletion | from lib.core.shell import autoCompletion | ||||||
| from lib.core.unescaper import unescaper | from lib.core.unescaper import unescaper | ||||||
|  | from lib.parse.banner import bannerParser | ||||||
| from lib.request import inject | from lib.request import inject | ||||||
| from lib.request.connect import Connect as Request | from lib.request.connect import Connect as Request | ||||||
| #from lib.utils.fuzzer import passiveFuzzing | #from lib.utils.fuzzer import passiveFuzzing | ||||||
|  | @ -180,26 +182,28 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     def getFingerprint(self): |     def getFingerprint(self): | ||||||
|         actVer = formatFingerprint() |         actVer = formatDBMSfp() | ||||||
| 
 | 
 | ||||||
|         if not conf.extensiveFp: |         if not conf.extensiveFp: | ||||||
|             return actVer |             return actVer | ||||||
| 
 | 
 | ||||||
|         blank = " " * 16 |         comVer     = self.__commentCheck() | ||||||
|         value = "active fingerprint: %s" % actVer |         blank      = " " * 16 | ||||||
|         comVer = self.__commentCheck() |         formatInfo = None | ||||||
|  |         value      = "active fingerprint: %s" % actVer | ||||||
| 
 | 
 | ||||||
|         if comVer: |         if comVer: | ||||||
|             comVer = formatFingerprint([comVer]) |             comVer = formatDBMSfp([comVer]) | ||||||
|             value += "\n%scomment injection fingerprint: %s" % (blank, comVer) |             value += "\n%scomment injection fingerprint: %s" % (blank, comVer) | ||||||
| 
 | 
 | ||||||
|         if self.banner: |         if self.banner: | ||||||
|             banVer = re.search("^([\d\.]+)", self.banner) |             info       = bannerParser(self.banner) | ||||||
|             banVer = banVer.groups()[0] |             formatInfo = formatOSfp(info) | ||||||
|  | 
 | ||||||
|  |             banVer = info['version'] | ||||||
|             if re.search("-log$", self.banner): |             if re.search("-log$", self.banner): | ||||||
|                 banVer += ", logging enabled" |                 banVer += ", logging enabled" | ||||||
|             banVer = formatFingerprint([banVer]) |             banVer = formatDBMSfp([banVer]) | ||||||
| 
 |  | ||||||
|             value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer) |             value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer) | ||||||
| 
 | 
 | ||||||
|         #passiveFuzzing() |         #passiveFuzzing() | ||||||
|  | @ -208,6 +212,9 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover): | ||||||
|         if htmlParsed: |         if htmlParsed: | ||||||
|             value += "\n%shtml error message fingerprint: %s" % (blank, htmlParsed) |             value += "\n%shtml error message fingerprint: %s" % (blank, htmlParsed) | ||||||
| 
 | 
 | ||||||
|  |         if formatInfo: | ||||||
|  |             value += "\n%s" % formatInfo | ||||||
|  | 
 | ||||||
|         return value |         return value | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -26,7 +26,8 @@ Franklin St, Fifth Floor, Boston, MA  02110-1301  USA | ||||||
| 
 | 
 | ||||||
| import re | import re | ||||||
| 
 | 
 | ||||||
| from lib.core.common import formatFingerprint | from lib.core.common import formatDBMSfp | ||||||
|  | from lib.core.common import formatOSfp | ||||||
| from lib.core.common import getHtmlErrorFp | from lib.core.common import getHtmlErrorFp | ||||||
| from lib.core.data import conf | from lib.core.data import conf | ||||||
| from lib.core.data import kb | from lib.core.data import kb | ||||||
|  | @ -36,6 +37,7 @@ from lib.core.session import setDbms | ||||||
| from lib.core.settings import ORACLE_ALIASES | from lib.core.settings import ORACLE_ALIASES | ||||||
| from lib.core.settings import ORACLE_SYSTEM_DBS | from lib.core.settings import ORACLE_SYSTEM_DBS | ||||||
| from lib.core.unescaper import unescaper | from lib.core.unescaper import unescaper | ||||||
|  | from lib.parse.banner import bannerParser | ||||||
| from lib.request import inject | from lib.request import inject | ||||||
| #from lib.utils.fuzzer import passiveFuzzing | #from lib.utils.fuzzer import passiveFuzzing | ||||||
| 
 | 
 | ||||||
|  | @ -119,19 +121,19 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Takeover): | ||||||
|         if not conf.extensiveFp: |         if not conf.extensiveFp: | ||||||
|             return "Oracle" |             return "Oracle" | ||||||
| 
 | 
 | ||||||
|         actVer = formatFingerprint() |         actVer = formatDBMSfp() | ||||||
| 
 | 
 | ||||||
|         blank = " " * 16 |         blank      = " " * 16 | ||||||
|         value = "active fingerprint: %s" % actVer |         formatInfo = None | ||||||
|  |         value      = "active fingerprint: %s" % actVer | ||||||
| 
 | 
 | ||||||
|         if self.banner: |         if self.banner: | ||||||
|             banVer = re.search("^Oracle .*Release ([\d\.]+) ", self.banner) |             info       = bannerParser(self.banner) | ||||||
|  |             formatInfo = formatOSfp(info) | ||||||
| 
 | 
 | ||||||
|             if banVer: |             banVer = info['version'] | ||||||
|                 banVer = banVer.groups()[0] |             banVer = formatDBMSfp([banVer]) | ||||||
|                 banVer = formatFingerprint([banVer]) |             value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer) | ||||||
| 
 |  | ||||||
|                 value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer) |  | ||||||
| 
 | 
 | ||||||
|         #passiveFuzzing() |         #passiveFuzzing() | ||||||
|         htmlParsed = getHtmlErrorFp() |         htmlParsed = getHtmlErrorFp() | ||||||
|  | @ -139,6 +141,9 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Takeover): | ||||||
|         if htmlParsed: |         if htmlParsed: | ||||||
|             value += "\n%shtml error message fingerprint: %s" % (blank, htmlParsed) |             value += "\n%shtml error message fingerprint: %s" % (blank, htmlParsed) | ||||||
| 
 | 
 | ||||||
|  |         if formatInfo: | ||||||
|  |             value += "\n%s" % formatInfo | ||||||
|  | 
 | ||||||
|         return value |         return value | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -159,7 +164,7 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Takeover): | ||||||
|             logMsg = "confirming Oracle" |             logMsg = "confirming Oracle" | ||||||
|             logger.info(logMsg) |             logger.info(logMsg) | ||||||
| 
 | 
 | ||||||
|             query = "SELECT VERSION FROM SYS.PRODUCT_COMPONENT_VERSION WHERE ROWNUM=1" |             query = "SELECT SUBSTR((VERSION), 1, 2) FROM SYS.PRODUCT_COMPONENT_VERSION WHERE ROWNUM=1" | ||||||
|             version = inject.getValue(query) |             version = inject.getValue(query) | ||||||
| 
 | 
 | ||||||
|             if not version: |             if not version: | ||||||
|  | @ -173,13 +178,13 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Takeover): | ||||||
|             if not conf.extensiveFp: |             if not conf.extensiveFp: | ||||||
|                 return True |                 return True | ||||||
| 
 | 
 | ||||||
|             if re.search("^11\.", version): |             if re.search("^11", version): | ||||||
|                 kb.dbmsVersion = ["11i"] |                 kb.dbmsVersion = ["11i"] | ||||||
|             elif re.search("^10\.", version): |             elif re.search("^10", version): | ||||||
|                 kb.dbmsVersion = ["10g"] |                 kb.dbmsVersion = ["10g"] | ||||||
|             elif re.search("^9\.", version): |             elif re.search("^9", version): | ||||||
|                 kb.dbmsVersion = ["9i"] |                 kb.dbmsVersion = ["9i"] | ||||||
|             elif re.search("^8\.", version): |             elif re.search("^8", version): | ||||||
|                 kb.dbmsVersion = ["8i"] |                 kb.dbmsVersion = ["8i"] | ||||||
| 
 | 
 | ||||||
|             if conf.getBanner: |             if conf.getBanner: | ||||||
|  |  | ||||||
|  | @ -26,7 +26,8 @@ Franklin St, Fifth Floor, Boston, MA  02110-1301  USA | ||||||
| 
 | 
 | ||||||
| import re | import re | ||||||
| 
 | 
 | ||||||
| from lib.core.common import formatFingerprint | from lib.core.common import formatDBMSfp | ||||||
|  | from lib.core.common import formatOSfp | ||||||
| from lib.core.common import getHtmlErrorFp | from lib.core.common import getHtmlErrorFp | ||||||
| from lib.core.common import randomInt | from lib.core.common import randomInt | ||||||
| from lib.core.data import conf | from lib.core.data import conf | ||||||
|  | @ -37,6 +38,7 @@ from lib.core.session import setDbms | ||||||
| from lib.core.settings import PGSQL_ALIASES | from lib.core.settings import PGSQL_ALIASES | ||||||
| from lib.core.settings import PGSQL_SYSTEM_DBS | from lib.core.settings import PGSQL_SYSTEM_DBS | ||||||
| from lib.core.unescaper import unescaper | from lib.core.unescaper import unescaper | ||||||
|  | from lib.parse.banner import bannerParser | ||||||
| from lib.request import inject | from lib.request import inject | ||||||
| #from lib.utils.fuzzer import passiveFuzzing | #from lib.utils.fuzzer import passiveFuzzing | ||||||
| 
 | 
 | ||||||
|  | @ -119,16 +121,18 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Takeover): | ||||||
|         if not conf.extensiveFp: |         if not conf.extensiveFp: | ||||||
|             return "PostgreSQL" |             return "PostgreSQL" | ||||||
| 
 | 
 | ||||||
|         actVer = formatFingerprint() |         actVer = formatDBMSfp() | ||||||
| 
 | 
 | ||||||
|         blank = " " * 16 |         blank      = " " * 16 | ||||||
|         value = "active fingerprint: %s" % actVer |         formatInfo = None | ||||||
|  |         value      = "active fingerprint: %s" % actVer | ||||||
| 
 | 
 | ||||||
|         if self.banner: |         if self.banner: | ||||||
|             banVer = re.search("^PostgreSQL ([\d\.]+)", self.banner) |             info       = bannerParser(self.banner) | ||||||
|             banVer = banVer.groups()[0] |             formatInfo = formatOSfp(info) | ||||||
|             banVer = formatFingerprint([banVer]) |  | ||||||
| 
 | 
 | ||||||
|  |             banVer = info['version'] | ||||||
|  |             banVer = formatDBMSfp([banVer]) | ||||||
|             value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer) |             value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer) | ||||||
| 
 | 
 | ||||||
|         #passiveFuzzing() |         #passiveFuzzing() | ||||||
|  | @ -137,6 +141,9 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Takeover): | ||||||
|         if htmlParsed: |         if htmlParsed: | ||||||
|             value += "\n%shtml error message fingerprint: %s" % (blank, htmlParsed) |             value += "\n%shtml error message fingerprint: %s" % (blank, htmlParsed) | ||||||
| 
 | 
 | ||||||
|  |         if formatInfo: | ||||||
|  |             value += "\n%s" % formatInfo | ||||||
|  | 
 | ||||||
|         return value |         return value | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										86
									
								
								xml/banner/generic.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								xml/banner/generic.xml
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,86 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | 
 | ||||||
|  | <root> | ||||||
|  |     <!-- Windows --> | ||||||
|  |     <regexp value="(Windows|Win32)"> | ||||||
|  |         <info type="Windows"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="Microsoft.*7\.0.*Service Pack (\d)"> | ||||||
|  |         <info type="Windows" distrib="Vista" sp="1"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="Microsoft.*6\.0.*Service Pack (\d)"> | ||||||
|  |         <info type="Windows" distrib="2003" sp="1"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="Microsoft.*5\.1.*Service Pack (\d)"> | ||||||
|  |         <info type="Windows" distrib="XP" sp="1"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="Microsoft.*5\.0.*Service Pack (\d)"> | ||||||
|  |         <info type="Windows" distrib="2000" sp="1"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <!-- Linux --> | ||||||
|  |     <regexp value="Linux"> | ||||||
|  |         <info type="Linux"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="Cobalt"> | ||||||
|  |         <info type="Linux" distrib="Cobalt"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="Conectiva"> | ||||||
|  |         <info type="Linux" distrib="Conectiva"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="Debian"> | ||||||
|  |         <info type="Linux" distrib="Debian or Ubuntu"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="Fedora"> | ||||||
|  |         <info type="Linux" distrib="Fedora"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="Gentoo"> | ||||||
|  |         <info type="Linux" distrib="Gentoo"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="Knoppix"> | ||||||
|  |         <info type="Linux" distrib="Knoppix"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="(Mandrake|Mandriva)"> | ||||||
|  |         <info type="Linux" distrib="Mandrake"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="Red[\-\_\ ]*Hat"> | ||||||
|  |         <info type="Linux" distrib="RedHat"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="SuSE"> | ||||||
|  |         <info type="Linux" distrib="SuSE"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="Ubuntu"> | ||||||
|  |         <info type="Linux" distrib="Ubuntu"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <!-- Unices --> | ||||||
|  |     <regexp value="FreeBSD"> | ||||||
|  |         <info type="FreeBSD"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="NetBSD"> | ||||||
|  |         <info type="NetBSD"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="OpenBSD"> | ||||||
|  |         <info type="OpenBSD"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="Darwin"> | ||||||
|  |         <info type="Mac OSX"/> | ||||||
|  |     </regexp> | ||||||
|  | </root> | ||||||
							
								
								
									
										43
									
								
								xml/banner/mysql.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								xml/banner/mysql.xml
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | 
 | ||||||
|  | <root> | ||||||
|  |     <!-- Generic --> | ||||||
|  |     <regexp value="^([\d\.\-]+)[\-\_\ ].*"> | ||||||
|  |         <info version="1"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <!-- Windows --> | ||||||
|  |     <regexp value="^([\d\.\-]+)[\-\_\ ].*nt$"> | ||||||
|  |         <info version="1" type="Windows"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <!-- Debian --> | ||||||
|  |     <regexp value="^([\d\.]+)[\-\_]Debian[\-\_][\d\.]+potato"> | ||||||
|  |         <info version="1" type="Linux" distrib="Debian" release="2.1" codename="Potato"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="^([\d\.]+)[\-\_]Debian[\-\_][\d\.]+woody"> | ||||||
|  |         <info version="1" type="Linux" distrib="Debian" release="3.0" codename="Woody"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="^([\d\.]+)[\-\_]Debian[\-\_][\d\.]+sarge"> | ||||||
|  |         <info version="1" type="Linux" distrib="Debian" release="3.1" codename="Sarge"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="^([\d\.]+)[\-\_]Debian[\-\_][\d\.]+etch"> | ||||||
|  |         <info version="1" type="Linux" distrib="Debian" release="4.0" codename="Etch"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="^([\d\.]+)[\-\_]Debian[\-\_][\d\.]+(sid|unstable)"> | ||||||
|  |         <info version="1" type="Linux" distrib="Debian" codename="Unstable"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <regexp value="^([\d\.]+)[\-\_]Debian[\-\_][\d\.]+testing"> | ||||||
|  |         <info version="1" type="Linux" distrib="Debian" codename="Testing"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <!-- Ubuntu --> | ||||||
|  |     <regexp value="(5\.0\.67)-0ubuntu6"> | ||||||
|  |         <info version="1" type="Linux" distrib="Ubuntu" release="8.10" codename="Intrepid"/> | ||||||
|  |     </regexp> | ||||||
|  | </root> | ||||||
							
								
								
									
										8
									
								
								xml/banner/oracle.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								xml/banner/oracle.xml
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | 
 | ||||||
|  | <root> | ||||||
|  |     <!-- Generic --> | ||||||
|  |     <regexp value="^Oracle\s+.*Release\s+([\d\.]+)\s+"> | ||||||
|  |         <info version="1"/> | ||||||
|  |     </regexp> | ||||||
|  | </root> | ||||||
							
								
								
									
										13
									
								
								xml/banner/postgresql.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								xml/banner/postgresql.xml
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | 
 | ||||||
|  | <root> | ||||||
|  |     <!-- Generic --> | ||||||
|  |     <regexp value="PostgreSQL\s+([\w\.]+)"> | ||||||
|  |         <info version="1"/> | ||||||
|  |     </regexp> | ||||||
|  | 
 | ||||||
|  |     <!-- Ubuntu --> | ||||||
|  |     <regexp value="PostgreSQL\s+(8\.2\.7)\s+on\s+.*?\s+\(Ubuntu 4\.2\.3-2ubuntu4\)"> | ||||||
|  |         <info version="1" type="Linux" distrib="Ubuntu" release="8.10" codename="Intrepid"/> | ||||||
|  |     </regexp> | ||||||
|  | </root> | ||||||
|  | @ -75,6 +75,10 @@ | ||||||
|         <timedelay query="BEGIN DBMS_LOCK.SLEEP(%d); END" query2="EXEC DBMS_LOCK.SLEEP(%d.00)" query3="EXEC USER_LOCK.SLEEP(%d00)"/> |         <timedelay query="BEGIN DBMS_LOCK.SLEEP(%d); END" query2="EXEC DBMS_LOCK.SLEEP(%d.00)" query3="EXEC USER_LOCK.SLEEP(%d00)"/> | ||||||
|         <substring query="SUBSTR((%s), %d, %d)"/> |         <substring query="SUBSTR((%s), %d, %d)"/> | ||||||
|         <inference query="AND ASCII(SUBSTR((%s), %d, 1)) > %d"/> |         <inference query="AND ASCII(SUBSTR((%s), %d, 1)) > %d"/> | ||||||
|  |         <!-- | ||||||
|  |              TODO: the following query does not work with inband SQL injection: | ||||||
|  |              SELECT banner FROM (SELECT banner, ROWNUM AS limit FROM v$version) WHERE limit=4 | ||||||
|  |         --> | ||||||
|         <banner query="SELECT banner FROM v$version WHERE ROWNUM=1"/> |         <banner query="SELECT banner FROM v$version WHERE ROWNUM=1"/> | ||||||
|         <current_user query="SELECT SYS.LOGIN_USER FROM DUAL"/> |         <current_user query="SELECT SYS.LOGIN_USER FROM DUAL"/> | ||||||
|         <current_db query="SELECT SYS.DATABASE_NAME FROM DUAL"/> |         <current_db query="SELECT SYS.DATABASE_NAME FROM DUAL"/> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user