dissect.target 3.17.dev35__py3-none-any.whl → 3.17.dev36__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dissect.target
3
- Version: 3.17.dev35
3
+ Version: 3.17.dev36
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
@@ -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
@@ -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.dev36.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
344
+ dissect.target-3.17.dev36.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
345
+ dissect.target-3.17.dev36.dist-info/METADATA,sha256=jvQ5nLWplAsNNZMyR1nIBwBQZEe-FnQRkk56_YpDAtw,11300
346
+ dissect.target-3.17.dev36.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
347
+ dissect.target-3.17.dev36.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
348
+ dissect.target-3.17.dev36.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
349
+ dissect.target-3.17.dev36.dist-info/RECORD,,