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
* Major bug fix to correctly handle httplib.BadStatusLine exception;
* Minor enhancement to support stacked queries which will be used
sometimes by takeover functionality and time based blind SQL injection
technique;
* Minor enhancement to be able to specify the number of seconds to wait
between each HTTP request;
* 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
database on MySQL and MSSQL, the 'public' scheme on PostgreSQL and the
'USERS' TABLESPACE_NAME on Oracle;
entries, also when the database name is not provided, by using the
current database on MySQL and Microsoft SQL Server, the 'public'
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
to official Debian project repository;
* 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:
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)
count += 1
continue

View File

@ -112,7 +112,7 @@ def paramToDict(place, parameters=None):
return testableParameters
def formatFingerprint(versions=None):
def formatDBMSfp(versions=None):
"""
This function format the back-end DBMS fingerprint value and return its
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]))
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():
"""
This function parses the knowledge base htmlFp list and return its
@ -442,20 +483,25 @@ def cleanQuery(query):
def setPaths():
# sqlmap paths
paths.SQLMAP_SHELL_PATH = "%s/shell" % 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_OUTPUT_PATH = "%s/output" % paths.SQLMAP_ROOT_PATH
paths.SQLMAP_DUMP_PATH = paths.SQLMAP_OUTPUT_PATH + "/%s/dump"
paths.SQLMAP_FILES_PATH = paths.SQLMAP_OUTPUT_PATH + "/%s/files"
paths.SQLMAP_SHELL_PATH = "%s/shell" % 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_BANNER_PATH = "%s/banner" % paths.SQLMAP_XML_PATH
paths.SQLMAP_OUTPUT_PATH = "%s/output" % paths.SQLMAP_ROOT_PATH
paths.SQLMAP_DUMP_PATH = paths.SQLMAP_OUTPUT_PATH + "/%s/dump"
paths.SQLMAP_FILES_PATH = paths.SQLMAP_OUTPUT_PATH + "/%s/files"
# sqlmap files
paths.SQLMAP_HISTORY = "%s/.sqlmap_history" % paths.SQLMAP_ROOT_PATH
paths.SQLMAP_CONFIG = "%s/sqlmap-%s.conf" % (paths.SQLMAP_ROOT_PATH, randomStr())
paths.FUZZ_VECTORS = "%s/fuzz_vectors.txt" % paths.SQLMAP_TXT_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.SQLMAP_HISTORY = "%s/.sqlmap_history" % paths.SQLMAP_ROOT_PATH
paths.SQLMAP_CONFIG = "%s/sqlmap-%s.conf" % (paths.SQLMAP_ROOT_PATH, randomStr())
paths.FUZZ_VECTORS = "%s/fuzz_vectors.txt" % paths.SQLMAP_TXT_PATH
paths.ERRORS_XML = "%s/errors.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():

View File

@ -31,25 +31,67 @@ from xml.sax.handler import ContentHandler
from lib.core.common import checkFile
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
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):
self.__banner = sanitizeStr(banner)
self.release = None
self.version = None
self.servicePack = None
self.__inVersion = False
self.__inServicePack = False
self.__release = None
self.__version = ""
self.__servicePack = ""
self.info = {}
def startElement(self, name, attrs):
if name == "signatures":
@ -72,9 +114,9 @@ class bannerHandler(ContentHandler):
def endElement(self, name):
if name == "signature":
if re.search(" %s[\.\ ]+" % self.__version, self.__banner):
self.release = self.__release
self.version = self.__version
self.servicePack = self.__servicePack
self.info['dbmsRelease'] = self.__release
self.info['dbmsVersion'] = self.__version
self.info['dbmsServicePack'] = self.__servicePack
self.__version = ""
self.__servicePack = ""
@ -89,16 +131,47 @@ class bannerHandler(ContentHandler):
self.__servicePack = self.__servicePack.replace(" ", "")
def bannerParser(banner, xmlfile):
def bannerParser(banner):
"""
This function calls a class to extract information from the given
DBMS banner based upon the data in XML file
"""
checkFile(xmlfile)
banner = sanitizeStr(banner)
handler = bannerHandler(banner)
parse(xmlfile, handler)
info = {}
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",
action="store_true",
help="Perform an extensive database fingerprint")
help="Perform an extensive DBMS version fingerprint")
# Enumeration options
enumeration = OptionGroup(parser, "Enumeration", "These options can "

View File

@ -28,14 +28,14 @@ import time
from lib.core.agent import agent
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 randomInt
from lib.core.common import readInput
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
from lib.core.data import paths
from lib.core.data import queries
from lib.core.exception import sqlmapNoneDataException
from lib.core.exception import sqlmapSyntaxException
@ -124,16 +124,21 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Takeover):
def getFingerprint(self):
actVer = formatFingerprint()
actVer = formatDBMSfp()
if not conf.extensiveFp:
return actVer
blank = " " * 16
value = "active fingerprint: %s" % actVer
blank = " " * 16
formatInfo = None
value = "active fingerprint: %s" % actVer
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:
banVer = "Microsoft SQL Server %s " % release
@ -148,6 +153,9 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Takeover):
if htmlParsed:
value += "\n%shtml error message fingerprint: %s" % (blank, htmlParsed)
if formatInfo:
value += "\n%s" % formatInfo
return value

View File

@ -28,7 +28,8 @@ import re
from lib.core.agent import agent
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 getHtmlErrorFp
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.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.utils.fuzzer import passiveFuzzing
@ -180,26 +182,28 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
def getFingerprint(self):
actVer = formatFingerprint()
actVer = formatDBMSfp()
if not conf.extensiveFp:
return actVer
blank = " " * 16
value = "active fingerprint: %s" % actVer
comVer = self.__commentCheck()
comVer = self.__commentCheck()
blank = " " * 16
formatInfo = None
value = "active fingerprint: %s" % actVer
if comVer:
comVer = formatFingerprint([comVer])
comVer = formatDBMSfp([comVer])
value += "\n%scomment injection fingerprint: %s" % (blank, comVer)
if self.banner:
banVer = re.search("^([\d\.]+)", self.banner)
banVer = banVer.groups()[0]
info = bannerParser(self.banner)
formatInfo = formatOSfp(info)
banVer = info['version']
if re.search("-log$", self.banner):
banVer += ", logging enabled"
banVer = formatFingerprint([banVer])
banVer = formatDBMSfp([banVer])
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
#passiveFuzzing()
@ -208,6 +212,9 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
if htmlParsed:
value += "\n%shtml error message fingerprint: %s" % (blank, htmlParsed)
if formatInfo:
value += "\n%s" % formatInfo
return value

View File

@ -26,7 +26,8 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
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.data import conf
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_SYSTEM_DBS
from lib.core.unescaper import unescaper
from lib.parse.banner import bannerParser
from lib.request import inject
#from lib.utils.fuzzer import passiveFuzzing
@ -119,19 +121,19 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Takeover):
if not conf.extensiveFp:
return "Oracle"
actVer = formatFingerprint()
actVer = formatDBMSfp()
blank = " " * 16
value = "active fingerprint: %s" % actVer
blank = " " * 16
formatInfo = None
value = "active fingerprint: %s" % actVer
if self.banner:
banVer = re.search("^Oracle .*Release ([\d\.]+) ", self.banner)
info = bannerParser(self.banner)
formatInfo = formatOSfp(info)
if banVer:
banVer = banVer.groups()[0]
banVer = formatFingerprint([banVer])
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
banVer = info['version']
banVer = formatDBMSfp([banVer])
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
#passiveFuzzing()
htmlParsed = getHtmlErrorFp()
@ -139,6 +141,9 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Takeover):
if htmlParsed:
value += "\n%shtml error message fingerprint: %s" % (blank, htmlParsed)
if formatInfo:
value += "\n%s" % formatInfo
return value
@ -159,7 +164,7 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Takeover):
logMsg = "confirming Oracle"
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)
if not version:
@ -173,13 +178,13 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Takeover):
if not conf.extensiveFp:
return True
if re.search("^11\.", version):
if re.search("^11", version):
kb.dbmsVersion = ["11i"]
elif re.search("^10\.", version):
elif re.search("^10", version):
kb.dbmsVersion = ["10g"]
elif re.search("^9\.", version):
elif re.search("^9", version):
kb.dbmsVersion = ["9i"]
elif re.search("^8\.", version):
elif re.search("^8", version):
kb.dbmsVersion = ["8i"]
if conf.getBanner:

View File

@ -26,7 +26,8 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
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 randomInt
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_SYSTEM_DBS
from lib.core.unescaper import unescaper
from lib.parse.banner import bannerParser
from lib.request import inject
#from lib.utils.fuzzer import passiveFuzzing
@ -119,16 +121,18 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
if not conf.extensiveFp:
return "PostgreSQL"
actVer = formatFingerprint()
actVer = formatDBMSfp()
blank = " " * 16
value = "active fingerprint: %s" % actVer
blank = " " * 16
formatInfo = None
value = "active fingerprint: %s" % actVer
if self.banner:
banVer = re.search("^PostgreSQL ([\d\.]+)", self.banner)
banVer = banVer.groups()[0]
banVer = formatFingerprint([banVer])
info = bannerParser(self.banner)
formatInfo = formatOSfp(info)
banVer = info['version']
banVer = formatDBMSfp([banVer])
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
#passiveFuzzing()
@ -137,6 +141,9 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
if htmlParsed:
value += "\n%shtml error message fingerprint: %s" % (blank, htmlParsed)
if formatInfo:
value += "\n%s" % formatInfo
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)"/>
<substring query="SUBSTR((%s), %d, %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"/>
<current_user query="SELECT SYS.LOGIN_USER FROM DUAL"/>
<current_db query="SELECT SYS.DATABASE_NAME FROM DUAL"/>