metasploit-framework/lib/rex/parser/dbeaver.rb

141 lines
4.7 KiB
Ruby

module Rex
module Parser
# @author Kali-Team
module Dbeaver
module Error
class DbeaverError < StandardError
end
class ParserError < DbeaverError
end
class DecryptionError < ParserError
end
end
SECRET_KEY = 'sdf@!#$verf^wv%6Fwe%$$#FFGwfsdefwfe135s$^H)dg'.freeze
AES_KEY = "\xBA\xBBJ\x9FwJ\xB8S\xC9l-e=\xFETJ".freeze
# decrypt_dbeaver_credentials
#
# @param credentials_config_data [String]
# @return [String] plaintext
def decrypt_dbeaver_credentials(credentials_config_data)
aes = OpenSSL::Cipher.new('AES-128-CBC')
begin
aes.decrypt
aes.key = AES_KEY
plaintext = aes.update(credentials_config_data)
plaintext << aes.final
rescue OpenSSL::Cipher::CipherError => e
raise Error::DecryptionError, 'Unable to decrypt dbeaver credentials'
end
return plaintext[plaintext.index('{"')..]
end
# parse_credentials
#
# @param credentials_config_data [String]
# @return [Hash] result_hashmap
def parse_credentials(credentials_config_data)
decrypt_data = decrypt_dbeaver_credentials(credentials_config_data)
result_hashmap = Hash.new
begin
result_hashmap = JSON.parse(decrypt_data)
rescue ::JSON::ParserError => e
raise Error::ParserError, "[parse_credentials] #{e.class} - #{e}"
end
return result_hashmap
end
# parse_data_sources
#
# @param data_sources_data [String]
# @param credentials_config_data [String]
# @return [Hash] result_hashmap
def parse_data_sources(data_sources_data, credentials_config_data)
credentials = parse_credentials(credentials_config_data)
result_hashmap = Hash.new
if credentials.empty?
return result_hashmap
end
begin
data_sources = JSON.parse(data_sources_data)
connections = data_sources['connections']
if connections.nil? || connections.empty?
return result_hashmap
end
connections.each do |data_source_id, item|
next if item['configuration'].nil?
result_hashmap[data_source_id] = Hash[
'name' => item['name'] || '',
'provider' => item['provider'] || '',
'host' => item['configuration']['host'] || '',
'port' => item['configuration']['port'] || '',
'user' => credentials.key?(data_source_id) ? credentials[data_source_id]['#connection']['user'] : '',
'password' => credentials.key?(data_source_id) ? credentials[data_source_id]['#connection']['password'] : '',
'database' => item['configuration']['database'] || '',
'url' => item['configuration']['url'] || '',
'type' => item['configuration']['type'] || ''
]
end
rescue ::JSON::ParserError => e
raise Error::ParserError, "[parse_data_sources] #{e.class} - #{e}"
end
return result_hashmap
end
# decrypt_dbeaver_6_1_3
#
# @param base64_string [String]
# @return [String]
def decrypt_dbeaver_6_1_3(base64_string)
plaintext = ''
if base64_string.nil?
return plaintext
end
data = Rex::Text.decode_base64(base64_string)
for i in 0..data.length - 3
xor_data = Rex::Text.xor(data[i], SECRET_KEY[i % SECRET_KEY.length])
plaintext += xor_data
end
return plaintext
end
# parse_data_sources_xml
#
# @param data_sources_data [String]
# @return [Hash] result_hashmap
def parse_data_sources_xml(data_sources_data)
mxml = REXML::Document.new(data_sources_data).root
unless mxml
raise Error::ParserError, '[parse_data_sources_xml] XML parsing error'
end
result_hashmap = Hash.new
mxml.elements.to_a('//data-sources//data-source//connection//').each do |node|
next unless node.name == 'connection'
data_source_id = node.parent.attributes['id']
result_hashmap[data_source_id] = Hash[
'name' => node.parent.attributes['name'] || '',
'provider' => node.parent.attributes['provider'] || '',
'host' => node.attributes['host'] || '',
'port' => node.attributes['port'] || '',
'user' => node.attributes['user'] || '',
'password' => decrypt_dbeaver_6_1_3(node.attributes['password']),
'database' => node.attributes['database'] || '',
'url' => node.attributes['url'] || '',
'type' => node.attributes['type'] || ''
]
end
return result_hashmap
end
end
end
end