2010-04-30 08:40:19 +00:00
##
# $Id$
##
2009-09-28 23:13:06 +00:00
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/projects/Framework/
##
require 'msf/core'
class Metasploit3 < Msf :: Auxiliary
2009-12-05 14:18:24 +00:00
2009-09-30 21:04:54 +00:00
include Msf :: Auxiliary :: Report
2009-09-28 23:13:06 +00:00
include Msf :: Exploit :: ORACLE
2010-04-30 08:40:19 +00:00
2009-09-28 23:13:06 +00:00
def initialize ( info = { } )
super ( update_info ( info ,
2009-12-05 14:18:24 +00:00
'Name' = > 'Oracle Database Enumeration' ,
2009-09-30 21:44:54 +00:00
'Description' = > %q{
This module provides a simple way to scan an Oracle database server
for configuration parameters that may be useful during a penetration
test . Valid database credentials must be provided for this module to
run .
} ,
'Author' = > [ 'Carlos Perez <carlos_perez[at]darkoperator.com>' ] ,
'License' = > MSF_LICENSE ,
'Version' = > '$Revision$'
2009-09-30 21:04:54 +00:00
) )
2009-09-28 23:13:06 +00:00
end
2009-09-30 21:04:54 +00:00
def run
2010-03-24 19:02:38 +00:00
return if not check_dependencies
2009-09-30 21:04:54 +00:00
begin
#Get all values from v$parameter
query = 'select name,value from v$parameter'
vparm = { }
2009-12-03 23:57:02 +00:00
params = prepare_exec ( query )
params . each do | l |
2009-09-30 21:04:54 +00:00
name , value = l . split ( " , " )
vparm [ " #{ name } " ] = value
2009-09-28 23:13:06 +00:00
end
2009-09-30 21:04:54 +00:00
end
print_status ( " Running Oracle Enumeration.... " )
2010-04-30 08:40:19 +00:00
2009-09-30 21:04:54 +00:00
#Version Check
query = 'select * from v$version'
2009-12-03 23:57:02 +00:00
ver = prepare_exec ( query )
2009-09-30 21:04:54 +00:00
print_status ( " The versions of the Components are: " )
2009-12-03 23:57:02 +00:00
ver . each do | v |
2009-09-30 21:04:54 +00:00
print_status ( " \t #{ v . chomp } " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Component Version: #{ v . chomp } " )
end
2010-04-30 08:40:19 +00:00
2009-09-30 21:04:54 +00:00
#Saving Major Release Number for other checks
2009-12-03 23:57:02 +00:00
majorrel = ver [ 0 ] . scan ( / Edition Release ( \ d*). / )
2009-09-30 21:04:54 +00:00
#-------------------------------------------------------
#Audit Check
print_status ( " Auditing: " )
begin
if vparm [ " audit_trail " ] == " NONE "
print_status ( " \t Database Auditing is not enabled! " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Audit Trail: Disabled " )
else
print_status ( " \t Database Auditing is enabled! " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Audit Trail: Enabled " )
end
if vparm [ " audit_sys_operations " ] == " FALSE "
print_status ( " \t Auditing of SYS Operations is not enabled! " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Audit SYS Ops: Disabled " )
else
print_status ( " \t Auditing of SYS Operations is enabled! " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Audit SYS Ops: Enabled " )
end
end
2010-04-30 08:40:19 +00:00
2009-09-30 21:04:54 +00:00
#-------------------------------------------------------
#Security Settings
print_status ( " Security Settings: " )
begin
if vparm [ " sql92_security " ] == " FALSE "
print_status ( " \t SQL92 Security restriction on SELECT is not Enabled " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " SQL92: Disabled " )
else
print_status ( " \t SQL92 Security restriction on SELECT is Enabled " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " SQL92: Enabled " )
end
# check for encryption of logins on version before 10g
if majorrel . join . to_i < 10
if vparm [ " dblink_encrypt_login " ] == " FALSE "
print_status ( " \t Link Encryption for Logins is not Enabled " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Link Encryption: Disabled " )
2009-09-29 21:58:01 +00:00
else
2009-09-30 21:04:54 +00:00
print_status ( " \t Link Encryption for Logins is Enabled " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Link Encryption: Enabled " )
2009-09-29 21:58:01 +00:00
end
end
2009-09-30 21:04:54 +00:00
2009-12-03 23:57:02 +00:00
print_status ( " \t UTL Directory Access is set to #{ vparm [ " utl_file_dir " ] } " ) if vparm [ " utl_file_dir " ] != " "
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " UTL_DIR: #{ vparm [ " utl_file_dir " ] } " ) if not vparm [ " utl_file_dir " ] #.empty?
2009-09-30 21:04:54 +00:00
2009-12-03 23:57:02 +00:00
print_status ( " \t Audit log is saved at #{ vparm [ " audit_file_dest " ] } " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Audit Log Location: #{ vparm [ " audit_file_dest " ] } " ) if not vparm [ " audit_file_dest " ] #.empty?
2009-09-30 21:04:54 +00:00
end
#-------------------------------------------------------
#Password Policy
print_status ( " Password Policy: " )
begin
query = % Q |
SELECT limit
FROM dba_profiles
WHERE resource_name = 'PASSWORD_LOCK_TIME'
AND profile = 'DEFAULT'
|
2009-12-03 23:57:02 +00:00
lockout = prepare_exec ( query )
print_status ( " \t Current Account Lockout Time is set to #{ lockout [ 0 ] . chomp } " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Account Lockout Time: #{ lockout [ 0 ] . chomp } " )
2009-09-30 21:04:54 +00:00
rescue = > e
if e . to_s =~ / ORA-00942: table or view does not exist /
print_error ( " It appears you do not have sufficient rights to perform the check " )
end
2009-09-29 21:58:01 +00:00
end
2010-04-30 08:40:19 +00:00
2009-09-30 21:04:54 +00:00
begin
query = % Q |
SELECT limit
FROM dba_profiles
WHERE resource_name = 'FAILED_LOGIN_ATTEMPTS'
AND profile = 'DEFAULT'
|
2009-12-03 23:57:02 +00:00
failed_logins = prepare_exec ( query )
print_status ( " \t The Number of Failed Logins before an account is locked is set to #{ failed_logins [ 0 ] . chomp } " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Account Fail Logins Permitted: #{ failed_logins [ 0 ] . chomp } " )
2009-09-28 23:13:06 +00:00
2009-09-30 21:04:54 +00:00
rescue = > e
if e . to_s =~ / ORA-00942: table or view does not exist /
print_error ( " It appears you do not have sufficient rights to perform the check " )
end
end
2010-04-30 08:40:19 +00:00
2009-09-30 21:04:54 +00:00
begin
query = % Q |
SELECT limit
FROM dba_profiles
WHERE resource_name = 'FAILED_LOGIN_ATTEMPTS'
AND profile = 'DEFAULT'
|
2009-12-03 23:57:02 +00:00
grace_time = prepare_exec ( query )
print_status ( " \t The Password Grace Time is set to #{ grace_time [ 0 ] . chomp } " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Account Password Grace Time: #{ grace_time [ 0 ] . chomp } " )
2009-09-30 21:04:54 +00:00
rescue = > e
if e . to_s =~ / ORA-00942: table or view does not exist /
print_error ( " It appears you do not have sufficient rights to perform the check " )
end
end
2010-04-30 08:40:19 +00:00
2009-09-30 21:04:54 +00:00
begin
query = % Q |
SELECT limit
FROM dba_profiles
WHERE resource_name = 'PASSWORD_LIFE_TIME'
AND profile = 'DEFAULT'
|
2009-12-03 23:57:02 +00:00
passlife_time = prepare_exec ( query )
print_status ( " \t The Lifetime of Passwords is set to #{ passlife_time [ 0 ] . chomp } " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Password Life Time: #{ passlife_time [ 0 ] . chomp } " )
2009-09-30 21:04:54 +00:00
rescue = > e
if e . to_s =~ / ORA-00942: table or view does not exist /
print_error ( " It appears you do not have sufficient rights to perform the check " )
end
end
2009-12-05 14:18:24 +00:00
2009-09-30 21:04:54 +00:00
begin
query = % Q |
SELECT limit
FROM dba_profiles
WHERE resource_name = 'PASSWORD_REUSE_TIME'
AND profile = 'DEFAULT'
|
2009-12-03 23:57:02 +00:00
passreuse = prepare_exec ( query )
print_status ( " \t The Number of Times a Password can be reused is set to #{ passreuse [ 0 ] . chomp } " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Password Reuse Time: #{ passreuse [ 0 ] . chomp } " )
2009-09-30 21:04:54 +00:00
rescue = > e
if e . to_s =~ / ORA-00942: table or view does not exist /
print_error ( " It appears you do not have sufficient rights to perform the check " )
end
end
2009-12-05 14:18:24 +00:00
2009-09-30 21:04:54 +00:00
begin
query = % Q |
SELECT limit
FROM dba_profiles
WHERE resource_name = 'PASSWORD_REUSE_MAX'
AND profile = 'DEFAULT'
|
2009-12-03 23:57:02 +00:00
passreusemax = prepare_exec ( query )
print_status ( " \t The Maximun Number of Times a Password needs to be changed before it can be reused is set to #{ passreusemax [ 0 ] . chomp } " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Password Maximun Reuse Time: #{ passreusemax [ 0 ] . chomp } " )
print_status ( " \t The Number of Times a Password can be reused is set to #{ passreuse [ 0 ] . chomp } " )
2009-09-30 21:04:54 +00:00
rescue = > e
if e . to_s =~ / ORA-00942: table or view does not exist /
print_error ( " It appears you do not have sufficient rights to perform the check " )
end
end
2009-12-05 14:18:24 +00:00
2009-09-30 21:04:54 +00:00
begin
query = % Q |
SELECT limit
FROM dba_profiles
WHERE resource_name = 'PASSWORD_VERIFY_FUNCTION'
AND profile = 'DEFAULT'
|
2009-12-03 23:57:02 +00:00
passrand = prepare_exec ( query )
if passrand [ 0 ] =~ / NULL /
2009-09-30 21:04:54 +00:00
print_status ( " \t Password Complexity is not checked " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Password Complexity is not being checked for new passwords " )
else
print_status ( " \t Password Complexity is being checked " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Password Complexity is being checked for new passwords " )
end
rescue = > e
if e . to_s =~ / ORA-00942: table or view does not exist /
print_error ( " It appears you do not have sufficient rights to perform the check " )
end
end
#-------------------------------------------------------
2009-12-03 23:57:02 +00:00
2009-09-30 21:04:54 +00:00
begin
if majorrel . join . to_i < 11
query = % Q |
2010-04-30 08:40:19 +00:00
SELECT name , password
2009-09-30 21:04:54 +00:00
FROM sys . user $
where password != 'null' and type # = 1 and astatus = 0
|
2009-12-03 23:57:02 +00:00
activeacc = prepare_exec ( query )
2009-09-30 21:04:54 +00:00
print_status ( " Active Accounts on the System in format Username,Hash are: " )
2009-12-03 23:57:02 +00:00
activeacc . each do | aa |
2009-09-30 21:04:54 +00:00
print_status ( " \t #{ aa . chomp } " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Active Account #{ aa . chomp } " )
end
else
query = % Q |
SELECT name , password , spare4
FROM sys . user $
where password != 'null' and type # = 1 and astatus = 0
|
2009-12-03 23:57:02 +00:00
activeacc = prepare_exec ( query )
2009-09-30 21:04:54 +00:00
print_status ( " Active Accounts on the System in format Username,Password,Spare4 are: " )
2009-12-03 23:57:02 +00:00
activeacc . each do | aa |
2009-09-30 21:04:54 +00:00
print_status ( " \t #{ aa . chomp } " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Active Account #{ aa . chomp } " )
end
end
rescue = > e
if e . to_s =~ / ORA-00942: table or view does not exist /
print_error ( " It appears you do not have sufficient rights to perform the check " )
end
end
begin
if majorrel . join . to_i < 11
query = % Q |
2010-04-30 08:40:19 +00:00
SELECT username , password
2009-09-30 21:04:54 +00:00
FROM dba_users
WHERE account_status = 'EXPIRED & LOCKED'
|
2009-12-03 23:57:02 +00:00
disabledacc = prepare_exec ( query )
2009-09-30 21:04:54 +00:00
print_status ( " Expired or Locked Accounts on the System in format Username,Hash are: " )
2009-12-03 23:57:02 +00:00
disabledacc . each do | da |
2009-09-30 21:04:54 +00:00
print_status ( " \t #{ da . chomp } " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Disabled Account #{ da . chomp } " )
end
else
query = % Q |
SELECT name , password , spare4
FROM sys . user $
where password != 'null' and type # = 1 and astatus = 8 or astatus = 9
|
2009-12-03 23:57:02 +00:00
disabledacc = prepare_exec ( query )
2009-09-30 21:04:54 +00:00
print_status ( " Expired or Locked Accounts on the System in format Username,Password,Spare4 are: " )
2009-12-03 23:57:02 +00:00
disabledacc . each do | da |
2009-09-30 21:04:54 +00:00
print_status ( " \t #{ da . chomp } " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Disabled Account #{ da . chomp } " )
end
end
rescue = > e
if e . to_s =~ / ORA-00942: table or view does not exist /
print_error ( " It appears you do not have sufficient rights to perform the check " )
end
end
begin
query = % Q |
SELECT grantee
FROM dba_role_privs
WHERE granted_role = 'DBA'
|
2009-12-03 23:57:02 +00:00
dbaacc = prepare_exec ( query )
2009-09-30 21:04:54 +00:00
print_status ( " Accounts with DBA Privilege in format Username,Hash on the System are: " )
2009-12-03 23:57:02 +00:00
dbaacc . each do | dba |
2009-09-30 21:04:54 +00:00
print_status ( " \t #{ dba . chomp } " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Account with DBA Priv #{ dba . chomp } " )
end
rescue = > e
if e . to_s =~ / ORA-00942: table or view does not exist /
print_error ( " It appears you do not have sufficient rights to perform the check " )
end
end
begin
query = % Q |
SELECT grantee
FROM dba_sys_privs
WHERE privilege = 'ALTER SYSTEM'
|
2009-12-03 23:57:02 +00:00
altersys = prepare_exec ( query )
2009-09-30 21:04:54 +00:00
print_status ( " Accounts with Alter System Privilege on the System are: " )
2009-12-03 23:57:02 +00:00
altersys . each do | as |
2009-09-30 21:04:54 +00:00
print_status ( " \t #{ as . chomp } " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Account with ALTER SYSTEM Priv #{ as . chomp } " )
end
rescue = > e
if e . to_s =~ / ORA-00942: table or view does not exist /
print_error ( " It appears you do not have sufficient rights to perform the check " )
end
end
begin
query = % Q |
SELECT grantee
FROM dba_sys_privs
WHERE privilege = 'JAVA ADMIN'
|
2009-12-03 23:57:02 +00:00
javaacc = prepare_exec ( query )
2009-09-30 21:04:54 +00:00
print_status ( " Accounts with JAVA ADMIN Privilege on the System are: " )
2009-12-03 23:57:02 +00:00
javaacc . each do | j |
2009-09-30 21:04:54 +00:00
print_status ( " \t #{ j . chomp } " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Account with JAVA ADMIN Priv #{ j . chomp } " )
end
rescue = > e
if e . to_s =~ / ORA-00942: table or view does not exist /
print_error ( " It appears you do not have sufficient rights to perform the check " )
end
end
2009-09-28 23:13:06 +00:00
begin
2009-09-30 21:04:54 +00:00
query = % Q |
select grantee
from dba_sys_privs
where privilege = 'CREATE LIBRARY'
or privilege = 'CREATE ANY'
|
2009-12-03 23:57:02 +00:00
libpriv = prepare_exec ( query )
2009-09-30 21:04:54 +00:00
print_status ( " Accounts that have CREATE LIBRARY Privilege on the System are: " )
2009-12-03 23:57:02 +00:00
libpriv . each do | lp |
2009-09-30 21:04:54 +00:00
print_status ( " \t #{ lp . chomp } " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Account with CREATE LIBRARY Priv #{ lp . chomp } " )
end
rescue = > e
if e . to_s =~ / ORA-00942: table or view does not exist /
print_error ( " It appears you do not have sufficient rights to perform the check " )
end
end
#Default Password Check
begin
print_status ( " Default password check: " )
if majorrel . join . to_i == 11
query = % Q |
SELECT * FROM dba_users_with_defpwd
|
2009-12-03 23:57:02 +00:00
defpwd = prepare_exec ( query )
2009-09-30 21:04:54 +00:00
defpwd . each do | dp |
print_status ( " \t The account #{ dp . chomp } has a default password. " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Account with Default Password #{ dp . chomp } " )
end
else
query = % Q |
SELECT name , password
FROM sys . user $
where password != 'null' and type # = 1
|
ordfltpss = " #{ File . join ( Msf :: Config . install_root , " data " , " wordlists " , " oracle_default_hashes.txt " ) } "
2009-12-03 23:57:02 +00:00
returnedstring = prepare_exec ( query )
2009-09-30 21:04:54 +00:00
accts = { }
2009-12-03 23:57:02 +00:00
returnedstring . each do | record |
2009-09-30 21:04:54 +00:00
user , pass = record . split ( " , " )
accts [ " #{ pass . chomp } " ] = " #{ user } "
end
2010-07-01 23:33:07 +00:00
:: File . open ( ordfltpss , " rb " ) . each_line do | l |
2009-09-30 21:04:54 +00:00
accrcrd = l . split ( " , " )
if accts . has_key? ( accrcrd [ 2 ] )
print_status ( " \t Default pass for account #{ accrcrd [ 0 ] } is #{ accrcrd [ 1 ] } " )
report_note ( :host = > datastore [ 'RHOST' ] , :proto = > 'TNS' , :port = > datastore [ 'RPORT' ] , :type = > 'ORA_ENUM' , :data = > " Account with Default Password #{ accrcrd [ 0 ] } is #{ accrcrd [ 1 ] } " )
end
end
end
end
end
2009-09-28 23:13:06 +00:00
end