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:
Bernardo Damele 2008-11-15 23:41:31 +00:00
parent 84cbc60659
commit fa0507ab39
15 changed files with 372 additions and 69 deletions

View File

@ -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

View File

@ -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

View File

@ -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():

View File

@ -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

View File

@ -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 "

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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
View 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
View 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
View 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
View 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>

View File

@ -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"/>