141 lines
4.7 KiB
Ruby
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
|