2008-10-15 19:38:22 +04:00
#!/usr/bin/env python
"""
2008-10-15 19:56:32 +04:00
$ Id $
2008-10-15 19:38:22 +04:00
2010-10-14 18:41:14 +04:00
Copyright ( c ) 2006 - 2010 sqlmap developers ( http : / / sqlmap . sourceforge . net / )
2010-10-15 03:18:29 +04:00
See the file ' doc/COPYING ' for copying permission
2008-10-15 19:38:22 +04:00
"""
import re
2008-12-23 02:26:44 +03:00
from lib . core . agent import agent
2011-01-20 02:06:15 +03:00
from lib . core . common import backend
from lib . core . common import format
2008-10-15 19:38:22 +04:00
from lib . core . data import conf
from lib . core . data import kb
from lib . core . data import logger
2010-11-08 12:20:02 +03:00
from lib . core . enums import DBMS
2008-10-15 19:38:22 +04:00
from lib . core . session import setDbms
from lib . core . settings import ORACLE_ALIASES
from lib . request import inject
2008-12-23 02:26:44 +03:00
from lib . request . connect import Connect as Request
2008-10-15 19:38:22 +04:00
2010-03-23 01:57:57 +03:00
from plugins . generic . fingerprint import Fingerprint as GenericFingerprint
2008-10-15 19:38:22 +04:00
2010-03-23 01:57:57 +03:00
class Fingerprint ( GenericFingerprint ) :
2008-10-15 19:38:22 +04:00
def __init__ ( self ) :
2011-01-14 14:55:20 +03:00
GenericFingerprint . __init__ ( self , DBMS . ORACLE )
2008-10-15 19:38:22 +04:00
def getFingerprint ( self ) :
2008-11-18 20:42:46 +03:00
value = " "
2011-01-20 02:06:15 +03:00
wsOsFp = format . getOs ( " web server " , kb . headersFp )
2008-11-18 20:42:46 +03:00
if wsOsFp :
value + = " %s \n " % wsOsFp
2008-11-17 14:22:03 +03:00
2009-04-22 15:48:07 +04:00
if kb . data . banner :
2011-01-20 02:06:15 +03:00
dbmsOsFp = format . getOs ( " back-end DBMS " , kb . bannerFp )
2008-11-17 14:22:03 +03:00
2008-11-18 20:42:46 +03:00
if dbmsOsFp :
value + = " %s \n " % dbmsOsFp
2008-11-17 14:22:03 +03:00
value + = " back-end DBMS: "
2008-10-15 19:38:22 +04:00
2008-11-17 03:00:54 +03:00
if not conf . extensiveFp :
2010-11-02 15:08:28 +03:00
value + = DBMS . ORACLE
2008-11-17 03:00:54 +03:00
return value
2008-10-15 19:38:22 +04:00
2008-11-17 03:00:54 +03:00
actVer = formatDBMSfp ( )
blank = " " * 15
value + = " active fingerprint: %s " % actVer
2008-10-15 19:38:22 +04:00
2008-11-17 20:41:02 +03:00
if kb . bannerFp :
2010-03-04 12:16:45 +03:00
banVer = kb . bannerFp [ " dbmsVersion " ] if ' dbmsVersion ' in kb . bannerFp else None
2008-11-16 02:41:31 +03:00
banVer = formatDBMSfp ( [ banVer ] )
value + = " \n %s banner parsing fingerprint: %s " % ( blank , banVer )
2008-10-15 19:38:22 +04:00
2011-01-20 02:06:15 +03:00
htmlErrorFp = format . getErrorParsedDBMSes ( )
2008-10-15 19:38:22 +04:00
2008-11-17 03:00:54 +03:00
if htmlErrorFp :
value + = " \n %s html error message fingerprint: %s " % ( blank , htmlErrorFp )
2008-10-15 19:38:22 +04:00
return value
def checkDbms ( self ) :
2011-01-20 02:06:15 +03:00
if not conf . extensiveFp and ( backend . isDbmsWithin ( ORACLE_ALIASES ) or conf . dbms in ORACLE_ALIASES ) :
2010-11-02 14:59:24 +03:00
setDbms ( DBMS . ORACLE )
2008-10-15 19:38:22 +04:00
2009-04-22 15:48:07 +04:00
self . getBanner ( )
2008-11-17 14:22:03 +03:00
2011-01-14 15:47:07 +03:00
return True
2008-10-15 19:38:22 +04:00
2011-01-20 02:06:15 +03:00
logMsg = " testing %s " % DBMS . ORACLE
2010-03-31 14:50:47 +04:00
logger . info ( logMsg )
2010-03-28 00:50:19 +03:00
# NOTE: SELECT ROWNUM=ROWNUM FROM DUAL does not work connecting
# directly to the Oracle database
if conf . direct :
result = True
else :
2010-12-14 00:33:42 +03:00
result = inject . checkBooleanExpression ( " ROWNUM=ROWNUM " )
2008-10-15 19:38:22 +04:00
2010-01-02 05:02:12 +03:00
if result :
2011-01-20 02:06:15 +03:00
logMsg = " confirming %s " % DBMS . ORACLE
2008-10-15 19:38:22 +04:00
logger . info ( logMsg )
2010-03-28 00:50:19 +03:00
# NOTE: SELECT LENGTH(SYSDATE)=LENGTH(SYSDATE) FROM DUAL does
# not work connecting directly to the Oracle database
if conf . direct :
result = True
else :
2010-12-14 00:33:42 +03:00
result = inject . checkBooleanExpression ( " LENGTH(SYSDATE)=LENGTH(SYSDATE) " )
2008-10-15 19:38:22 +04:00
2010-01-02 05:02:12 +03:00
if not result :
2011-01-20 02:06:15 +03:00
warnMsg = " the back-end DBMS is not %s " % DBMS . ORACLE
2008-10-15 19:38:22 +04:00
logger . warn ( warnMsg )
return False
2010-11-02 14:59:24 +03:00
setDbms ( DBMS . ORACLE )
2008-10-15 19:38:22 +04:00
2009-04-22 15:48:07 +04:00
self . getBanner ( )
2008-11-17 14:22:03 +03:00
2008-10-15 19:38:22 +04:00
if not conf . extensiveFp :
return True
2011-01-20 02:06:15 +03:00
infoMsg = " actively fingerprinting %s " % DBMS . ORACLE
logger . info ( infoMsg )
2010-12-14 00:33:42 +03:00
for version in ( " 11i " , " 10g " , " 9i " , " 8i " ) :
2010-12-31 01:40:37 +03:00
number = int ( re . search ( " ([ \ d]+) " , version ) . group ( 1 ) )
output = inject . checkBooleanExpression ( " %d =(SELECT SUBSTR((VERSION), 1, %d ) FROM SYS.PRODUCT_COMPONENT_VERSION WHERE ROWNUM=1) " % ( number , 1 if number < 10 else 2 ) )
2010-12-14 00:33:42 +03:00
if output :
2011-01-20 02:06:15 +03:00
backend . setVersion ( version )
2010-12-14 00:33:42 +03:00
break
2008-10-15 19:38:22 +04:00
return True
else :
2011-01-20 02:06:15 +03:00
warnMsg = " the back-end DBMS is not %s " % DBMS . ORACLE
2008-10-15 19:38:22 +04:00
logger . warn ( warnMsg )
return False
2008-10-26 19:19:15 +03:00
def forceDbmsEnum ( self ) :
if conf . db :
conf . db = conf . db . upper ( )
else :
conf . db = " USERS "
2011-01-20 02:06:15 +03:00
warnMsg = " on %s it is only possible to enumerate " % DBMS . ORACLE
2008-10-26 19:19:15 +03:00
warnMsg + = " if you provide a TABLESPACE_NAME as database "
warnMsg + = " name. sqlmap is going to use ' USERS ' as database "
warnMsg + = " name "
logger . warn ( warnMsg )
if conf . tbl :
conf . tbl = conf . tbl . upper ( )