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.
@@ -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
- ("string", "path"),
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
- path (string): The run key path.
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
- path=entry.value,
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.dev35
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.14.0
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=BiZ_gtqVxuByLWrga1lfglk3X-TcMrJC0quxPpXoIRo,3138
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=Y8QdSgPZktYy4IF36aI1Jfbw_ucysx82PNljnyUCmRY,27025
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=qX-6xOrgBq7_B00C1BoQtI0Ovzou6Sx3XemV0Ra4JMs,4178
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.dev35.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
344
- dissect.target-3.17.dev35.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
345
- dissect.target-3.17.dev35.dist-info/METADATA,sha256=Dd4TxlQKuWjqnUY6nMqiEvR-YBsmXIbhGN6CLjdsGhI,11300
346
- dissect.target-3.17.dev35.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
347
- dissect.target-3.17.dev35.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
348
- dissect.target-3.17.dev35.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
349
- dissect.target-3.17.dev35.dist-info/RECORD,,
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,,