Skip to content

Commit 7ac9d02

Browse files
authored
Merge pull request #1682 from volatilityfoundation/fix_secrets_dumping_plugins
Bring hash dumping plugins up to current coding standards and error c…
2 parents 237ff92 + 3800ef3 commit 7ac9d02

File tree

3 files changed

+48
-23
lines changed

3 files changed

+48
-23
lines changed

volatility3/framework/plugins/windows/cachedump.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class Cachedump(interfaces.plugins.PluginInterface):
2222
"""Dumps lsa secrets from memory"""
2323

2424
_required_framework_version = (2, 0, 0)
25-
_version = (1, 0, 1)
25+
_version = (1, 0, 2)
2626

2727
@classmethod
2828
def get_requirements(cls):

volatility3/framework/plugins/windows/hashdump.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from Crypto.Cipher import AES, ARC4, DES
1111

12-
from volatility3.framework import interfaces, renderers
12+
from volatility3.framework import interfaces, renderers, exceptions
1313
from volatility3.framework.configuration import requirements
1414
from volatility3.framework.symbols.windows.extensions import registry
1515
from volatility3.plugins.windows.registry import hivelist
@@ -21,7 +21,7 @@ class Hashdump(interfaces.plugins.PluginInterface):
2121
"""Dumps user hashes from memory"""
2222

2323
_required_framework_version = (2, 0, 0)
24-
_version = (1, 1, 0)
24+
_version = (1, 1, 1)
2525

2626
@classmethod
2727
def get_requirements(cls):
@@ -326,7 +326,9 @@ def get_requirements(cls):
326326
empty_nt = b"\x31\xd6\xcf\xe0\xd1\x6a\xe9\x31\xb7\x3c\x59\xd7\xe0\xc0\x89\xc0"
327327

328328
@classmethod
329-
def get_hive_key(cls, hive: registry.RegistryHive, key: str):
329+
def get_hive_key(
330+
cls, hive: registry.RegistryHive, key: str
331+
) -> Optional["registry.CM_KEY_NODE"]:
330332
result = None
331333
try:
332334
if hive:
@@ -351,6 +353,9 @@ def get_user_keys(
351353

352354
@classmethod
353355
def get_bootkey(cls, syshive: registry.RegistryHive) -> Optional[bytes]:
356+
"""
357+
Returns the scrambled bootkey necesary to decrypt hashes
358+
"""
354359
cs = 1
355360
lsa_base = f"ControlSet{cs:03}" + "\\Control\\Lsa"
356361
lsa_keys = ["JD", "Skew1", "GBG", "Data"]
@@ -366,7 +371,10 @@ def get_bootkey(cls, syshive: registry.RegistryHive) -> Optional[bytes]:
366371
key = cls.get_hive_key(syshive, lsa_base + "\\" + lk)
367372
class_data = None
368373
if key:
369-
class_data = syshive.read(key.Class + 4, key.ClassLength)
374+
try:
375+
class_data = syshive.read(key.Class + 4, key.ClassLength)
376+
except exceptions.InvalidAddressException:
377+
return None
370378

371379
if class_data is None:
372380
return None
@@ -394,7 +402,11 @@ def get_hbootkey(
394402
sam_data = None
395403
for v in sam_account_key.get_values():
396404
if v.get_name() == "F":
397-
sam_data = samhive.read(v.Data + 4, v.DataLength)
405+
try:
406+
sam_data = samhive.read(v.Data + 4, v.DataLength)
407+
except exceptions.InvalidAddressException:
408+
return None
409+
398410
if not sam_data:
399411
return None
400412

@@ -444,7 +456,11 @@ def get_user_hashes(
444456
sam_data = None
445457
for v in user.get_values():
446458
if v.get_name() == "V":
447-
sam_data = samhive.read(v.Data + 4, v.DataLength)
459+
try:
460+
sam_data = samhive.read(v.Data + 4, v.DataLength)
461+
except exceptions.InvalidAddressException:
462+
return None
463+
448464
if not sam_data:
449465
return None
450466

@@ -546,7 +562,11 @@ def get_user_name(
546562
value = None
547563
for v in user.get_values():
548564
if v.get_name() == "V":
549-
value = samhive.read(v.Data + 4, v.DataLength)
565+
try:
566+
value = samhive.read(v.Data + 4, v.DataLength)
567+
except exceptions.InvalidAddressException:
568+
return None
569+
550570
if not value:
551571
return None
552572

volatility3/framework/plugins/windows/lsadump.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class Lsadump(interfaces.plugins.PluginInterface):
2222
"""Dumps lsa secrets from memory"""
2323

2424
_required_framework_version = (2, 0, 0)
25-
_version = (1, 0, 0)
25+
_version = (1, 0, 1)
2626

2727
@classmethod
2828
def get_requirements(cls):
@@ -76,8 +76,7 @@ def get_lsa_key(
7676
enc_reg_key = hashdump.Hashdump.get_hive_key(sechive, "Policy\\" + policy_key)
7777
if not enc_reg_key:
7878
return None
79-
enc_reg_value = next(enc_reg_key.get_values())
80-
79+
enc_reg_value = next(enc_reg_key.get_values(), None)
8180
if not enc_reg_value:
8281
return None
8382

@@ -112,18 +111,22 @@ def get_secret_by_name(
112111
name: str,
113112
lsakey: bytes,
114113
is_vista_or_later: bool,
115-
):
114+
) -> Optional[bytes]:
116115
enc_secret_key = hashdump.Hashdump.get_hive_key(
117116
sechive, "Policy\\Secrets\\" + name + "\\CurrVal"
118117
)
119118

120119
secret = None
121120
if enc_secret_key:
122-
enc_secret_value = next(enc_secret_key.get_values())
121+
enc_secret_value = next(enc_secret_key.get_values(), None)
123122
if enc_secret_value:
124-
enc_secret = sechive.read(
125-
enc_secret_value.Data + 4, enc_secret_value.DataLength
126-
)
123+
try:
124+
enc_secret = sechive.read(
125+
enc_secret_value.Data + 4, enc_secret_value.DataLength
126+
)
127+
except exceptions.InvalidAddressExceptions:
128+
return None
129+
127130
if enc_secret:
128131
if not is_vista_or_later:
129132
secret = cls.decrypt_secret(enc_secret[0xC:], lsakey)
@@ -133,7 +136,7 @@ def get_secret_by_name(
133136
return secret
134137

135138
@classmethod
136-
def decrypt_secret(cls, secret: bytes, key: bytes):
139+
def decrypt_secret(cls, secret: bytes, key: bytes) -> bytes:
137140
"""Python implementation of SystemFunction005.
138141
139142
Decrypts a block of data with DES using given key.
@@ -168,11 +171,11 @@ def _generator(
168171
)
169172

170173
bootkey = hashdump.Hashdump.get_bootkey(syshive)
171-
lsakey = self.get_lsa_key(sechive, bootkey, vista_or_later)
172174
if not bootkey:
173175
vollog.warning("Unable to find bootkey")
174176
return None
175177

178+
lsakey = self.get_lsa_key(sechive, bootkey, vista_or_later)
176179
if not lsakey:
177180
vollog.warning("Unable to find lsa key")
178181
return None
@@ -190,15 +193,17 @@ def _generator(
190193
if not sec_val_key:
191194
continue
192195

193-
enc_secret_value = next(sec_val_key.get_values())
196+
enc_secret_value = next(sec_val_key.get_values(), None)
194197
if not enc_secret_value:
195198
continue
196199

197-
enc_secret = sechive.read(
198-
enc_secret_value.Data + 4, enc_secret_value.DataLength
199-
)
200-
if not enc_secret:
200+
try:
201+
enc_secret = sechive.read(
202+
enc_secret_value.Data + 4, enc_secret_value.DataLength
203+
)
204+
except exceptions.InvalidAddressExceptions:
201205
continue
206+
202207
if not vista_or_later:
203208
secret = self.decrypt_secret(enc_secret[0xC:], lsakey)
204209
else:

0 commit comments

Comments
 (0)