dissect.target 3.11.dev4__py3-none-any.whl → 3.11.dev6__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.
@@ -11,18 +11,27 @@ from dissect.target.plugin import OperatingSystem
11
11
  if TYPE_CHECKING:
12
12
  from dissect.target import Target
13
13
 
14
+ PREFIXES = ["", "fs"]
15
+
14
16
 
15
17
  class DirLoader(Loader):
16
18
  """Load a directory as a filesystem."""
17
19
 
18
20
  @staticmethod
19
21
  def detect(path: Path) -> bool:
20
- return find_dirs(path)[0] is not None
22
+ return find_entry_path(path) is not None
21
23
 
22
24
  def map(self, target: Target) -> None:
25
+ self.path /= find_entry_path(self.path)
23
26
  find_and_map_dirs(target, self.path)
24
27
 
25
28
 
29
+ def find_entry_path(path: Path) -> str | None:
30
+ for prefix in PREFIXES:
31
+ if find_dirs(path / prefix)[0] is not None:
32
+ return prefix
33
+
34
+
26
35
  def map_dirs(target: Target, dirs: list[Path], os_type: str, **kwargs) -> None:
27
36
  """Map directories as filesystems into the given target.
28
37
 
@@ -81,7 +90,7 @@ def find_dirs(path: Path) -> tuple[str, list[Path]]:
81
90
  if path.is_dir():
82
91
  for p in path.iterdir():
83
92
  # Look for directories like C or C:
84
- if p.is_dir() and is_drive_letter_path(p):
93
+ if p.is_dir() and (is_drive_letter_path(p) or p.name in ("sysvol", "$rootfs$")):
85
94
  dirs.append(p)
86
95
 
87
96
  if not os_type:
@@ -19,11 +19,50 @@ from dissect.target.plugins.os.windows.task_helpers.tasks_records import (
19
19
  TimeTriggerRecord,
20
20
  TriggerRecord,
21
21
  )
22
- from dissect.target.target import Target
23
22
 
24
23
  warnings.simplefilter(action="ignore", category=FutureWarning)
25
24
 
26
25
 
26
+ class ScheduledTasks:
27
+ def __init__(self, xml_file: TargetPath):
28
+ try:
29
+ self.xml_data = self.strip_namespace(ElementTree.fromstring(xml_file.open().read(), forbid_dtd=True))
30
+ except Exception as e:
31
+ raise InvalidTaskError(e)
32
+
33
+ self.task_path = xml_file
34
+ self.tasks = self.get_tasks()
35
+
36
+ def strip_namespace(self, data: Element) -> Element:
37
+ """Strip namespace from XML data.
38
+
39
+ If the data has a namespace, it will be removed from all the XML tags.
40
+
41
+ Args:
42
+ data: The XML data as an Element object.
43
+
44
+ Returns:
45
+ The XML data with the stripped namespace.
46
+ """
47
+ if data.tag.startswith("{"):
48
+ ns_length = data.tag.find("}")
49
+ ns = data.tag[0 : ns_length + 1]
50
+ for element in data.iter():
51
+ if element.tag.startswith(ns):
52
+ element.tag = element.tag[len(ns) :]
53
+ return data
54
+
55
+ def get_tasks(self):
56
+ tasks = []
57
+ if self.xml_data.tag == "Task":
58
+ tasks.append(XmlTask(self.xml_data, self.task_path))
59
+ else:
60
+ for task_element in self.xml_data.findall(".//{*}Task"):
61
+ tasks.append(XmlTask(task_element, self.task_path))
62
+
63
+ return tasks
64
+
65
+
27
66
  class XmlTask:
28
67
  """Initialize the XmlTask class for open XML-based task files.
29
68
 
@@ -32,13 +71,21 @@ class XmlTask:
32
71
  target: the target system.
33
72
  """
34
73
 
35
- def __init__(self, xml_file: TargetPath, target: Target):
36
- try:
37
- self.xml_data = self.strip_namespace(ElementTree.fromstring(xml_file.open().read(), forbid_dtd=True))
38
- except Exception as e:
39
- raise InvalidTaskError(e)
74
+ def __init__(self, task_element: Element, task_path: TargetPath):
75
+ self.task_path = task_path
76
+ self.task_element = task_element
77
+
78
+ # Properties
79
+ self.task_name = self.get_element("Properties", attribute="name")
80
+ self.app_name = self.get_element("Properties", attribute="appName")
81
+ self.args = self.get_element("Properties", attribute="args")
82
+ self.start_in = self.get_element("Properties", attribute="startIn")
83
+ self.comment = self.get_element("Properties", attribute="comment")
84
+ self.run_as = self.get_element("Properties", attribute="runAs")
85
+ self.cpassword = self.get_element("Properties", attribute="cpassword")
86
+ self.enabled = self.get_element("Properties", attribute="enabled")
87
+ self.action = self.get_element("Properties", attribute="action")
40
88
 
41
- self.task_path = xml_file
42
89
  self.uri = self.get_element("RegistrationInfo/URI")
43
90
  self.security_descriptor = self.get_element("RegistrationInfo/SecurityDescriptor")
44
91
  self.source = self.get_element("RegistrationInfo/Source")
@@ -88,6 +135,8 @@ class XmlTask:
88
135
  # Data
89
136
  self.data = self.get_raw("Data")
90
137
 
138
+ self.raw_data = self.get_raw()
139
+
91
140
  def strip_namespace(self, data: Element) -> Element:
92
141
  """Strip namespace from XML data.
93
142
 
@@ -120,7 +169,7 @@ class XmlTask:
120
169
  Returns:
121
170
  str: The value of the XML element if found, otherwise None.
122
171
  """
123
- xml_data = xml_data or self.xml_data
172
+ xml_data = xml_data or self.task_element
124
173
  data = xml_data.find(xml_path)
125
174
 
126
175
  if data is None:
@@ -130,7 +179,7 @@ class XmlTask:
130
179
 
131
180
  return data.text
132
181
 
133
- def get_raw(self, xml_path: str) -> str:
182
+ def get_raw(self, xml_path: Optional[str] = None) -> str:
134
183
  """Get the raw XML data of the specified element.
135
184
 
136
185
  Args:
@@ -139,9 +188,9 @@ class XmlTask:
139
188
  Returns:
140
189
  bytes: The raw XML data as string of the element if found, otherwise None.
141
190
  """
142
- data = self.xml_data.find(xml_path)
191
+ data = self.task_element.find(xml_path) if xml_path else self.task_element
143
192
  if data:
144
- return ElementTree.tostring(data, encoding="utf-8")
193
+ return ElementTree.tostring(data, encoding="utf-8").strip()
145
194
 
146
195
  def get_triggers(self) -> Iterator[GroupedRecord]:
147
196
  """Get the triggers from the XML task data.
@@ -149,7 +198,7 @@ class XmlTask:
149
198
  Yields:
150
199
  GroupedRecord: The grouped record representing a trigger.
151
200
  """
152
- for trigger in self.xml_data.findall("Triggers/*"):
201
+ for trigger in self.task_element.findall("Triggers/*"):
153
202
  trigger_type = trigger.tag
154
203
  enabled = self.get_element("Enabled", trigger)
155
204
  start_boundary = self.get_element("StartBoundary", trigger)
@@ -233,7 +282,7 @@ class XmlTask:
233
282
  Yields:
234
283
  ActionRecord: The action record representing an action.
235
284
  """
236
- for action in self.xml_data.findall("Actions/*"):
285
+ for action in self.task_element.findall("Actions/*"):
237
286
  action_type = action.tag
238
287
  if action_type == "Exec":
239
288
  command = self.get_element("Actions/Exec/Command")
@@ -7,7 +7,7 @@ from dissect.target.exceptions import UnsupportedPluginError
7
7
  from dissect.target.helpers.record import DynamicDescriptor, TargetRecordDescriptor
8
8
  from dissect.target.plugin import Plugin, export
9
9
  from dissect.target.plugins.os.windows.task_helpers.tasks_job import AtTask
10
- from dissect.target.plugins.os.windows.task_helpers.tasks_xml import XmlTask
10
+ from dissect.target.plugins.os.windows.task_helpers.tasks_xml import ScheduledTasks
11
11
  from dissect.target.target import Target
12
12
 
13
13
  warnings.simplefilter(action="ignore", category=FutureWarning)
@@ -25,6 +25,15 @@ TaskRecord = TargetRecordDescriptor(
25
25
  ("string", "version"),
26
26
  ("string", "description"),
27
27
  ("string", "documentation"),
28
+ ("string", "task_name"),
29
+ ("string", "app_name"),
30
+ ("string", "args"),
31
+ ("string", "start_in"),
32
+ ("string", "comment"),
33
+ ("string", "run_as"),
34
+ ("string", "cpassword"),
35
+ ("string", "enabled"),
36
+ ("string", "action"),
28
37
  ("string", "principal_id"),
29
38
  ("string", "user_id"),
30
39
  ("string", "logon_type"),
@@ -59,6 +68,7 @@ TaskRecord = TargetRecordDescriptor(
59
68
  ("string", "unified_scheduling_engine"),
60
69
  ("string", "disallow_start_on_remote_app_session"),
61
70
  ("string", "data"),
71
+ ("string", "raw_data"),
62
72
  ],
63
73
  )
64
74
 
@@ -119,23 +129,24 @@ class TasksPlugin(Plugin):
119
129
  """
120
130
  for task_file in self.task_files:
121
131
  if not task_file.suffix or task_file.suffix == ".xml":
122
- task_object = XmlTask(task_file, self.target)
132
+ task_objects = ScheduledTasks(task_file).tasks
123
133
  else:
124
- task_object = AtTask(task_file, self.target)
134
+ task_objects = [AtTask(task_file, self.target)]
125
135
 
126
- record_kwargs = {}
127
- for attr in TaskRecord.fields.keys():
128
- record_kwargs[attr] = getattr(task_object, attr, None)
136
+ for task_object in task_objects:
137
+ record_kwargs = {}
138
+ for attr in TaskRecord.fields.keys():
139
+ record_kwargs[attr] = getattr(task_object, attr, None)
129
140
 
130
- record = TaskRecord(**record_kwargs, _target=self.target)
131
- yield record
141
+ record = TaskRecord(**record_kwargs, _target=self.target)
142
+ yield record
132
143
 
133
- # Actions
134
- for action in task_object.get_actions():
135
- grouped = GroupedRecord("filesystem/windows/task/grouped", [record, action])
136
- yield grouped
144
+ # Actions
145
+ for action in task_object.get_actions():
146
+ grouped = GroupedRecord("filesystem/windows/task/grouped", [record, action])
147
+ yield grouped
137
148
 
138
- # Triggers
139
- for trigger in task_object.get_triggers():
140
- grouped = GroupedRecord("filesystem/windows/task/grouped", [record, trigger])
141
- yield grouped
149
+ # Triggers
150
+ for trigger in task_object.get_triggers():
151
+ grouped = GroupedRecord("filesystem/windows/task/grouped", [record, trigger])
152
+ yield grouped
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dissect.target
3
- Version: 3.11.dev4
3
+ Version: 3.11.dev6
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
@@ -57,7 +57,7 @@ dissect/target/loaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
57
57
  dissect/target/loaders/ad1.py,sha256=k0bkY0L6NKuQBboua-jM_KgeyIcXAo59NjExDZHMy0o,572
58
58
  dissect/target/loaders/asdf.py,sha256=oNmfsMpQw143FW3eeYDGCn4V-t2PC-4oBKs7U5d-DEQ,941
59
59
  dissect/target/loaders/cb.py,sha256=pNFk185tfC-PDJjSrTEsdFgnH5DhY-xPXZkwrFMyJ30,3962
60
- dissect/target/loaders/dir.py,sha256=y-bbLGmHhzjRBEGp9w7mfUcFAIsLy_a6WssqVJy6Lco,4453
60
+ dissect/target/loaders/dir.py,sha256=44eQZsCG0WBm0heZV4uNfOc0EHmudEQFG5q3PJ5IWMQ,4720
61
61
  dissect/target/loaders/ewf.py,sha256=6v0ROnXBHp9JiuGjJTBeG_qQQ1rYEUueiILuUcl_PYc,505
62
62
  dissect/target/loaders/hyperv.py,sha256=_IOUJEO0BXaCBZ6sjIX0DZTkG9UNW5Vs9VcNHYv073w,5928
63
63
  dissect/target/loaders/itunes.py,sha256=69aMTQiiGYpmD_EYSmf9mO1re8C3jAZIEStmwlMxdAk,13146
@@ -215,7 +215,7 @@ dissect/target/plugins/os/windows/services.py,sha256=p2v4z4YM-K3G2cnWIHVyPgsJgfr
215
215
  dissect/target/plugins/os/windows/sru.py,sha256=4Vybz3_RJYNbLZXKYGOouUKZNWyOUSgSTf4JAGN2O7w,16808
216
216
  dissect/target/plugins/os/windows/startupinfo.py,sha256=foGO8NLLjMCDEUu0x3f_2GX-1dNN-D67WFX_3ykbL_8,3407
217
217
  dissect/target/plugins/os/windows/syscache.py,sha256=G3nB3TZpDKNUWXUozlPijkgRWfUmYNXf6IVYj72wAJw,3457
218
- dissect/target/plugins/os/windows/tasks.py,sha256=vfBsURCmxAQPlDk5TMzdaNtW4uIEbBAx_0crrM9aU24,5256
218
+ dissect/target/plugins/os/windows/tasks.py,sha256=YIFkco-zrUbNukKBQC66jdIYu3r1-J3ZRb_9gnWeQFA,5676
219
219
  dissect/target/plugins/os/windows/thumbcache.py,sha256=noIpYTcqPk_zRV-DspSUjkhKoHkqiz0OJGOXPRRt6QQ,4141
220
220
  dissect/target/plugins/os/windows/ual.py,sha256=vVGt5eW6axgIupYmJ_j0mAfBSoGmMqjDheLCFR5eGks,9779
221
221
  dissect/target/plugins/os/windows/wer.py,sha256=vQBbUfZtgYeKg46hK_-R95aMHkm-AI2QUz3UMzQPwD4,7574
@@ -249,7 +249,7 @@ dissect/target/plugins/os/windows/regf/userassist.py,sha256=u0vOLZiLhGZLCy6L-EoZ
249
249
  dissect/target/plugins/os/windows/task_helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
250
250
  dissect/target/plugins/os/windows/task_helpers/tasks_job.py,sha256=-dCkJnyEiWG9nCK378-GswM5EXelrA_g3zDHLhSQMu0,21199
251
251
  dissect/target/plugins/os/windows/task_helpers/tasks_records.py,sha256=vpCyKqLQSzI5ymD1h5P6RncLEE47YtmjDFwKA16dVZ4,4046
252
- dissect/target/plugins/os/windows/task_helpers/tasks_xml.py,sha256=zWDxYNJ_Hel0w0QdyzLz1YPwq7ahITjm7trotingphk,13347
252
+ dissect/target/plugins/os/windows/task_helpers/tasks_xml.py,sha256=Xyt69OvUteov7rIEYK6b0AhFvN8kUun0k1uIAanCx6A,15250
253
253
  dissect/target/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
254
254
  dissect/target/tools/build_pluginlist.py,sha256=5fomcuMwsVzcnYx5Htf5f9lSwsLeUUvomLUXNA4t7m4,849
255
255
  dissect/target/tools/dd.py,sha256=Nlh2CFOCV0ksxyedFp7BuyoQ3tBFi6rK6UO0_k5GR_8,1758
@@ -270,10 +270,10 @@ dissect/target/volumes/bde.py,sha256=gYGg5yF9MNARwNzEkrEfZmKkxyZW4rhLkpdnPJCbhGk
270
270
  dissect/target/volumes/disk.py,sha256=95grSsPt1BLVpKwTclwQYzPFGKTkFFqapIk0RoGWf38,968
271
271
  dissect/target/volumes/lvm.py,sha256=_kIB1mdRs1OFhRgoT4VEP5Fv8imQnI7oQ_ie4x710tQ,1814
272
272
  dissect/target/volumes/vmfs.py,sha256=mlAJ8278tYaoRjk1u6tFFlCaDQUrVu5ZZE4ikiFvxi8,1707
273
- dissect.target-3.11.dev4.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
274
- dissect.target-3.11.dev4.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
275
- dissect.target-3.11.dev4.dist-info/METADATA,sha256=l47jC7Ke9Oc6nERaHVolbiwpd4asbl6fBLegbyVinI4,10683
276
- dissect.target-3.11.dev4.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
277
- dissect.target-3.11.dev4.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
278
- dissect.target-3.11.dev4.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
279
- dissect.target-3.11.dev4.dist-info/RECORD,,
273
+ dissect.target-3.11.dev6.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
274
+ dissect.target-3.11.dev6.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
275
+ dissect.target-3.11.dev6.dist-info/METADATA,sha256=sR-MwTH-UuIh5xHWbx51ZFeANVcbNo4AC-8289muhXk,10683
276
+ dissect.target-3.11.dev6.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
277
+ dissect.target-3.11.dev6.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
278
+ dissect.target-3.11.dev6.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
279
+ dissect.target-3.11.dev6.dist-info/RECORD,,