dissect.target 3.11.dev5__py3-none-any.whl → 3.11.dev6__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- dissect/target/plugins/os/windows/task_helpers/tasks_xml.py +62 -13
- dissect/target/plugins/os/windows/tasks.py +27 -16
- {dissect.target-3.11.dev5.dist-info → dissect.target-3.11.dev6.dist-info}/METADATA +1 -1
- {dissect.target-3.11.dev5.dist-info → dissect.target-3.11.dev6.dist-info}/RECORD +9 -9
- {dissect.target-3.11.dev5.dist-info → dissect.target-3.11.dev6.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.11.dev5.dist-info → dissect.target-3.11.dev6.dist-info}/LICENSE +0 -0
- {dissect.target-3.11.dev5.dist-info → dissect.target-3.11.dev6.dist-info}/WHEEL +0 -0
- {dissect.target-3.11.dev5.dist-info → dissect.target-3.11.dev6.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.11.dev5.dist-info → dissect.target-3.11.dev6.dist-info}/top_level.txt +0 -0
@@ -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,
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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.
|
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.
|
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.
|
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.
|
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
|
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
|
-
|
132
|
+
task_objects = ScheduledTasks(task_file).tasks
|
123
133
|
else:
|
124
|
-
|
134
|
+
task_objects = [AtTask(task_file, self.target)]
|
125
135
|
|
126
|
-
|
127
|
-
|
128
|
-
|
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
|
-
|
131
|
-
|
141
|
+
record = TaskRecord(**record_kwargs, _target=self.target)
|
142
|
+
yield record
|
132
143
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
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
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
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.
|
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
|
@@ -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=
|
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=
|
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.
|
274
|
-
dissect.target-3.11.
|
275
|
-
dissect.target-3.11.
|
276
|
-
dissect.target-3.11.
|
277
|
-
dissect.target-3.11.
|
278
|
-
dissect.target-3.11.
|
279
|
-
dissect.target-3.11.
|
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,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|