dissect.target 3.20.dev17__py3-none-any.whl → 3.20.dev19__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.
- dissect/target/plugins/apps/virtualization/__init__.py +0 -0
- dissect/target/plugins/apps/virtualization/vmware_workstation.py +61 -0
- dissect/target/plugins/child/vmware_workstation.py +23 -8
- dissect/target/tools/shell.py +37 -1
- {dissect.target-3.20.dev17.dist-info → dissect.target-3.20.dev19.dist-info}/METADATA +1 -1
- {dissect.target-3.20.dev17.dist-info → dissect.target-3.20.dev19.dist-info}/RECORD +11 -9
- {dissect.target-3.20.dev17.dist-info → dissect.target-3.20.dev19.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.20.dev17.dist-info → dissect.target-3.20.dev19.dist-info}/LICENSE +0 -0
- {dissect.target-3.20.dev17.dist-info → dissect.target-3.20.dev19.dist-info}/WHEEL +0 -0
- {dissect.target-3.20.dev17.dist-info → dissect.target-3.20.dev19.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.20.dev17.dist-info → dissect.target-3.20.dev19.dist-info}/top_level.txt +0 -0
File without changes
|
@@ -0,0 +1,61 @@
|
|
1
|
+
from typing import Iterator
|
2
|
+
|
3
|
+
from dissect.target.exceptions import UnsupportedPluginError
|
4
|
+
from dissect.target.helpers.descriptor_extensions import UserRecordDescriptorExtension
|
5
|
+
from dissect.target.helpers.fsutil import TargetPath
|
6
|
+
from dissect.target.helpers.record import create_extended_descriptor
|
7
|
+
from dissect.target.plugin import Plugin, alias, export
|
8
|
+
from dissect.target.plugins.general.users import UserDetails
|
9
|
+
from dissect.target.target import Target
|
10
|
+
|
11
|
+
VmwareDragAndDropRecord = create_extended_descriptor([UserRecordDescriptorExtension])(
|
12
|
+
"virtualization/vmware/clipboard",
|
13
|
+
[
|
14
|
+
("datetime", "ts"),
|
15
|
+
("path", "path"),
|
16
|
+
],
|
17
|
+
)
|
18
|
+
|
19
|
+
VMWARE_DND_PATHS = [
|
20
|
+
# Windows
|
21
|
+
"AppData/Local/Temp/VmwareDND",
|
22
|
+
# Linux
|
23
|
+
".cache/vmware/drag_and_drop",
|
24
|
+
]
|
25
|
+
|
26
|
+
|
27
|
+
class VmwareWorkstationPlugin(Plugin):
|
28
|
+
"""VMware Workstation plugin."""
|
29
|
+
|
30
|
+
__namespace__ = "vmware"
|
31
|
+
|
32
|
+
def __init__(self, target: Target):
|
33
|
+
super().__init__(target)
|
34
|
+
self.dnd_dirs = list(self.find_dnd_dirs())
|
35
|
+
|
36
|
+
def check_compatible(self) -> None:
|
37
|
+
if not self.dnd_dirs:
|
38
|
+
raise UnsupportedPluginError("No VMware Workstation DnD artifact(s) found")
|
39
|
+
|
40
|
+
def find_dnd_dirs(self) -> Iterator[tuple[UserDetails, TargetPath]]:
|
41
|
+
for user_details in self.target.user_details.all_with_home():
|
42
|
+
for dnd_path in VMWARE_DND_PATHS:
|
43
|
+
if (dnd_dir := user_details.home_path.joinpath(dnd_path)).exists():
|
44
|
+
yield user_details, dnd_dir
|
45
|
+
|
46
|
+
@alias("draganddrop")
|
47
|
+
@export(record=VmwareDragAndDropRecord)
|
48
|
+
def clipboard(self) -> Iterator[VmwareDragAndDropRecord]:
|
49
|
+
"""Yield cached VMware Workstation drag-and-drop file artifacts."""
|
50
|
+
|
51
|
+
for user_details, dnd_dir in self.dnd_dirs:
|
52
|
+
for file in dnd_dir.rglob("*/*"):
|
53
|
+
if file.is_dir():
|
54
|
+
continue
|
55
|
+
|
56
|
+
yield VmwareDragAndDropRecord(
|
57
|
+
ts=file.lstat().st_mtime,
|
58
|
+
path=file,
|
59
|
+
_user=user_details.user,
|
60
|
+
_target=self.target,
|
61
|
+
)
|
@@ -1,29 +1,44 @@
|
|
1
|
+
from typing import Iterator
|
2
|
+
|
1
3
|
from dissect.target.exceptions import UnsupportedPluginError
|
4
|
+
from dissect.target.helpers.fsutil import TargetPath
|
2
5
|
from dissect.target.helpers.record import ChildTargetRecord
|
3
6
|
from dissect.target.plugin import ChildTargetPlugin
|
7
|
+
from dissect.target.target import Target
|
8
|
+
|
9
|
+
INVENTORY_PATHS = [
|
10
|
+
# Windows
|
11
|
+
"AppData/Roaming/VMware/inventory.vmls",
|
12
|
+
# Linux
|
13
|
+
".vmware/inventory.vmls",
|
14
|
+
]
|
15
|
+
|
16
|
+
|
17
|
+
def find_vm_inventory(target: Target) -> Iterator[TargetPath]:
|
18
|
+
"""Search for inventory.vmls files in user home folders.
|
4
19
|
|
20
|
+
Does not support older vmAutoStart.xml or vmInventory.xml formats."""
|
5
21
|
|
6
|
-
def find_vm_inventory(target):
|
7
22
|
for user_details in target.user_details.all_with_home():
|
8
|
-
|
9
|
-
|
10
|
-
|
23
|
+
for inv_path in INVENTORY_PATHS:
|
24
|
+
if (inv_file := user_details.home_path.joinpath(inv_path)).exists():
|
25
|
+
yield inv_file
|
11
26
|
|
12
27
|
|
13
|
-
class
|
28
|
+
class VmwareWorkstationChildTargetPlugin(ChildTargetPlugin):
|
14
29
|
"""Child target plugin that yields from VMware Workstation VM inventory."""
|
15
30
|
|
16
31
|
__type__ = "vmware_workstation"
|
17
32
|
|
18
|
-
def __init__(self, target):
|
33
|
+
def __init__(self, target: Target):
|
19
34
|
super().__init__(target)
|
20
35
|
self.inventories = list(find_vm_inventory(target))
|
21
36
|
|
22
37
|
def check_compatible(self) -> None:
|
23
|
-
if not
|
38
|
+
if not self.inventories:
|
24
39
|
raise UnsupportedPluginError("No VMWare inventories found")
|
25
40
|
|
26
|
-
def list_children(self):
|
41
|
+
def list_children(self) -> Iterator[ChildTargetRecord]:
|
27
42
|
for inv in self.inventories:
|
28
43
|
for line in inv.open("rt"):
|
29
44
|
line = line.strip()
|
dissect/target/tools/shell.py
CHANGED
@@ -96,6 +96,7 @@ class ExtendedCmd(cmd.Cmd):
|
|
96
96
|
|
97
97
|
CMD_PREFIX = "cmd_"
|
98
98
|
_runtime_aliases = {}
|
99
|
+
DEFAULT_RUNCOMMANDS_FILE = None
|
99
100
|
|
100
101
|
def __init__(self, cyber: bool = False):
|
101
102
|
cmd.Cmd.__init__(self)
|
@@ -121,6 +122,28 @@ class ExtendedCmd(cmd.Cmd):
|
|
121
122
|
|
122
123
|
return object.__getattribute__(self, attr)
|
123
124
|
|
125
|
+
def _load_targetrc(self, path: pathlib.Path) -> None:
|
126
|
+
"""Load and execute commands from the run commands file."""
|
127
|
+
try:
|
128
|
+
with path.open() as fh:
|
129
|
+
for line in fh:
|
130
|
+
if (line := line.strip()) and not line.startswith("#"): # Ignore empty lines and comments
|
131
|
+
self.onecmd(line)
|
132
|
+
except FileNotFoundError:
|
133
|
+
# The .targetrc file is optional
|
134
|
+
pass
|
135
|
+
except Exception as e:
|
136
|
+
log.debug("Error processing .targetrc file: %s", e)
|
137
|
+
|
138
|
+
def _get_targetrc_path(self) -> pathlib.Path | None:
|
139
|
+
"""Get the path to the run commands file. Can return ``None`` if ``DEFAULT_RUNCOMMANDS_FILE`` is not set."""
|
140
|
+
return pathlib.Path(self.DEFAULT_RUNCOMMANDS_FILE).expanduser() if self.DEFAULT_RUNCOMMANDS_FILE else None
|
141
|
+
|
142
|
+
def preloop(self) -> None:
|
143
|
+
super().preloop()
|
144
|
+
if targetrc_path := self._get_targetrc_path():
|
145
|
+
self._load_targetrc(targetrc_path)
|
146
|
+
|
124
147
|
@staticmethod
|
125
148
|
def check_compatible(target: Target) -> bool:
|
126
149
|
return True
|
@@ -309,6 +332,8 @@ class TargetCmd(ExtendedCmd):
|
|
309
332
|
DEFAULT_HISTFILESIZE = 10_000
|
310
333
|
DEFAULT_HISTDIR = None
|
311
334
|
DEFAULT_HISTDIRFMT = ".dissect_history_{uid}_{target}"
|
335
|
+
DEFAULT_RUNCOMMANDS_FILE = "~/.targetrc"
|
336
|
+
CONFIG_KEY_RUNCOMMANDS_FILE = "TARGETRCFILE"
|
312
337
|
|
313
338
|
def __init__(self, target: Target):
|
314
339
|
self.target = target
|
@@ -338,7 +363,15 @@ class TargetCmd(ExtendedCmd):
|
|
338
363
|
|
339
364
|
super().__init__(self.target.props.get("cyber"))
|
340
365
|
|
366
|
+
def _get_targetrc_path(self) -> pathlib.Path:
|
367
|
+
"""Get the path to the run commands file."""
|
368
|
+
|
369
|
+
return pathlib.Path(
|
370
|
+
getattr(self.target._config, self.CONFIG_KEY_RUNCOMMANDS_FILE, self.DEFAULT_RUNCOMMANDS_FILE)
|
371
|
+
).expanduser()
|
372
|
+
|
341
373
|
def preloop(self) -> None:
|
374
|
+
super().preloop()
|
342
375
|
if readline and self.histfile.exists():
|
343
376
|
try:
|
344
377
|
readline.read_history_file(self.histfile)
|
@@ -507,7 +540,6 @@ class TargetCli(TargetCmd):
|
|
507
540
|
self.prompt_base = _target_name(target)
|
508
541
|
|
509
542
|
TargetCmd.__init__(self, target)
|
510
|
-
|
511
543
|
self._clicache = {}
|
512
544
|
self.cwd = None
|
513
545
|
self.chdir("/")
|
@@ -1144,6 +1176,10 @@ class UnixConfigTreeCli(TargetCli):
|
|
1144
1176
|
class RegistryCli(TargetCmd):
|
1145
1177
|
"""CLI for browsing the registry."""
|
1146
1178
|
|
1179
|
+
# Registry shell is incompatible with default shell, so override the default rc file and config key
|
1180
|
+
DEFAULT_RUNCOMMANDS_FILE = "~/.targetrc.registry"
|
1181
|
+
CONFIG_KEY_RUNCOMMANDS_FILE = "TARGETRCFILE_REGISTRY"
|
1182
|
+
|
1147
1183
|
def __init__(self, target: Target, registry: regutil.RegfHive | None = None):
|
1148
1184
|
self.prompt_base = _target_name(target)
|
1149
1185
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: dissect.target
|
3
|
-
Version: 3.20.
|
3
|
+
Version: 3.20.dev19
|
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
|
@@ -141,6 +141,8 @@ dissect/target/plugins/apps/ssh/ssh.py,sha256=d3U8PJbtMvOV3K0wV_9KzGt2oRs-mfNQz1
|
|
141
141
|
dissect/target/plugins/apps/texteditor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
142
142
|
dissect/target/plugins/apps/texteditor/texteditor.py,sha256=h-tF1x2hLlgeNM3W-0Z9g0mjjkb9ietT1D5c-9GaMr8,543
|
143
143
|
dissect/target/plugins/apps/texteditor/windowsnotepad.py,sha256=BXGhcwWIW6zlQyD_nHpc1r5Lxt6WMvhfqY2PWf0A6pw,14852
|
144
|
+
dissect/target/plugins/apps/virtualization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
145
|
+
dissect/target/plugins/apps/virtualization/vmware_workstation.py,sha256=7G-MRZCMN6aSYfs5NpaW2wkezqlx_EXq9-GzdbvtRrk,2088
|
144
146
|
dissect/target/plugins/apps/vpn/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
145
147
|
dissect/target/plugins/apps/vpn/openvpn.py,sha256=d-DGINTIHP_bvv3T09ZwbezHXGctvCyAhJ482m2_-a0,7654
|
146
148
|
dissect/target/plugins/apps/vpn/wireguard.py,sha256=SoAMED_bwWJQ3nci5qEY-qV4wJKSSDZQ8K7DoJRYq0k,6521
|
@@ -160,7 +162,7 @@ dissect/target/plugins/child/hyperv.py,sha256=R2qVeu4p_9V53jO-65znN0LwX9v3FVA-9j
|
|
160
162
|
dissect/target/plugins/child/parallels.py,sha256=jeBT_NvTQbQBaUjqGWTy2I5Q5OWlrogoyWHRXjOhLis,2255
|
161
163
|
dissect/target/plugins/child/qemu.py,sha256=vNzQwzFO964jYaI67MlX8vpWyHxpegjIU5F29zHKOGI,791
|
162
164
|
dissect/target/plugins/child/virtuozzo.py,sha256=Mx4ZxEl21g7IYkzraw4FBZup5EfrkFDv4WuTE3hxguw,1206
|
163
|
-
dissect/target/plugins/child/vmware_workstation.py,sha256=
|
165
|
+
dissect/target/plugins/child/vmware_workstation.py,sha256=eLvgi_aFUaMN1tC5X4RN85nKQdsuRQygrFYtNMAERTc,2030
|
164
166
|
dissect/target/plugins/child/wsl.py,sha256=IssQgYET1T-XR5ZX2lGlNFJ_u_3QECpMF_7kXu09HTE,2469
|
165
167
|
dissect/target/plugins/filesystem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
166
168
|
dissect/target/plugins/filesystem/acquire_handles.py,sha256=-pX_akH5GrYe0HofXOa2Il75knZH6ZKgru4BFcrElkM,1731
|
@@ -351,7 +353,7 @@ dissect/target/tools/logging.py,sha256=5ZnumtMWLyslxfrUGZ4ntRyf3obOOhmn8SBjKfdLc
|
|
351
353
|
dissect/target/tools/mount.py,sha256=8GRYnu4xEmFBHxuIZAYhOMyyTGX8fat1Ou07DNiUnW4,3945
|
352
354
|
dissect/target/tools/query.py,sha256=e-yAN9zdQjuOiTuoOQoo17mVEQGGcOgaA9YkF4GYpkM,15394
|
353
355
|
dissect/target/tools/reg.py,sha256=FDsiBBDxjWVUBTRj8xn82vZe-J_d9piM-TKS3PHZCcM,3193
|
354
|
-
dissect/target/tools/shell.py,sha256=
|
356
|
+
dissect/target/tools/shell.py,sha256=0RqcPmOmFEQ0-5Efqm8ZdGbTeZw2OXFFaCGNyCCzUVs,53714
|
355
357
|
dissect/target/tools/utils.py,sha256=JJZDSso1CEK2sv4Z3HJNgqxH6G9S5lbmV-C3h-XmcMo,12035
|
356
358
|
dissect/target/tools/yara.py,sha256=70k-2VMulf1EdkX03nCACzejaOEcsFHOyX-4E40MdQU,2044
|
357
359
|
dissect/target/tools/dump/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -366,10 +368,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z
|
|
366
368
|
dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
|
367
369
|
dissect/target/volumes/md.py,sha256=7ShPtusuLGaIv27SvEETtgsuoQyAa4iAAeOR1NEaajI,1689
|
368
370
|
dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
|
369
|
-
dissect.target-3.20.
|
370
|
-
dissect.target-3.20.
|
371
|
-
dissect.target-3.20.
|
372
|
-
dissect.target-3.20.
|
373
|
-
dissect.target-3.20.
|
374
|
-
dissect.target-3.20.
|
375
|
-
dissect.target-3.20.
|
371
|
+
dissect.target-3.20.dev19.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
|
372
|
+
dissect.target-3.20.dev19.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
373
|
+
dissect.target-3.20.dev19.dist-info/METADATA,sha256=I3DYNx-CfW04SXNH44iwl9Gtaq5jIdEfhdukyOAp9GM,12897
|
374
|
+
dissect.target-3.20.dev19.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
375
|
+
dissect.target-3.20.dev19.dist-info/entry_points.txt,sha256=BWuxAb_6AvUAQpIQOQU0IMTlaF6TDht2AIZK8bHd-zE,492
|
376
|
+
dissect.target-3.20.dev19.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
|
377
|
+
dissect.target-3.20.dev19.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
{dissect.target-3.20.dev17.dist-info → dissect.target-3.20.dev19.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|