Initial support for SQLite (90% approx).

Initial support for Firebird (30% approx).
Initial support for Access (10% approx).
Shared libraries code/installation scripts ported to 64bit, directory structure adapted.
Minor code adjustments.
This commit is contained in:
Bernardo Damele
2010-03-18 17:20:54 +00:00
parent f1fde2e443
commit 0d559d14df
61 changed files with 3769 additions and 670 deletions

View File

@@ -29,11 +29,17 @@ from lib.core.settings import MSSQL_ALIASES
from lib.core.settings import MYSQL_ALIASES
from lib.core.settings import ORACLE_ALIASES
from lib.core.settings import PGSQL_ALIASES
from lib.core.settings import SQLITE_ALIASES
from lib.core.settings import ACCESS_ALIASES
from lib.core.settings import FIREBIRD_ALIASES
from plugins.dbms.mssqlserver import MSSQLServerMap
from plugins.dbms.mysql import MySQLMap
from plugins.dbms.oracle import OracleMap
from plugins.dbms.postgresql import PostgreSQLMap
from plugins.dbms.sqlite import SQLiteMap
from plugins.dbms.access import AccessMap
from plugins.dbms.firebird import FirebirdMap
def setHandler():
"""
@@ -42,12 +48,15 @@ def setHandler():
"""
count = 0
dbmsNames = ( "MySQL", "Oracle", "PostgreSQL", "Microsoft SQL Server" )
dbmsNames = ( "MySQL", "Oracle", "PostgreSQL", "Microsoft SQL Server", "SQLite", "Microsoft Access", "Firebird" )
dbmsMap = (
( MYSQL_ALIASES, MySQLMap ),
( ORACLE_ALIASES, OracleMap ),
( PGSQL_ALIASES, PostgreSQLMap ),
( MSSQL_ALIASES, MSSQLServerMap ),
( SQLITE_ALIASES, SQLiteMap ),
( ACCESS_ALIASES, AccessMap ),
( FIREBIRD_ALIASES, FirebirdMap ),
)
for dbmsAliases, dbmsEntry in dbmsMap:

View File

@@ -182,6 +182,11 @@ class Agent:
@rtype: C{str}
"""
# SQLite version 2 does not support neither CAST() nor IFNULL(),
# introduced only in SQLite version 3
if kb.dbms == "SQLite":
return field
if field.startswith("(CASE"):
nulledCastedField = field
else:
@@ -252,12 +257,12 @@ class Agent:
@return: query fields (columns) and more details
@rtype: C{str}
"""
prefixRegex = "(?:\s+(?:FIRST|SKIP)\s+\d+)*"
fieldsSelectTop = re.search("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", query, re.I)
fieldsSelectDistinct = re.search("\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", query, re.I)
fieldsSelectCase = re.search("\ASELECT\s+(\(CASE WHEN\s+.+\s+END\))", query, re.I)
fieldsSelectFrom = re.search("\ASELECT\s+(.+?)\s+FROM\s+", query, re.I)
fieldsSelect = re.search("\ASELECT\s+(.*)", query, re.I)
fieldsSelectDistinct = re.search("\ASELECT%s\s+DISTINCT\((.+?)\)\s+FROM" % prefixRegex, query, re.I)
fieldsSelectCase = re.search("\ASELECT%s\s+(\(CASE WHEN\s+.+\s+END\))" % prefixRegex, query, re.I)
fieldsSelectFrom = re.search("\ASELECT%s\s+(.+?)\s+FROM\s+" % prefixRegex, query, re.I)
fieldsSelect = re.search("\ASELECT%s\s+(.*)" % prefixRegex, query, re.I)
fieldsNoSelect = query
if fieldsSelectTop:
@@ -284,7 +289,7 @@ class Agent:
if kb.dbms == "MySQL":
concatenatedQuery = "CONCAT(%s,%s)" % (query1, query2)
elif kb.dbms in ( "PostgreSQL", "Oracle" ):
elif kb.dbms in ( "PostgreSQL", "Oracle", "SQLite" ):
concatenatedQuery = "%s||%s" % (query1, query2)
elif kb.dbms == "Microsoft SQL Server":
@@ -342,7 +347,7 @@ class Agent:
elif fieldsNoSelect:
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (temp.start, concatenatedQuery, temp.stop)
elif kb.dbms in ( "PostgreSQL", "Oracle" ):
elif kb.dbms in ( "PostgreSQL", "Oracle", "SQLite" ):
if fieldsSelectCase:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % temp.start, 1)
concatenatedQuery += "||'%s'" % temp.stop
@@ -483,9 +488,13 @@ class Agent:
untilFrom = limitedQuery[:fromIndex]
fromFrom = limitedQuery[fromIndex+1:]
if kb.dbms in ( "MySQL", "PostgreSQL" ):
if kb.dbms in ( "MySQL", "PostgreSQL", "SQLite" ):
limitStr = queries[kb.dbms].limit % (num, 1)
limitedQuery += " %s" % limitStr
elif kb.dbms == "Firebird":
limitStr = queries[kb.dbms].limit % (num+1, num+1)
limitedQuery += " %s" % limitStr
elif kb.dbms == "Oracle":
if " ORDER BY " in limitedQuery and "(SELECT " in limitedQuery:

View File

@@ -127,7 +127,7 @@ def formatDBMSfp(versions=None):
@rtype: C{str}
"""
if not versions or versions == [None]:
if ( not versions or versions == [None] ) and kb.dbmsVersion[0] != "Unknown":
versions = kb.dbmsVersion
if isinstance(versions, str):
@@ -734,14 +734,19 @@ def getDelayQuery(andCond=False):
if (kb.dbms == "MySQL" and banVer >= "5.0.12") or (kb.dbms == "PostgreSQL" and banVer >= "8.2"):
query = queries[kb.dbms].timedelay % conf.timeSec
if kb.dbms == "MySQL" and andCond:
query = query.replace("SELECT ", "")
else:
query = queries[kb.dbms].timedelay2 % conf.timeSec
elif kb.dbms is "Firebird":
query = queries[kb.dbms].timedelay
else:
query = queries[kb.dbms].timedelay % conf.timeSec
if andCond:
if kb.dbms in ( "MySQL", "SQLite" ):
query = query.replace("SELECT ", "")
elif kb.dbms is "Firebird":
query = "(%s)>0" % query
return query
def getLocalIP():

View File

@@ -52,18 +52,30 @@ PYVERSION = sys.version.split()[0]
# Url to update Microsoft SQL Server XML versions file from
MSSQL_VERSIONS_URL = "http://www.sqlsecurity.com/FAQs/SQLServerVersionDatabase/tabid/63/Default.aspx"
# Database managemen system specific variables
# Database management system specific variables
MSSQL_SYSTEM_DBS = ( "Northwind", "model", "msdb", "pubs", "tempdb" )
MYSQL_SYSTEM_DBS = ( "information_schema", "mysql" ) # Before MySQL 5.0 only "mysql"
PGSQL_SYSTEM_DBS = ( "information_schema", "pg_catalog", "pg_toast" )
ORACLE_SYSTEM_DBS = ( "SYSTEM", "SYSAUX" ) # These are TABLESPACE_NAME
SQLITE_SYSTEM_DBS = ( "sqlite_master", "sqlite_temp_master" )
ACCESS_SYSTEM_DBS = ( "MSysAccessObjects", "MSysACEs", "MSysObjects", "MSysQueries", "MSysRelationships", "MSysAccessStorage",\
"MSysAccessXML", "MSysModules", "MSysModules2" )
FIREBIRD_SYSTEM_DBS = ( "RDB$BACKUP_HISTORY", "RDB$CHARACTER_SETS", "RDB$CHECK_CONSTRAINTS", "RDB$COLLATIONS", "RDB$DATABASE",\
"RDB$DEPENDENCIES", "RDB$EXCEPTIONS", "RDB$FIELDS", "RDB$FIELD_DIMENSIONS", " RDB$FILES", "RDB$FILTERS",\
"RDB$FORMATS", "RDB$FUNCTIONS", "RDB$FUNCTION_ARGUMENTS", "RDB$GENERATORS", "RDB$INDEX_SEGMENTS", "RDB$INDICES",\
"RDB$LOG_FILES", "RDB$PAGES", "RDB$PROCEDURES", "RDB$PROCEDURE_PARAMETERS", "RDB$REF_CONSTRAINTS", "RDB$RELATIONS",\
"RDB$RELATION_CONSTRAINTS", "RDB$RELATION_FIELDS", "RDB$ROLES", "RDB$SECURITY_CLASSES", "RDB$TRANSACTIONS", "RDB$TRIGGERS",\
"RDB$TRIGGER_MESSAGES", "RDB$TYPES", "RDB$USER_PRIVILEGES", "RDB$VIEW_RELATIONS" )
MSSQL_ALIASES = [ "microsoft sql server", "mssqlserver", "mssql", "ms" ]
MYSQL_ALIASES = [ "mysql", "my" ]
PGSQL_ALIASES = [ "postgresql", "postgres", "pgsql", "psql", "pg" ]
ORACLE_ALIASES = [ "oracle", "orcl", "ora", "or" ]
SQLITE_ALIASES = [ "sqlite", "sqlite3" ]
ACCESS_ALIASES = [ "access", "jet", "microsoft access", "msaccess" ]
FIREBIRD_ALIASES = [ "firebird", "mozilla firebird", "interbase", "ibase", "fb" ]
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES
SUPPORTED_OS = ( "linux", "windows" )
SQL_STATEMENTS = {

View File

@@ -103,6 +103,8 @@ def bannerParser(banner):
DBMS banner based upon the data in XML file
"""
xmlfile = None
if kb.dbms == "Microsoft SQL Server":
xmlfile = paths.MSSQL_XML
elif kb.dbms == "MySQL":
@@ -112,6 +114,9 @@ def bannerParser(banner):
elif kb.dbms == "PostgreSQL":
xmlfile = paths.PGSQL_XML
if not xmlfile:
return
checkFile(xmlfile)
if kb.dbms == "Microsoft SQL Server":

View File

@@ -133,6 +133,10 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
if kb.dbmsDetected:
_, _, _, _, _, expressionFieldsList, expressionFields = agent.getFields(expression)
rdbRegExp = re.search("RDB\$GET_CONTEXT\([^)]+\)", expression, re.I)
if rdbRegExp and kb.dbms == "Firebird":
expressionFieldsList = [expressionFields]
if len(expressionFieldsList) > 1:
infoMsg = "the SQL query provided has more than a field. "
infoMsg += "sqlmap will now unpack it into distinct queries "
@@ -375,6 +379,9 @@ def getValue(expression, blind=True, inband=True, fromUser=False, expected=None,
conf.paramFalseCond = oldParamFalseCond
conf.paramNegative = oldParamNegative
if value:
value = value.strip()
return value
def goStacked(expression, silent=False):

View File

@@ -121,9 +121,17 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
queriesCount[0] += 1
position = (len(asciiTbl) / 2)
posValue = asciiTbl[position]
if kb.dbms == "SQLite":
posValueOld = posValue
posValue = chr(posValue)
forgedPayload = safeStringFormat(payload, (expressionUnescaped, idx, posValue))
result = Request.queryPage(forgedPayload)
if kb.dbms == "SQLite":
posValue = posValueOld
if result:
minValue = posValue
asciiTbl = asciiTbl[position:]