mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-09 19:27:39 +02:00
Merge pull request #1682 from volatilityfoundation/fix_secrets_dumping_plugins
Bring hash dumping plugins up to current coding standards and error c…
This commit is contained in:
@@ -22,7 +22,7 @@ class Cachedump(interfaces.plugins.PluginInterface):
|
||||
"""Dumps lsa secrets from memory"""
|
||||
|
||||
_required_framework_version = (2, 0, 0)
|
||||
_version = (1, 0, 1)
|
||||
_version = (1, 0, 2)
|
||||
|
||||
@classmethod
|
||||
def get_requirements(cls):
|
||||
|
||||
@@ -9,7 +9,7 @@ from typing import List, Optional, Tuple
|
||||
|
||||
from Crypto.Cipher import AES, ARC4, DES
|
||||
|
||||
from volatility3.framework import interfaces, renderers
|
||||
from volatility3.framework import interfaces, renderers, exceptions
|
||||
from volatility3.framework.configuration import requirements
|
||||
from volatility3.framework.symbols.windows.extensions import registry
|
||||
from volatility3.plugins.windows.registry import hivelist
|
||||
@@ -21,7 +21,7 @@ class Hashdump(interfaces.plugins.PluginInterface):
|
||||
"""Dumps user hashes from memory"""
|
||||
|
||||
_required_framework_version = (2, 0, 0)
|
||||
_version = (1, 1, 0)
|
||||
_version = (1, 1, 1)
|
||||
|
||||
@classmethod
|
||||
def get_requirements(cls):
|
||||
@@ -326,7 +326,9 @@ class Hashdump(interfaces.plugins.PluginInterface):
|
||||
empty_nt = b"\x31\xd6\xcf\xe0\xd1\x6a\xe9\x31\xb7\x3c\x59\xd7\xe0\xc0\x89\xc0"
|
||||
|
||||
@classmethod
|
||||
def get_hive_key(cls, hive: registry.RegistryHive, key: str):
|
||||
def get_hive_key(
|
||||
cls, hive: registry.RegistryHive, key: str
|
||||
) -> Optional["registry.CM_KEY_NODE"]:
|
||||
result = None
|
||||
try:
|
||||
if hive:
|
||||
@@ -351,6 +353,9 @@ class Hashdump(interfaces.plugins.PluginInterface):
|
||||
|
||||
@classmethod
|
||||
def get_bootkey(cls, syshive: registry.RegistryHive) -> Optional[bytes]:
|
||||
"""
|
||||
Returns the scrambled bootkey necesary to decrypt hashes
|
||||
"""
|
||||
cs = 1
|
||||
lsa_base = f"ControlSet{cs:03}" + "\\Control\\Lsa"
|
||||
lsa_keys = ["JD", "Skew1", "GBG", "Data"]
|
||||
@@ -366,7 +371,10 @@ class Hashdump(interfaces.plugins.PluginInterface):
|
||||
key = cls.get_hive_key(syshive, lsa_base + "\\" + lk)
|
||||
class_data = None
|
||||
if key:
|
||||
class_data = syshive.read(key.Class + 4, key.ClassLength)
|
||||
try:
|
||||
class_data = syshive.read(key.Class + 4, key.ClassLength)
|
||||
except exceptions.InvalidAddressException:
|
||||
return None
|
||||
|
||||
if class_data is None:
|
||||
return None
|
||||
@@ -394,7 +402,11 @@ class Hashdump(interfaces.plugins.PluginInterface):
|
||||
sam_data = None
|
||||
for v in sam_account_key.get_values():
|
||||
if v.get_name() == "F":
|
||||
sam_data = samhive.read(v.Data + 4, v.DataLength)
|
||||
try:
|
||||
sam_data = samhive.read(v.Data + 4, v.DataLength)
|
||||
except exceptions.InvalidAddressException:
|
||||
return None
|
||||
|
||||
if not sam_data:
|
||||
return None
|
||||
|
||||
@@ -444,7 +456,11 @@ class Hashdump(interfaces.plugins.PluginInterface):
|
||||
sam_data = None
|
||||
for v in user.get_values():
|
||||
if v.get_name() == "V":
|
||||
sam_data = samhive.read(v.Data + 4, v.DataLength)
|
||||
try:
|
||||
sam_data = samhive.read(v.Data + 4, v.DataLength)
|
||||
except exceptions.InvalidAddressException:
|
||||
return None
|
||||
|
||||
if not sam_data:
|
||||
return None
|
||||
|
||||
@@ -546,7 +562,11 @@ class Hashdump(interfaces.plugins.PluginInterface):
|
||||
value = None
|
||||
for v in user.get_values():
|
||||
if v.get_name() == "V":
|
||||
value = samhive.read(v.Data + 4, v.DataLength)
|
||||
try:
|
||||
value = samhive.read(v.Data + 4, v.DataLength)
|
||||
except exceptions.InvalidAddressException:
|
||||
return None
|
||||
|
||||
if not value:
|
||||
return None
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ class Lsadump(interfaces.plugins.PluginInterface):
|
||||
"""Dumps lsa secrets from memory"""
|
||||
|
||||
_required_framework_version = (2, 0, 0)
|
||||
_version = (1, 0, 0)
|
||||
_version = (1, 0, 1)
|
||||
|
||||
@classmethod
|
||||
def get_requirements(cls):
|
||||
@@ -76,8 +76,7 @@ class Lsadump(interfaces.plugins.PluginInterface):
|
||||
enc_reg_key = hashdump.Hashdump.get_hive_key(sechive, "Policy\\" + policy_key)
|
||||
if not enc_reg_key:
|
||||
return None
|
||||
enc_reg_value = next(enc_reg_key.get_values())
|
||||
|
||||
enc_reg_value = next(enc_reg_key.get_values(), None)
|
||||
if not enc_reg_value:
|
||||
return None
|
||||
|
||||
@@ -112,18 +111,22 @@ class Lsadump(interfaces.plugins.PluginInterface):
|
||||
name: str,
|
||||
lsakey: bytes,
|
||||
is_vista_or_later: bool,
|
||||
):
|
||||
) -> Optional[bytes]:
|
||||
enc_secret_key = hashdump.Hashdump.get_hive_key(
|
||||
sechive, "Policy\\Secrets\\" + name + "\\CurrVal"
|
||||
)
|
||||
|
||||
secret = None
|
||||
if enc_secret_key:
|
||||
enc_secret_value = next(enc_secret_key.get_values())
|
||||
enc_secret_value = next(enc_secret_key.get_values(), None)
|
||||
if enc_secret_value:
|
||||
enc_secret = sechive.read(
|
||||
enc_secret_value.Data + 4, enc_secret_value.DataLength
|
||||
)
|
||||
try:
|
||||
enc_secret = sechive.read(
|
||||
enc_secret_value.Data + 4, enc_secret_value.DataLength
|
||||
)
|
||||
except exceptions.InvalidAddressExceptions:
|
||||
return None
|
||||
|
||||
if enc_secret:
|
||||
if not is_vista_or_later:
|
||||
secret = cls.decrypt_secret(enc_secret[0xC:], lsakey)
|
||||
@@ -133,7 +136,7 @@ class Lsadump(interfaces.plugins.PluginInterface):
|
||||
return secret
|
||||
|
||||
@classmethod
|
||||
def decrypt_secret(cls, secret: bytes, key: bytes):
|
||||
def decrypt_secret(cls, secret: bytes, key: bytes) -> bytes:
|
||||
"""Python implementation of SystemFunction005.
|
||||
|
||||
Decrypts a block of data with DES using given key.
|
||||
@@ -168,11 +171,11 @@ class Lsadump(interfaces.plugins.PluginInterface):
|
||||
)
|
||||
|
||||
bootkey = hashdump.Hashdump.get_bootkey(syshive)
|
||||
lsakey = self.get_lsa_key(sechive, bootkey, vista_or_later)
|
||||
if not bootkey:
|
||||
vollog.warning("Unable to find bootkey")
|
||||
return None
|
||||
|
||||
lsakey = self.get_lsa_key(sechive, bootkey, vista_or_later)
|
||||
if not lsakey:
|
||||
vollog.warning("Unable to find lsa key")
|
||||
return None
|
||||
@@ -190,15 +193,17 @@ class Lsadump(interfaces.plugins.PluginInterface):
|
||||
if not sec_val_key:
|
||||
continue
|
||||
|
||||
enc_secret_value = next(sec_val_key.get_values())
|
||||
enc_secret_value = next(sec_val_key.get_values(), None)
|
||||
if not enc_secret_value:
|
||||
continue
|
||||
|
||||
enc_secret = sechive.read(
|
||||
enc_secret_value.Data + 4, enc_secret_value.DataLength
|
||||
)
|
||||
if not enc_secret:
|
||||
try:
|
||||
enc_secret = sechive.read(
|
||||
enc_secret_value.Data + 4, enc_secret_value.DataLength
|
||||
)
|
||||
except exceptions.InvalidAddressExceptions:
|
||||
continue
|
||||
|
||||
if not vista_or_later:
|
||||
secret = self.decrypt_secret(enc_secret[0xC:], lsakey)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user