dissect.target 3.17.dev35__py3-none-any.whl → 3.17.dev37__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dissect/target/helpers/record_modifier.py +4 -1
- dissect/target/plugins/apps/browser/firefox.py +72 -0
- dissect/target/plugins/os/windows/regf/runkeys.py +6 -4
- {dissect.target-3.17.dev35.dist-info → dissect.target-3.17.dev37.dist-info}/METADATA +2 -2
- {dissect.target-3.17.dev35.dist-info → dissect.target-3.17.dev37.dist-info}/RECORD +10 -10
- {dissect.target-3.17.dev35.dist-info → dissect.target-3.17.dev37.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.17.dev35.dist-info → dissect.target-3.17.dev37.dist-info}/LICENSE +0 -0
- {dissect.target-3.17.dev35.dist-info → dissect.target-3.17.dev37.dist-info}/WHEEL +0 -0
- {dissect.target-3.17.dev35.dist-info → dissect.target-3.17.dev37.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.17.dev35.dist-info → dissect.target-3.17.dev37.dist-info}/top_level.txt +0 -0
@@ -62,13 +62,16 @@ MODIFIER_MAPPING = {
|
|
62
62
|
|
63
63
|
def _resolve_path_types(target: Target, record: Record) -> Iterator[tuple[str, TargetPath]]:
|
64
64
|
for field_name, field_type in record._field_types.items():
|
65
|
-
if not issubclass(field_type, fieldtypes.path):
|
65
|
+
if not issubclass(field_type, (fieldtypes.path, fieldtypes.command)):
|
66
66
|
continue
|
67
67
|
|
68
68
|
path = getattr(record, field_name, None)
|
69
69
|
if path is None:
|
70
70
|
continue
|
71
71
|
|
72
|
+
if isinstance(path, fieldtypes.command):
|
73
|
+
path = path.executable
|
74
|
+
|
72
75
|
yield field_name, target.resolve(str(path))
|
73
76
|
|
74
77
|
|
@@ -18,6 +18,7 @@ from dissect.target.plugin import export
|
|
18
18
|
from dissect.target.plugins.apps.browser.browser import (
|
19
19
|
GENERIC_COOKIE_FIELDS,
|
20
20
|
GENERIC_DOWNLOAD_RECORD_FIELDS,
|
21
|
+
GENERIC_EXTENSION_RECORD_FIELDS,
|
21
22
|
GENERIC_HISTORY_RECORD_FIELDS,
|
22
23
|
GENERIC_PASSWORD_RECORD_FIELDS,
|
23
24
|
BrowserPlugin,
|
@@ -43,6 +44,7 @@ try:
|
|
43
44
|
except ImportError:
|
44
45
|
HAS_CRYPTO = False
|
45
46
|
|
47
|
+
FIREFOX_EXTENSION_RECORD_FIELDS = [("uri", "source_uri"), ("string[]", "optional_permissions")]
|
46
48
|
|
47
49
|
log = logging.getLogger(__name__)
|
48
50
|
|
@@ -76,6 +78,10 @@ class FirefoxPlugin(BrowserPlugin):
|
|
76
78
|
"browser/firefox/download", GENERIC_DOWNLOAD_RECORD_FIELDS
|
77
79
|
)
|
78
80
|
|
81
|
+
BrowserExtensionRecord = create_extended_descriptor([UserRecordDescriptorExtension])(
|
82
|
+
"browser/firefox/extension", GENERIC_EXTENSION_RECORD_FIELDS + FIREFOX_EXTENSION_RECORD_FIELDS
|
83
|
+
)
|
84
|
+
|
79
85
|
BrowserPasswordRecord = create_extended_descriptor([UserRecordDescriptorExtension])(
|
80
86
|
"browser/firefox/password", GENERIC_PASSWORD_RECORD_FIELDS
|
81
87
|
)
|
@@ -305,6 +311,72 @@ class FirefoxPlugin(BrowserPlugin):
|
|
305
311
|
except SQLError as e:
|
306
312
|
self.target.log.warning("Error processing history file: %s", db_file, exc_info=e)
|
307
313
|
|
314
|
+
@export(record=BrowserExtensionRecord)
|
315
|
+
def extensions(self) -> Iterator[BrowserExtensionRecord]:
|
316
|
+
"""Return browser extension records for Firefox.
|
317
|
+
|
318
|
+
Yields BrowserExtensionRecord with the following fields::
|
319
|
+
ts_install (datetime): Extension install timestamp.
|
320
|
+
ts_update (datetime): Extension update timestamp.
|
321
|
+
browser (string): The browser from which the records are generated.
|
322
|
+
id (string): Extension unique identifier.
|
323
|
+
name (string): Name of the extension.
|
324
|
+
short_name (string): Short name of the extension.
|
325
|
+
default_title (string): Default title of the extension.
|
326
|
+
description (string): Description of the extension.
|
327
|
+
version (string): Version of the extension.
|
328
|
+
ext_path (path): Relative path of the extension.
|
329
|
+
from_webstore (boolean): Extension from webstore.
|
330
|
+
permissions (string[]): Permissions of the extension.
|
331
|
+
manifest (varint): Version of the extensions' manifest.
|
332
|
+
optional_permissions (string[]): Optional permissions of the extension.
|
333
|
+
source_uri (path): Source path from which the extension was downloaded.
|
334
|
+
source (path): The source file of the download record.
|
335
|
+
"""
|
336
|
+
for user, _, profile_dir in self._iter_profiles():
|
337
|
+
extension_file = profile_dir.joinpath("extensions.json")
|
338
|
+
|
339
|
+
if not extension_file.exists():
|
340
|
+
self.target.log.warning(
|
341
|
+
"No 'extensions.json' addon file found for user %s in directory %s", user, profile_dir
|
342
|
+
)
|
343
|
+
continue
|
344
|
+
|
345
|
+
try:
|
346
|
+
extensions = json.load(extension_file.open())
|
347
|
+
|
348
|
+
for extension in extensions.get("addons", []):
|
349
|
+
yield self.BrowserExtensionRecord(
|
350
|
+
ts_install=extension.get("installDate", 0) // 1000,
|
351
|
+
ts_update=extension.get("updateDate", 0) // 1000,
|
352
|
+
browser="firefox",
|
353
|
+
id=extension.get("id"),
|
354
|
+
name=extension.get("defaultLocale", {}).get("name"),
|
355
|
+
short_name=None,
|
356
|
+
default_title=None,
|
357
|
+
description=extension.get("defaultLocale", {}).get("description"),
|
358
|
+
version=extension.get("version"),
|
359
|
+
ext_path=extension.get("path"),
|
360
|
+
from_webstore=None,
|
361
|
+
permissions=extension.get("userPermissions", {}).get("permissions"),
|
362
|
+
manifest_version=extension.get("manifestVersion"),
|
363
|
+
source_uri=extension.get("sourceURI"),
|
364
|
+
optional_permissions=extension.get("optionalPermissions", {}).get("permissions"),
|
365
|
+
source=extension_file,
|
366
|
+
_target=self.target,
|
367
|
+
_user=user.user,
|
368
|
+
)
|
369
|
+
|
370
|
+
except FileNotFoundError:
|
371
|
+
self.target.log.info(
|
372
|
+
"No 'extensions.json' addon file found for user %s in directory %s", user, profile_dir
|
373
|
+
)
|
374
|
+
except json.JSONDecodeError:
|
375
|
+
self.target.log.warning(
|
376
|
+
"extensions.json file in directory %s is malformed, consider inspecting the file manually",
|
377
|
+
profile_dir,
|
378
|
+
)
|
379
|
+
|
308
380
|
@export(record=BrowserPasswordRecord)
|
309
381
|
def passwords(self) -> Iterator[BrowserPasswordRecord]:
|
310
382
|
"""Return Firefox browser password records.
|
@@ -1,3 +1,5 @@
|
|
1
|
+
from typing import Iterator
|
2
|
+
|
1
3
|
from dissect.target.exceptions import UnsupportedPluginError
|
2
4
|
from dissect.target.helpers.descriptor_extensions import (
|
3
5
|
RegistryRecordDescriptorExtension,
|
@@ -11,7 +13,7 @@ RunKeyRecord = create_extended_descriptor([RegistryRecordDescriptorExtension, Us
|
|
11
13
|
[
|
12
14
|
("datetime", "ts"),
|
13
15
|
("wstring", "name"),
|
14
|
-
("
|
16
|
+
("command", "command"),
|
15
17
|
("string", "key"),
|
16
18
|
],
|
17
19
|
)
|
@@ -48,7 +50,7 @@ class RunKeysPlugin(Plugin):
|
|
48
50
|
raise UnsupportedPluginError("No registry run key found")
|
49
51
|
|
50
52
|
@export(record=RunKeyRecord)
|
51
|
-
def runkeys(self):
|
53
|
+
def runkeys(self) -> Iterator[RunKeyRecord]:
|
52
54
|
"""Iterate various run key locations. See source for all locations.
|
53
55
|
|
54
56
|
Run keys (Run and RunOnce) are registry keys that make a program run when a user logs on. a Run key runs every
|
@@ -63,7 +65,7 @@ class RunKeysPlugin(Plugin):
|
|
63
65
|
domain (string): The target domain.
|
64
66
|
ts (datetime): The registry key last modified timestamp.
|
65
67
|
name (string): The run key name.
|
66
|
-
|
68
|
+
command (command): The run key command.
|
67
69
|
key (string): The source key for this run key.
|
68
70
|
"""
|
69
71
|
for key in self.KEYS:
|
@@ -73,7 +75,7 @@ class RunKeysPlugin(Plugin):
|
|
73
75
|
yield RunKeyRecord(
|
74
76
|
ts=r.ts,
|
75
77
|
name=entry.name,
|
76
|
-
|
78
|
+
command=entry.value,
|
77
79
|
key=key,
|
78
80
|
_target=self.target,
|
79
81
|
_key=r,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: dissect.target
|
3
|
-
Version: 3.17.
|
3
|
+
Version: 3.17.dev37
|
4
4
|
Summary: This module ties all other Dissect modules together, it provides a programming API and command line tools which allow easy access to various data sources inside disk images or file collections (a.k.a. targets)
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
6
6
|
License: Affero General Public License v3
|
@@ -31,7 +31,7 @@ Requires-Dist: dissect.ntfs <4.0.dev,>=3.4.dev
|
|
31
31
|
Requires-Dist: dissect.regf <4.0.dev,>=3.3.dev
|
32
32
|
Requires-Dist: dissect.util <4.0.dev,>=3.0.dev
|
33
33
|
Requires-Dist: dissect.volume <4.0.dev,>=3.0.dev
|
34
|
-
Requires-Dist: flow.record ~=3.
|
34
|
+
Requires-Dist: flow.record ~=3.15.0
|
35
35
|
Requires-Dist: structlog
|
36
36
|
Provides-Extra: cb
|
37
37
|
Requires-Dist: dissect.target[full] ; extra == 'cb'
|
@@ -62,7 +62,7 @@ dissect/target/helpers/network_managers.py,sha256=uRh_P8ICbKke2N7eFJ6AS2-I5DmIRi
|
|
62
62
|
dissect/target/helpers/polypath.py,sha256=h8p7m_OCNiQljGwoZh5Aflr9H2ot6CZr6WKq1OSw58o,2175
|
63
63
|
dissect/target/helpers/protobuf.py,sha256=NwKrZD4q9v7J8GnZX9gbzMUMV5pR78eAV17jgWOz_EY,1730
|
64
64
|
dissect/target/helpers/record.py,sha256=lWl7k2Mp9Axllm0tXzPGJx2zj2zONsyY_p5g424T0Lc,4826
|
65
|
-
dissect/target/helpers/record_modifier.py,sha256=
|
65
|
+
dissect/target/helpers/record_modifier.py,sha256=3I_rC5jqvl0TsW3V8OQ6Dltz_D8J4PU1uhhzbJGKm9c,3245
|
66
66
|
dissect/target/helpers/regutil.py,sha256=kX-sSZbW8Qkg29Dn_9zYbaQrwLumrr4Y8zJ1EhHXIAM,27337
|
67
67
|
dissect/target/helpers/shell_folder_ids.py,sha256=Behhb8oh0kMxrEk6YYKYigCDZe8Hw5QS6iK_d2hTs2Y,24978
|
68
68
|
dissect/target/helpers/ssh.py,sha256=LPssHXyfL8QYmLi2vpa3wElsGboLG_A1Y8kvOehpUr4,6338
|
@@ -124,7 +124,7 @@ dissect/target/plugins/apps/browser/browser.py,sha256=rBIwcgdl73gm-8APwx2jEUAYXR
|
|
124
124
|
dissect/target/plugins/apps/browser/chrome.py,sha256=hxS8gqpBwoCrPaxNpllIa6K9DtsSGzn6XXcUaHyes6w,3048
|
125
125
|
dissect/target/plugins/apps/browser/chromium.py,sha256=1oaQhMN5mJysw0VIVpTEmRCAifgv-mUQxZwrGmGHqAQ,27875
|
126
126
|
dissect/target/plugins/apps/browser/edge.py,sha256=woXzZtHPWmfcV8vbxGKHELKru5JRb32MAXs43_b4K4E,2883
|
127
|
-
dissect/target/plugins/apps/browser/firefox.py,sha256=
|
127
|
+
dissect/target/plugins/apps/browser/firefox.py,sha256=Msicw-13AJWbXRRF6m_p4L84rXAjsIYGFRve29cPY2M,30806
|
128
128
|
dissect/target/plugins/apps/browser/iexplore.py,sha256=MqMonoaM5lj0ZFqGwS4F-P1eLmnLvX7VQGE9S3hxXag,8739
|
129
129
|
dissect/target/plugins/apps/container/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
130
130
|
dissect/target/plugins/apps/container/docker.py,sha256=67Eih9AfUbqsP-HlnlwoHi4rSAnVCZWM76sEyO_1m18,15316
|
@@ -307,7 +307,7 @@ dissect/target/plugins/os/windows/regf/muicache.py,sha256=qoA7S8SiZakIreQqxc_QH1
|
|
307
307
|
dissect/target/plugins/os/windows/regf/nethist.py,sha256=QHbG9fmZNmjSVhrgqMvMo12YBaQedzeToS7ZD9eIJ28,3111
|
308
308
|
dissect/target/plugins/os/windows/regf/recentfilecache.py,sha256=Wr6u7SajA9BtUiypztak9ASJZuimOtWfQUAlfvskjMg,1838
|
309
309
|
dissect/target/plugins/os/windows/regf/regf.py,sha256=IbLnOurtlprXAo12iYRdw6fv5J45SuMAqt-mXVYaZi4,3357
|
310
|
-
dissect/target/plugins/os/windows/regf/runkeys.py,sha256=
|
310
|
+
dissect/target/plugins/os/windows/regf/runkeys.py,sha256=f10jOPTJlUVDEhSiH9JSltKQ-V7zfa8iPX0nKl1gBXo,4247
|
311
311
|
dissect/target/plugins/os/windows/regf/shellbags.py,sha256=EKBWBjxvSfxc7WFKmICZs8QUJnjhsCKesjl_NHEnSUo,25621
|
312
312
|
dissect/target/plugins/os/windows/regf/shimcache.py,sha256=4SHtwh-ajhgcyR2-vsBbjnsyBtEVPwlgk5j8e1TQkWM,9972
|
313
313
|
dissect/target/plugins/os/windows/regf/trusteddocs.py,sha256=4g4m1FYljOpYqGG-7NGyj738Tfnz0uEaN2is2YzkMgg,3669
|
@@ -340,10 +340,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z
|
|
340
340
|
dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
|
341
341
|
dissect/target/volumes/md.py,sha256=j1K1iKmspl0C_OJFc7-Q1BMWN2OCC5EVANIgVlJ_fIE,1673
|
342
342
|
dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
|
343
|
-
dissect.target-3.17.
|
344
|
-
dissect.target-3.17.
|
345
|
-
dissect.target-3.17.
|
346
|
-
dissect.target-3.17.
|
347
|
-
dissect.target-3.17.
|
348
|
-
dissect.target-3.17.
|
349
|
-
dissect.target-3.17.
|
343
|
+
dissect.target-3.17.dev37.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
|
344
|
+
dissect.target-3.17.dev37.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
345
|
+
dissect.target-3.17.dev37.dist-info/METADATA,sha256=lG1EhM84cgxqVPODtlB_Ruvy2WmoUgjrea3a9pSWu20,11300
|
346
|
+
dissect.target-3.17.dev37.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
347
|
+
dissect.target-3.17.dev37.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
|
348
|
+
dissect.target-3.17.dev37.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
|
349
|
+
dissect.target-3.17.dev37.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
{dissect.target-3.17.dev35.dist-info → dissect.target-3.17.dev37.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|