Skip to content

Commit a607448

Browse files
committed
Process review feedback
1 parent 4e90d7d commit a607448

File tree

2 files changed

+25
-28
lines changed

2 files changed

+25
-28
lines changed

dissect/target/plugins/os/windows/catroot.py

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
from binascii import hexlify
21
from collections import defaultdict, namedtuple
32
from enum import Enum
4-
from typing import Optional
3+
from typing import Optional, Iterator
54

65
from asn1crypto.cms import ContentInfo
76
from asn1crypto.core import Sequence
@@ -41,7 +40,7 @@ class CatrootFileType(str, Enum):
4140
CatrootFileInfo = namedtuple("CatrootFileInfo", ["file_type", "pattern", "base_path"])
4241

4342

44-
def findall(buf, needle):
43+
def findall(buf: bytes, needle: bytes) -> Iterator[int]:
4544
offset = 0
4645
while True:
4746
offset = buf.find(needle, offset)
@@ -101,7 +100,7 @@ def check_compatible(self) -> None:
101100
raise UnsupportedPluginError("No catroot files or catroot ESE files found")
102101

103102
@export(record=CatrootRecord)
104-
def files(self):
103+
def files(self) -> Iterator[CatrootRecord]:
105104
"""Return the content of the catalog files in the CatRoot folder.
106105
107106
A catalog file contains a collection of cryptographic hashes, or thumbprints. These files are generally used to
@@ -114,8 +113,8 @@ def files(self):
114113
Yields CatrootRecords with the following fields:
115114
hostname (string): The target hostname.
116115
domain (string): The target domain.
117-
digest (digest): The parsed digest.
118-
hint (string): File hint, if present.
116+
digests (digest[]): The parsed digests.
117+
hints (string[]): File hints, if present.
119118
filename (string): catroot filename.
120119
source (path): Source catroot file.
121120
"""
@@ -165,31 +164,29 @@ def files(self):
165164
# the format is not yet known and therefore not supported.
166165
hints = []
167166
try:
168-
# As far as known, the hint data is only present in the encap_content_info after the last digest.
169-
hint_buf = encap_contents[offset + len(needle) + len(raw_digest) + 2 :]
167+
if offset:
168+
# As far as known, the PackageName data is only present in the encap_content_info after the last digest.
169+
hint_buf = encap_contents[offset + len(needle) + len(raw_digest) + 2 :]
170170

171-
# First try to find to find the "PackageName" value, if it's present.
172-
hint = find_package_name(hint_buf)
173-
if hint:
174-
hints.append(hint)
171+
# First try to find to find the "PackageName" value, if it's present.
172+
hint = find_package_name(hint_buf)
173+
if hint:
174+
hints.append(hint)
175175

176-
# If the package_name needle is not found or it's present in the first 7 bytes of the hint_buf
177-
# We are dealing with a catroot file including a file hint.
176+
# If the package_name needle is not found or it's not present in the first 7 bytes of the hint_buf
177+
# We are probably dealing with a catroot file that contains "hint" needle.
178178
if not hints:
179179
for hint_offset in findall(encap_contents, NEEDLES["hint"]):
180180
# Either 3 or 4 bytes before the needle, a sequence starts
181-
if encap_contents[hint_offset - 3] == 48:
182-
name_sequence = Sequence.load(encap_contents[hint_offset - 3 :])
183-
else:
184-
name_sequence = Sequence.load(encap_contents[hint_offset - 4 :])
181+
bytes_before_needle = 3 if encap_contents[hint_offset - 3] == 48 else 4
182+
name_sequence = Sequence.load(encap_contents[hint_offset - bytes_before_needle :])
185183

186184
hint = name_sequence[2].native.decode("utf-16-le").strip("\x00")
187185
hints.append(hint)
188-
self.target.log.error(f"{hint} - {file}")
189186

190187
except Exception as error:
191188
self.target.log.warning(
192-
f"An error occurred while parsing the hint for catroot file '{file}': {error}"
189+
f"An error occurred while parsing the hint for catroot file %s: %s", file, error
193190
)
194191

195192
yield CatrootRecord(
@@ -201,13 +198,13 @@ def files(self):
201198
)
202199

203200
except Exception as error:
204-
self.target.log.error(f"An error occurred while parsing the catroot file '{file}': {error}")
201+
self.target.log.error(f"An error occurred while parsing the catroot file %s: %s", file, error)
205202

206203
@export(record=CatrootRecord)
207-
def catdb(self):
204+
def catdb(self) -> Iterator[CatrootRecord]:
208205
"""Return the hash values present in the catdb files in the catroot2 folder.
209206
210-
The catdb file is a ESE database file that contains the digests of the catalog files present on the system.
207+
The catdb file is an ESE database file that contains the digests of the catalog files present on the system.
211208
This database is used to speed up the process of validating a Portable Executable (PE) file.
212209
213210
References:
@@ -217,8 +214,8 @@ def catdb(self):
217214
Yields CatrootRecords with the following fields:
218215
hostname (string): The target hostname.
219216
domain (string): The target domain.
220-
digest (digest): The parsed digest.
221-
hint (string): File hint, if present.
217+
digests (digest[]): The parsed digests.
218+
hints (string[]): File hints, if present.
222219
filename (string): catroot filename.
223220
source (path): Source catroot file.
224221
"""
@@ -235,7 +232,7 @@ def catdb(self):
235232

236233
for record in ese_db.table(table_name).records():
237234
file_digest = digest()
238-
setattr(file_digest, hash_type, hexlify(record.get("HashCatNameTable_HashCol")).decode("utf-8"))
235+
setattr(file_digest, hash_type, record.get("HashCatNameTable_HashCol").hex())
239236
raw_hint = record.get("HashCatNameTable_CatNameCol").decode("utf-8").rstrip("|")
240237
# Group by raw_hint to get one record per raw_hint containing all digests (SHA256, SHA1)
241238
catroot_records[raw_hint].append(file_digest)

tests/plugins/os/windows/test_catroot.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
)
6161
def test_catroot_files(
6262
target_win: Target, fs_win: VirtualFilesystem, filename: str, hashes: list[str], file_hints: list[str]
63-
):
63+
) -> None:
6464
catroot_file = absolute_path(f"_data/plugins/os/windows/catroot/{filename}")
6565
file_location = f"\\windows\\system32\\catroot\\test\\{filename}"
6666
fs_win.map_file(
@@ -84,7 +84,7 @@ def test_catroot_files(
8484
assert record_hash.sha256 == cat_hash
8585

8686

87-
def test_catroot_catdb(target_win: Target, fs_win: VirtualFilesystem):
87+
def test_catroot_catdb(target_win: Target, fs_win: VirtualFilesystem) -> None:
8888
catroot_file = absolute_path("_data/plugins/os/windows/catroot/catdb")
8989
fs_win.map_file("windows/system32/catroot2/{ID}/catdb", catroot_file)
9090

0 commit comments

Comments
 (0)