dissect.target 3.20.dev36__py3-none-any.whl → 3.20.dev38__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. dissect/target/filesystems/config.py +1 -1
  2. dissect/target/helpers/compat/path_common.py +5 -5
  3. dissect/target/helpers/configutil.py +31 -29
  4. dissect/target/helpers/cyber.py +2 -0
  5. dissect/target/helpers/docs.py +1 -1
  6. dissect/target/helpers/keychain.py +2 -0
  7. dissect/target/helpers/mount.py +2 -1
  8. dissect/target/plugin.py +15 -13
  9. dissect/target/plugins/apps/av/mcafee.py +2 -0
  10. dissect/target/plugins/apps/av/sophos.py +2 -0
  11. dissect/target/plugins/apps/av/trendmicro.py +2 -0
  12. dissect/target/plugins/apps/browser/chromium.py +27 -6
  13. dissect/target/plugins/apps/shell/powershell.py +6 -2
  14. dissect/target/plugins/apps/shell/wget.py +1 -1
  15. dissect/target/plugins/apps/ssh/openssh.py +2 -0
  16. dissect/target/plugins/apps/ssh/opensshd.py +2 -0
  17. dissect/target/plugins/apps/vpn/wireguard.py +9 -9
  18. dissect/target/plugins/apps/webhosting/cpanel.py +2 -0
  19. dissect/target/plugins/apps/webserver/caddy.py +2 -0
  20. dissect/target/plugins/apps/webserver/nginx.py +2 -0
  21. dissect/target/plugins/child/esxi.py +3 -1
  22. dissect/target/plugins/child/virtuozzo.py +12 -8
  23. dissect/target/plugins/filesystem/acquire_hash.py +2 -1
  24. dissect/target/plugins/filesystem/icat.py +15 -11
  25. dissect/target/plugins/filesystem/ntfs/mft.py +2 -0
  26. dissect/target/plugins/filesystem/ntfs/mft_timeline.py +3 -1
  27. dissect/target/plugins/filesystem/ntfs/usnjrnl.py +2 -0
  28. dissect/target/plugins/filesystem/ntfs/utils.py +3 -1
  29. dissect/target/plugins/filesystem/unix/suid.py +4 -1
  30. dissect/target/plugins/filesystem/walkfs.py +2 -0
  31. dissect/target/plugins/general/example.py +2 -2
  32. dissect/target/plugins/general/loaders.py +1 -1
  33. dissect/target/plugins/general/network.py +7 -0
  34. dissect/target/plugins/general/osinfo.py +1 -0
  35. dissect/target/plugins/general/plugins.py +4 -0
  36. dissect/target/plugins/os/unix/_os.py +2 -1
  37. dissect/target/plugins/os/unix/bsd/citrix/history.py +2 -0
  38. dissect/target/plugins/os/unix/bsd/osx/network.py +2 -0
  39. dissect/target/plugins/os/unix/bsd/osx/user.py +4 -0
  40. dissect/target/plugins/os/unix/cronjobs.py +8 -4
  41. dissect/target/plugins/os/unix/etc/etc.py +4 -0
  42. dissect/target/plugins/os/unix/generic.py +2 -0
  43. dissect/target/plugins/os/unix/history.py +27 -25
  44. dissect/target/plugins/os/unix/linux/cmdline.py +2 -0
  45. dissect/target/plugins/os/unix/linux/debian/apt.py +4 -1
  46. dissect/target/plugins/os/unix/linux/debian/dpkg.py +3 -3
  47. dissect/target/plugins/os/unix/linux/environ.py +2 -0
  48. dissect/target/plugins/os/unix/linux/fortios/generic.py +2 -0
  49. dissect/target/plugins/os/unix/linux/fortios/locale.py +2 -0
  50. dissect/target/plugins/os/unix/linux/modules.py +2 -0
  51. dissect/target/plugins/os/unix/linux/netstat.py +2 -0
  52. dissect/target/plugins/os/unix/linux/processes.py +2 -0
  53. dissect/target/plugins/os/unix/linux/redhat/yum.py +4 -1
  54. dissect/target/plugins/os/unix/linux/services.py +5 -3
  55. dissect/target/plugins/os/unix/linux/sockets.py +2 -0
  56. dissect/target/plugins/os/unix/linux/suse/zypper.py +4 -1
  57. dissect/target/plugins/os/unix/locale.py +2 -0
  58. dissect/target/plugins/os/unix/locate/gnulocate.py +4 -2
  59. dissect/target/plugins/os/unix/locate/mlocate.py +2 -0
  60. dissect/target/plugins/os/unix/locate/plocate.py +3 -1
  61. dissect/target/plugins/os/unix/log/atop.py +2 -0
  62. dissect/target/plugins/os/unix/log/audit.py +3 -1
  63. dissect/target/plugins/os/unix/log/auth.py +4 -2
  64. dissect/target/plugins/os/unix/log/lastlog.py +5 -3
  65. dissect/target/plugins/os/unix/log/messages.py +2 -0
  66. dissect/target/plugins/os/unix/log/utmp.py +4 -2
  67. dissect/target/plugins/os/unix/packagemanager.py +4 -37
  68. dissect/target/plugins/os/unix/shadow.py +3 -1
  69. dissect/target/plugins/os/unix/trash.py +1 -1
  70. dissect/target/plugins/os/windows/activitiescache.py +9 -4
  71. dissect/target/plugins/os/windows/adpolicy.py +2 -1
  72. dissect/target/plugins/os/windows/amcache.py +16 -13
  73. dissect/target/plugins/os/windows/defender.py +3 -3
  74. dissect/target/plugins/os/windows/dpapi/keyprovider/credhist.py +3 -0
  75. dissect/target/plugins/os/windows/dpapi/keyprovider/empty.py +3 -0
  76. dissect/target/plugins/os/windows/dpapi/keyprovider/keychain.py +3 -0
  77. dissect/target/plugins/os/windows/dpapi/keyprovider/lsa.py +3 -0
  78. dissect/target/plugins/os/windows/env.py +1 -2
  79. dissect/target/plugins/os/windows/exchange/exchange.py +6 -4
  80. dissect/target/plugins/os/windows/generic.py +20 -18
  81. dissect/target/plugins/os/windows/lnk.py +2 -0
  82. dissect/target/plugins/os/windows/locale.py +9 -3
  83. dissect/target/plugins/os/windows/log/etl.py +5 -4
  84. dissect/target/plugins/os/windows/log/evt.py +12 -8
  85. dissect/target/plugins/os/windows/log/evtx.py +9 -7
  86. dissect/target/plugins/os/windows/log/pfro.py +2 -1
  87. dissect/target/plugins/os/windows/network.py +2 -0
  88. dissect/target/plugins/os/windows/notifications.py +6 -4
  89. dissect/target/plugins/os/windows/prefetch.py +7 -2
  90. dissect/target/plugins/os/windows/regf/7zip.py +9 -1
  91. dissect/target/plugins/os/windows/regf/auditpol.py +2 -1
  92. dissect/target/plugins/os/windows/regf/bam.py +3 -1
  93. dissect/target/plugins/os/windows/regf/cit.py +14 -12
  94. dissect/target/plugins/os/windows/regf/clsid.py +6 -3
  95. dissect/target/plugins/os/windows/regf/firewall.py +2 -1
  96. dissect/target/plugins/os/windows/regf/mru.py +9 -8
  97. dissect/target/plugins/os/windows/regf/nethist.py +6 -3
  98. dissect/target/plugins/os/windows/regf/recentfilecache.py +3 -1
  99. dissect/target/plugins/os/windows/regf/regf.py +5 -1
  100. dissect/target/plugins/os/windows/regf/shimcache.py +1 -1
  101. dissect/target/plugins/os/windows/regf/usb.py +2 -1
  102. dissect/target/plugins/os/windows/regf/userassist.py +2 -1
  103. dissect/target/plugins/os/windows/registry.py +11 -0
  104. dissect/target/plugins/os/windows/services.py +3 -2
  105. dissect/target/plugins/os/windows/startupinfo.py +7 -2
  106. dissect/target/plugins/os/windows/syscache.py +3 -1
  107. dissect/target/plugins/os/windows/tasks.py +1 -1
  108. dissect/target/plugins/os/windows/thumbcache.py +11 -5
  109. dissect/target/plugins/os/windows/ual.py +12 -9
  110. dissect/target/plugins/os/windows/wua_history.py +0 -1
  111. dissect/target/tools/dump/utils.py +4 -0
  112. dissect/target/tools/shell.py +2 -1
  113. {dissect.target-3.20.dev36.dist-info → dissect.target-3.20.dev38.dist-info}/METADATA +1 -1
  114. {dissect.target-3.20.dev36.dist-info → dissect.target-3.20.dev38.dist-info}/RECORD +119 -120
  115. dissect/target/plugins/os/unix/etc.py +0 -9
  116. {dissect.target-3.20.dev36.dist-info → dissect.target-3.20.dev38.dist-info}/COPYRIGHT +0 -0
  117. {dissect.target-3.20.dev36.dist-info → dissect.target-3.20.dev38.dist-info}/LICENSE +0 -0
  118. {dissect.target-3.20.dev36.dist-info → dissect.target-3.20.dev38.dist-info}/WHEEL +0 -0
  119. {dissect.target-3.20.dev36.dist-info → dissect.target-3.20.dev38.dist-info}/entry_points.txt +0 -0
  120. {dissect.target-3.20.dev36.dist-info → dissect.target-3.20.dev38.dist-info}/top_level.txt +0 -0
@@ -68,6 +68,10 @@ class RegistryPlugin(Plugin):
68
68
  "COMPONENTS",
69
69
  "DEFAULT",
70
70
  "ELAM",
71
+ "USER.DAT", # Win 95/98/ME
72
+ "SYSTEM.DAT", # Win 95/98/ME
73
+ "CLASSES.DAT", # Win ME
74
+ "REG.DAT", # Win 3.1
71
75
  ]
72
76
 
73
77
  def __init__(self, target: Target) -> None:
@@ -88,7 +92,14 @@ class RegistryPlugin(Plugin):
88
92
 
89
93
  def _init_registry(self) -> None:
90
94
  dirs = [
95
+ # Windows XP or newer
91
96
  ("sysvol/windows/system32/config", False),
97
+ # Windows NT3, NT4, 2k
98
+ ("sysvol/WINNT/system32/config", False),
99
+ # Windows 3.11, 95, 98, ME
100
+ ("sysvol/windows", False),
101
+ # ReactOS (alternative location)
102
+ ("sysvol/reactos", False),
92
103
  # RegBack hives are often empty files
93
104
  ("sysvol/windows/system32/config/RegBack", True),
94
105
  ]
@@ -1,4 +1,5 @@
1
1
  import re
2
+ from typing import Iterator
2
3
 
3
4
  from dissect.target.exceptions import (
4
5
  RegistryError,
@@ -62,8 +63,8 @@ class ServicesPlugin(Plugin):
62
63
  raise UnsupportedPluginError("No services found in the registry")
63
64
 
64
65
  @export(record=ServiceRecord)
65
- def services(self):
66
- """Return information about all installed services.
66
+ def services(self) -> Iterator[ServiceRecord]:
67
+ """Return information about all installed Windows services.
67
68
 
68
69
  The HKLM\\SYSTEM\\CurrentControlSet\\Services registry key contains information about the installed services and
69
70
  drivers on the system.
@@ -1,4 +1,7 @@
1
+ from __future__ import annotations
2
+
1
3
  import datetime
4
+ from typing import Iterator
2
5
 
3
6
  from defusedxml import ElementTree
4
7
 
@@ -34,7 +37,7 @@ StartupInfoRecord = TargetRecordDescriptor(
34
37
  )
35
38
 
36
39
 
37
- def parse_ts(time_string):
40
+ def parse_ts(time_string: str) -> datetime.datetime | None:
38
41
  if not time_string:
39
42
  return None
40
43
 
@@ -42,6 +45,8 @@ def parse_ts(time_string):
42
45
 
43
46
 
44
47
  class StartupInfoPlugin(Plugin):
48
+ """Windows startup info plugin."""
49
+
45
50
  def __init__(self, target):
46
51
  super().__init__(target)
47
52
  self._files = []
@@ -55,7 +60,7 @@ class StartupInfoPlugin(Plugin):
55
60
  raise UnsupportedPluginError("No StartupInfo files found")
56
61
 
57
62
  @export(record=StartupInfoRecord)
58
- def startupinfo(self):
63
+ def startupinfo(self) -> Iterator[StartupInfoRecord]:
59
64
  """Return the contents of StartupInfo files.
60
65
 
61
66
  On a Windows system, the StartupInfo log files contain information about process execution for the first 90
@@ -1,3 +1,5 @@
1
+ from typing import Iterator
2
+
1
3
  from dissect.ntfs import ntfs
2
4
 
3
5
  from dissect.target.exceptions import RegistryValueNotFoundError, UnsupportedPluginError
@@ -41,7 +43,7 @@ class SyscachePlugin(Plugin):
41
43
  raise UnsupportedPluginError("Could not load Syscache.hve")
42
44
 
43
45
  @export(record=SyscacheRecord)
44
- def syscache(self):
46
+ def syscache(self) -> Iterator[SyscacheRecord]:
45
47
  """Parse the objects in the ObjectTable from the Syscache.hve file."""
46
48
 
47
49
  # Try to get the system volume
@@ -125,7 +125,7 @@ class TasksPlugin(Plugin):
125
125
  intervals. An adversary may leverage such scheduled tasks to gain persistence on a system.
126
126
 
127
127
  References:
128
- https://en.wikipedia.org/wiki/Windows_Task_Scheduler
128
+ - https://en.wikipedia.org/wiki/Windows_Task_Scheduler
129
129
 
130
130
  Yields:
131
131
  The scheduled tasks found on the target.
@@ -1,5 +1,7 @@
1
+ from __future__ import annotations
2
+
1
3
  from pathlib import Path
2
- from typing import Iterator, Optional, Union
4
+ from typing import Iterator
3
5
 
4
6
  from dissect.thumbcache import Error, Thumbcache
5
7
  from dissect.thumbcache.tools.extract_with_index import dump_entry_data_through_index
@@ -33,6 +35,8 @@ IconcacheRecord = TargetRecordDescriptor("windows/thumbcache/iconcache", GENERIC
33
35
 
34
36
 
35
37
  class ThumbcachePlugin(Plugin):
38
+ """Windows thumbcache plugin."""
39
+
36
40
  __namespace__ = "thumbcache"
37
41
 
38
42
  def get_cache_paths(self) -> Iterator[TargetPath]:
@@ -71,8 +75,8 @@ class ThumbcachePlugin(Plugin):
71
75
  self,
72
76
  record_type: TargetRecordDescriptor,
73
77
  prefix: str,
74
- output_dir: Optional[Path],
75
- ) -> Iterator[Union[ThumbcacheRecord, IconcacheRecord, IndexRecord]]:
78
+ output_dir: Path | None,
79
+ ) -> Iterator[ThumbcacheRecord | IconcacheRecord | IndexRecord]:
76
80
  for cache_path in self.get_cache_paths():
77
81
  try:
78
82
  if output_dir:
@@ -91,10 +95,12 @@ class ThumbcachePlugin(Plugin):
91
95
 
92
96
  @arg("--output", "-o", dest="output_dir", type=Path, help="Path to extract thumbcache thumbnails to.")
93
97
  @export(record=[ThumbcacheRecord, IndexRecord])
94
- def thumbcache(self, output_dir: Optional[Path] = None) -> Iterator[Union[ThumbcacheRecord, IndexRecord]]:
98
+ def thumbcache(self, output_dir: Path | None = None) -> Iterator[ThumbcacheRecord | IndexRecord]:
99
+ """Yield thumbcache thumbnails."""
95
100
  yield from self._parse_thumbcache(ThumbcacheRecord, "thumbcache", output_dir)
96
101
 
97
102
  @arg("--output", "-o", dest="output_dir", type=Path, help="Path to extract iconcache thumbnails to.")
98
103
  @export(record=[IconcacheRecord, IndexRecord])
99
- def iconcache(self, output_dir: Optional[Path] = None) -> Iterator[Union[IconcacheRecord, IndexRecord]]:
104
+ def iconcache(self, output_dir: Path | None = None) -> Iterator[IconcacheRecord | IndexRecord]:
105
+ """Yield iconcache thumbnails."""
100
106
  yield from self._parse_thumbcache(IconcacheRecord, "iconcache", output_dir)
@@ -1,3 +1,6 @@
1
+ from pathlib import Path
2
+ from typing import Any, Iterator
3
+
1
4
  from dissect.esedb.exceptions import Error
2
5
  from dissect.esedb.tools import ual
3
6
 
@@ -165,14 +168,14 @@ class UalPlugin(Plugin):
165
168
  if not any([path.exists() for path in self.mdb_paths]):
166
169
  raise UnsupportedPluginError("No MDB files found")
167
170
 
168
- def find_mdb_files(self):
171
+ def find_mdb_files(self) -> list[Path]:
169
172
  return [
170
173
  path
171
174
  for path in self.target.fs.path("/").glob(self.LOG_DB_GLOB)
172
175
  if path.exists() and path.name != self.IDENTITY_DB_FILENAME
173
176
  ]
174
177
 
175
- def populate_role_guid_map(self):
178
+ def populate_role_guid_map(self) -> None:
176
179
  identity_db = self.target.fs.path(self.IDENTITY_DB_PATH)
177
180
  if not identity_db.exists():
178
181
  return
@@ -192,13 +195,13 @@ class UalPlugin(Plugin):
192
195
  "role_name": record.get("RoleName"),
193
196
  }
194
197
 
195
- def read_table_records(self, table_name):
198
+ def read_table_records(self, table_name: str) -> Iterator[tuple[Path, dict[str, Any]]]:
196
199
  for mdb_path in self.mdb_paths:
197
200
  fh = mdb_path.open()
198
201
  try:
199
202
  parser = ual.UAL(fh)
200
203
  except Error as e:
201
- self.target.log.warning(f"Error opening {mdb_path} database", exc_info=e)
204
+ self.target.log.warning("Error opening database: %s", mdb_path, exc_info=e)
202
205
  continue
203
206
 
204
207
  for table_record in parser.get_table_records(table_name):
@@ -206,7 +209,7 @@ class UalPlugin(Plugin):
206
209
  yield mdb_path, values
207
210
 
208
211
  @export(record=ClientAccessRecord)
209
- def client_access(self):
212
+ def client_access(self) -> Iterator[ClientAccessRecord]:
210
213
  """Return client access data within the User Access Logs."""
211
214
  for path, client_record in self.read_table_records("CLIENTS"):
212
215
  common_values = {k: v for k, v in client_record.items() if k != "activity_counts"}
@@ -224,7 +227,7 @@ class UalPlugin(Plugin):
224
227
  )
225
228
 
226
229
  @export(record=RoleAccessRecord)
227
- def role_access(self):
230
+ def role_access(self) -> Iterator[RoleAccessRecord]:
228
231
  """Return role access data within the User Access Logs."""
229
232
  for path, record in self.read_table_records("ROLE_ACCESS"):
230
233
  role_guid_data = self.role_guid_map.get(record.get("role_guid"), {})
@@ -237,19 +240,19 @@ class UalPlugin(Plugin):
237
240
  )
238
241
 
239
242
  @export(record=VirtualMachineRecord)
240
- def virtual_machines(self):
243
+ def virtual_machines(self) -> Iterator[VirtualMachineRecord]:
241
244
  """Return virtual machine data within the User Access Logs."""
242
245
  for path, record in self.read_table_records("VIRTUALMACHINES"):
243
246
  yield VirtualMachineRecord(path=path, _target=self.target, **record)
244
247
 
245
248
  @export(record=DomainSeenRecord)
246
- def domains_seen(self):
249
+ def domains_seen(self) -> Iterator[DomainSeenRecord]:
247
250
  """Return DNS data within the User Access Logs."""
248
251
  for path, record in self.read_table_records("DNS"):
249
252
  yield DomainSeenRecord(path=path, _target=self.target, **record)
250
253
 
251
254
  @export(record=SystemIdentityRecord)
252
- def system_identities(self):
255
+ def system_identities(self) -> Iterator[SystemIdentityRecord]:
253
256
  """Return system identity data within the User Access Logs."""
254
257
  if not self.identity_db_parser:
255
258
  return
@@ -994,7 +994,6 @@ class WuaHistoryPlugin(Plugin):
994
994
  - https://learn.microsoft.com/en-us/windows/deployment/update/windows-update-error-reference
995
995
  - https://learn.microsoft.com/en-us/troubleshoot/windows-client/installing-updates-features-roles/common-windows-update-errors
996
996
  - https://learn.microsoft.com/en-us/troubleshoot/windows-client/installing-updates-features-roles/common-windows-update-errors?context=%2Fwindows%2Fdeployment%2Fcontext%2Fcontext
997
-
998
997
  - https://github.com/libyal/esedb-kb/blob/main/documentation/Windows%20Update.asciidoc
999
998
  - https://www.nirsoft.net/articles/extract-windows-updates-list-external-drive.html
1000
999
 
@@ -38,6 +38,8 @@ log = structlog.get_logger(__name__)
38
38
 
39
39
 
40
40
  class Compression(enum.Enum):
41
+ """Supported compression types."""
42
+
41
43
  BZIP2 = "bzip2"
42
44
  GZIP = "gzip"
43
45
  LZ4 = "lz4"
@@ -46,6 +48,8 @@ class Compression(enum.Enum):
46
48
 
47
49
 
48
50
  class Serialization(enum.Enum):
51
+ """Supported serialization methods."""
52
+
49
53
  JSONLINES = "jsonlines"
50
54
  MSGPACK = "msgpack"
51
55
 
@@ -205,7 +205,8 @@ class ExtendedCmd(cmd.Cmd):
205
205
 
206
206
  When entering an empty command, the cmd module will by default repeat the previous command.
207
207
  By defining an empty ``emptyline`` function we make sure no command is executed instead.
208
- Resources:
208
+
209
+ References:
209
210
  - https://stackoverflow.com/a/16479030
210
211
  - https://github.com/python/cpython/blob/3.12/Lib/cmd.py#L10
211
212
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dissect.target
3
- Version: 3.20.dev36
3
+ Version: 3.20.dev38
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