2013-02-14 15:32:17 +04:00
#!/usr/bin/env python
2008-10-15 19:38:22 +04:00
"""
2019-01-05 23:38:52 +03:00
Copyright ( c ) 2006 - 2019 sqlmap developers ( http : / / sqlmap . org / )
2017-10-11 15:50:46 +03:00
See the file ' LICENSE ' for copying permission
2008-10-15 19:38:22 +04:00
"""
import re
2011-01-28 19:36:09 +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
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 ) :
2011-04-30 17:20:05 +04:00
value = " "
2011-01-28 19:36:09 +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-28 19:36:09 +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
2011-04-30 17:20:05 +04:00
actVer = Format . getDbms ( )
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 :
2018-08-25 23:57:49 +03:00
banVer = kb . bannerFp . get ( " dbmsVersion " )
2011-01-28 19:36:09 +03:00
banVer = Format . getDbms ( [ banVer ] )
2008-11-16 02:41:31 +03:00
value + = " \n %s banner parsing fingerprint: %s " % ( blank , banVer )
2008-10-15 19:38:22 +04:00
2011-01-28 19:36:09 +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 ) :
2017-03-06 14:53:04 +03:00
if not conf . extensiveFp and Backend . isDbmsWithin ( 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-04-30 19:29:59 +04:00
infoMsg = " testing %s " % DBMS . ORACLE
logger . info ( infoMsg )
2010-03-31 14:50:47 +04:00
2018-06-05 01:59:47 +03:00
# NOTE: SELECT LENGTH(SYSDATE)=LENGTH(SYSDATE) FROM DUAL does
# not work connecting directly to the Oracle database
2010-03-28 00:50:19 +03:00
if conf . direct :
result = True
else :
2018-06-05 01:59:47 +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 result :
2011-04-30 19:29:59 +04:00
infoMsg = " confirming %s " % DBMS . ORACLE
logger . info ( infoMsg )
2008-10-15 19:38:22 +04:00
2018-06-05 01:59:47 +03:00
# NOTE: SELECT NVL(RAWTOHEX([RANDNUM1]),[RANDNUM1])=RAWTOHEX([RANDNUM1]) FROM DUAL does
2010-03-28 00:50:19 +03:00
# not work connecting directly to the Oracle database
if conf . direct :
result = True
else :
2018-06-05 01:59:47 +03:00
result = inject . checkBooleanExpression ( " NVL(RAWTOHEX([RANDNUM1]),[RANDNUM1])=RAWTOHEX([RANDNUM1]) " )
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 )
2016-06-03 03:27:59 +03:00
# Reference: https://en.wikipedia.org/wiki/Oracle_Database
2019-03-12 16:12:23 +03:00
for version in ( " 18c " , " 12c " , " 11g " , " 10g " , " 9i " , " 8i " ) :
2017-10-31 13:38:09 +03:00
number = int ( re . search ( r " ([ \ d]+) " , version ) . group ( 1 ) )
2013-06-26 15:53:42 +04:00
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-28 19:36:09 +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 ( )
if conf . tbl :
conf . tbl = conf . tbl . upper ( )