Added support to connect directly also to Oracle - see #158

This commit is contained in:
Bernardo Damele 2010-03-27 21:50:19 +00:00
parent 1416cd0d86
commit a0290a257b
7 changed files with 98 additions and 12 deletions

View File

@ -628,7 +628,7 @@ def parseTargetDirect():
dbmsDict = { "Microsoft SQL Server": [MSSQL_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/"],
"MySQL": [MYSQL_ALIASES, "python-mysqldb", "http://mysql-python.sourceforge.net/"],
"PostgreSQL": [PGSQL_ALIASES, "python-psycopg2", "http://initd.org/psycopg/"],
"Oracle": [ORACLE_ALIASES, "", ""],
"Oracle": [ORACLE_ALIASES, "python cx_Oracle", "http://cx-oracle.sourceforge.net/"],
"SQLite": [SQLITE_ALIASES, "", ""],
"Access": [ACCESS_ALIASES, "", ""],
"Firebird": [FIREBIRD_ALIASES, "", ""] }
@ -642,6 +642,8 @@ def parseTargetDirect():
import MySQLdb
elif dbmsName == "PostgreSQL":
import psycopg2
elif dbmsName == "Oracle":
import cx_Oracle
except ImportError, _:
errMsg = "sqlmap requires %s third-party library " % data[1]
errMsg += "in order to directly connect to the database "

View File

@ -268,6 +268,9 @@ class Connect:
values = None
select = False
if kb.dbms == "Oracle" and value.startswith("SELECT ") and " FROM " not in value:
value = "%s FROM DUAL" % value
for sqlTitle, sqlStatements in SQL_STATEMENTS.items():
for sqlStatement in sqlStatements:
if value.lower().startswith(sqlStatement) and sqlTitle == "SQL SELECT statement":

View File

@ -356,6 +356,9 @@ def getValue(expression, blind=True, inband=True, fromUser=False, expected=None,
values = None
select = False
if kb.dbms == "Oracle" and expression.startswith("SELECT ") and " FROM " not in expression:
expression = "%s FROM DUAL" % expression
for sqlTitle, sqlStatements in SQL_STATEMENTS.items():
for sqlStatement in sqlStatements:
if expression.lower().startswith(sqlStatement) and sqlTitle == "SQL SELECT statement":
@ -419,6 +422,9 @@ def goStacked(expression, silent=False):
values = None
select = False
if kb.dbms == "Oracle" and expression.startswith("SELECT ") and " FROM " not in expression:
expression = "%s FROM DUAL" % expression
for sqlTitle, sqlStatements in SQL_STATEMENTS.items():
for sqlStatement in sqlStatements:
if expression.lower().startswith(sqlStatement) and sqlTitle == "SQL SELECT statement":

View File

@ -22,14 +22,72 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
try:
import cx_Oracle
except ImportError, _:
pass
from lib.core.data import logger
from lib.core.exception import sqlmapConnectionException
from plugins.generic.connector import Connector as GenericConnector
class Connector(GenericConnector):
"""
Homepage:
User guide:
API:
Homepage: http://cx-oracle.sourceforge.net/
User guide: http://cx-oracle.sourceforge.net/README.txt
API: http://cx-oracle.sourceforge.net/html/index.html
Debian package: -
License: http://cx-oracle.sourceforge.net/LICENSE.txt
Possible connectors: -
"""
def __init__(self):
GenericConnector.__init__(self)
def connect(self):
self.initConnection()
self.__dsn = cx_Oracle.makedsn(self.hostname, self.port, self.db)
try:
self.connector = cx_Oracle.connect(dsn=self.__dsn, user=self.user, password=self.password, mode=cx_Oracle.SYSDBA)
logger.info("successfully connected as SYSDBA")
except (cx_Oracle.OperationalError, cx_Oracle.DatabaseError), _:
try:
self.connector = cx_Oracle.connect(dsn=self.__dsn, user=self.user, password=self.password)
except (cx_Oracle.OperationalError, cx_Oracle.DatabaseError), msg:
raise sqlmapConnectionException, msg
self.setCursor()
self.connected()
def fetchall(self):
try:
return self.cursor.fetchall()
except cx_Oracle.InterfaceError, msg:
logger.log(8, msg)
return None
def execute(self, query):
logger.debug(query)
try:
self.cursor.execute(query)
except (cx_Oracle.DatabaseError), msg:
logger.log(8, msg)
except cx_Oracle.InternalError, msg:
raise sqlmapConnectionException, msg
self.connector.commit()
def select(self, query):
self.execute(query)
return self.fetchall()
def setCursor(self):
self.cursor = self.connector.cursor()
def close(self):
self.cursor.close()
self.connector.close()

View File

@ -22,6 +22,7 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
from lib.core.common import getRange
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
@ -49,7 +50,7 @@ class Enumeration(GenericEnumeration):
# Set containing the list of DBMS administrators
areAdmins = set()
if kb.unionPosition:
if kb.unionPosition or conf.direct:
if query2:
query = rootQuery["inband"]["query2"]
condition = rootQuery["inband"]["condition2"]

View File

@ -78,6 +78,12 @@ class Fingerprint(GenericFingerprint):
return value
def checkDbms(self):
logMsg = "testing Oracle"
logger.info(logMsg)
if conf.direct:
conf.dbmsConnector.connect()
if conf.dbms in ORACLE_ALIASES:
setDbms("Oracle")
@ -86,9 +92,11 @@ class Fingerprint(GenericFingerprint):
if not conf.extensiveFp:
return True
logMsg = "testing Oracle"
logger.info(logMsg)
# NOTE: SELECT ROWNUM=ROWNUM FROM DUAL does not work connecting
# directly to the Oracle database
if conf.direct:
result = True
else:
payload = agent.fullPayload(" AND ROWNUM=ROWNUM")
result = Request.queryPage(payload)
@ -96,6 +104,11 @@ class Fingerprint(GenericFingerprint):
logMsg = "confirming Oracle"
logger.info(logMsg)
# NOTE: SELECT LENGTH(SYSDATE)=LENGTH(SYSDATE) FROM DUAL does
# not work connecting directly to the Oracle database
if conf.direct:
result = True
else:
payload = agent.fullPayload(" AND LENGTH(SYSDATE)=LENGTH(SYSDATE)")
result = Request.queryPage(payload)

View File

@ -26,6 +26,9 @@ import os
import sys
import time
import traceback
import warnings
warnings.filterwarnings(action="ignore", message=".*was already imported", category=UserWarning)
try:
import psyco