dissect.target 3.15.dev13__py3-none-any.whl → 3.15.dev14__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/ssh/openssh.py +11 -54
- dissect/target/plugins/apps/ssh/opensshd.py +4 -3
- dissect/target/plugins/apps/ssh/putty.py +236 -0
- dissect/target/plugins/apps/ssh/ssh.py +58 -0
- dissect/target/plugins/os/windows/registry.py +1 -1
- {dissect.target-3.15.dev13.dist-info → dissect.target-3.15.dev14.dist-info}/METADATA +1 -1
- {dissect.target-3.15.dev13.dist-info → dissect.target-3.15.dev14.dist-info}/RECORD +12 -10
- {dissect.target-3.15.dev13.dist-info → dissect.target-3.15.dev14.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.15.dev13.dist-info → dissect.target-3.15.dev14.dist-info}/LICENSE +0 -0
- {dissect.target-3.15.dev13.dist-info → dissect.target-3.15.dev14.dist-info}/WHEEL +0 -0
- {dissect.target-3.15.dev13.dist-info → dissect.target-3.15.dev14.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.15.dev13.dist-info → dissect.target-3.15.dev14.dist-info}/top_level.txt +0 -0
@@ -5,59 +5,15 @@ from typing import Iterator
|
|
5
5
|
|
6
6
|
from dissect.target import Target
|
7
7
|
from dissect.target.exceptions import UnsupportedPluginError
|
8
|
-
from dissect.target.helpers.descriptor_extensions import UserRecordDescriptorExtension
|
9
8
|
from dissect.target.helpers.fsutil import TargetPath
|
10
|
-
from dissect.target.helpers.record import create_extended_descriptor
|
11
9
|
from dissect.target.helpers.ssh import SSHPrivateKey
|
12
|
-
from dissect.target.plugin import
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
("path", "path"),
|
20
|
-
]
|
21
|
-
|
22
|
-
AuthorizedKeysRecord = OpenSSHUserRecordDescriptor(
|
23
|
-
"application/openssh/authorized_keys",
|
24
|
-
[
|
25
|
-
*COMMON_ELLEMENTS,
|
26
|
-
("string", "public_key"),
|
27
|
-
("string", "options"),
|
28
|
-
],
|
29
|
-
)
|
30
|
-
|
31
|
-
|
32
|
-
KnownHostRecord = OpenSSHUserRecordDescriptor(
|
33
|
-
"application/openssh/known_host",
|
34
|
-
[
|
35
|
-
*COMMON_ELLEMENTS,
|
36
|
-
("string", "hostname_pattern"),
|
37
|
-
("string", "public_key"),
|
38
|
-
("string", "marker"),
|
39
|
-
],
|
40
|
-
)
|
41
|
-
|
42
|
-
|
43
|
-
PrivateKeyRecord = OpenSSHUserRecordDescriptor(
|
44
|
-
"application/openssh/private_key",
|
45
|
-
[
|
46
|
-
*COMMON_ELLEMENTS,
|
47
|
-
("datetime", "mtime_ts"),
|
48
|
-
("string", "key_format"),
|
49
|
-
("string", "public_key"),
|
50
|
-
("boolean", "encrypted"),
|
51
|
-
],
|
52
|
-
)
|
53
|
-
|
54
|
-
PublicKeyRecord = OpenSSHUserRecordDescriptor(
|
55
|
-
"application/openssh/public_key",
|
56
|
-
[
|
57
|
-
*COMMON_ELLEMENTS,
|
58
|
-
("datetime", "mtime_ts"),
|
59
|
-
("string", "public_key"),
|
60
|
-
],
|
10
|
+
from dissect.target.plugin import export
|
11
|
+
from dissect.target.plugins.apps.ssh.ssh import (
|
12
|
+
AuthorizedKeysRecord,
|
13
|
+
KnownHostRecord,
|
14
|
+
PrivateKeyRecord,
|
15
|
+
PublicKeyRecord,
|
16
|
+
SSHPlugin,
|
61
17
|
)
|
62
18
|
|
63
19
|
|
@@ -72,8 +28,8 @@ def find_sshd_directory(target: Target) -> TargetPath:
|
|
72
28
|
return target.fs.path("/etc/ssh/")
|
73
29
|
|
74
30
|
|
75
|
-
class OpenSSHPlugin(
|
76
|
-
__namespace__ = "
|
31
|
+
class OpenSSHPlugin(SSHPlugin):
|
32
|
+
__namespace__ = "openssh"
|
77
33
|
|
78
34
|
SSHD_DIRECTORIES = ["/sysvol/ProgramData/ssh", "/etc/ssh"]
|
79
35
|
|
@@ -136,7 +92,8 @@ class OpenSSHPlugin(Plugin):
|
|
136
92
|
|
137
93
|
for hostname in hostnames:
|
138
94
|
yield KnownHostRecord(
|
139
|
-
|
95
|
+
host=hostname,
|
96
|
+
port=None,
|
140
97
|
key_type=keytype,
|
141
98
|
public_key=public_key,
|
142
99
|
comment=comment,
|
@@ -3,8 +3,9 @@ from typing import TYPE_CHECKING, Any, Callable, Iterator, Optional, Union
|
|
3
3
|
from dissect.target import Target
|
4
4
|
from dissect.target.exceptions import UnsupportedPluginError
|
5
5
|
from dissect.target.helpers.record import DynamicDescriptor, TargetRecordDescriptor
|
6
|
-
from dissect.target.plugin import
|
6
|
+
from dissect.target.plugin import export
|
7
7
|
from dissect.target.plugins.apps.ssh.openssh import find_sshd_directory
|
8
|
+
from dissect.target.plugins.apps.ssh.ssh import SSHPlugin
|
8
9
|
|
9
10
|
if TYPE_CHECKING:
|
10
11
|
from dissect.target.plugins.general.config import ConfigurationTreePlugin
|
@@ -72,8 +73,8 @@ SSHD_MULTIPLE_DEFINITIONS_ALLOWED_FIELDS = (
|
|
72
73
|
)
|
73
74
|
|
74
75
|
|
75
|
-
class SSHServerPlugin(
|
76
|
-
__namespace__ = "
|
76
|
+
class SSHServerPlugin(SSHPlugin):
|
77
|
+
__namespace__ = "opensshd"
|
77
78
|
|
78
79
|
def __init__(self, target: Target):
|
79
80
|
super().__init__(target)
|
@@ -0,0 +1,236 @@
|
|
1
|
+
import logging
|
2
|
+
from datetime import datetime
|
3
|
+
from pathlib import Path
|
4
|
+
from typing import Iterator, Optional, Union
|
5
|
+
|
6
|
+
from Crypto.PublicKey import ECC, RSA
|
7
|
+
from flow.record.fieldtypes import posix_path, windows_path
|
8
|
+
|
9
|
+
from dissect.target.exceptions import RegistryKeyNotFoundError, UnsupportedPluginError
|
10
|
+
from dissect.target.helpers.descriptor_extensions import UserRecordDescriptorExtension
|
11
|
+
from dissect.target.helpers.fsutil import TargetPath, open_decompress
|
12
|
+
from dissect.target.helpers.record import create_extended_descriptor
|
13
|
+
from dissect.target.helpers.regutil import RegistryKey
|
14
|
+
from dissect.target.plugin import export
|
15
|
+
from dissect.target.plugins.apps.ssh.ssh import KnownHostRecord, SSHPlugin
|
16
|
+
from dissect.target.plugins.general.users import UserDetails
|
17
|
+
|
18
|
+
log = logging.getLogger(__name__)
|
19
|
+
|
20
|
+
PuTTYUserRecordDescriptor = create_extended_descriptor([UserRecordDescriptorExtension])
|
21
|
+
PuTTYSessionRecord = PuTTYUserRecordDescriptor(
|
22
|
+
"application/putty/saved_session",
|
23
|
+
[
|
24
|
+
("datetime", "ts"),
|
25
|
+
("string", "session_name"),
|
26
|
+
("string", "protocol"),
|
27
|
+
("string", "host"),
|
28
|
+
("string", "user"),
|
29
|
+
("varint", "port"),
|
30
|
+
("string", "remote_command"),
|
31
|
+
("string", "port_forward"),
|
32
|
+
("string", "manual_ssh_host_keys"),
|
33
|
+
("path", "path"),
|
34
|
+
],
|
35
|
+
)
|
36
|
+
|
37
|
+
|
38
|
+
class PuTTYPlugin(SSHPlugin):
|
39
|
+
"""Extract artifacts from the PuTTY client.
|
40
|
+
|
41
|
+
NOTE:
|
42
|
+
- Does not parse ``$HOME/.putty/randomseed`` (GNU/Linux)
|
43
|
+
and ``HKCU\\Software\\SimonTatham\\PuTTY\\RandSeedFile`` (Windows)
|
44
|
+
|
45
|
+
Resources:
|
46
|
+
- http://www.chiark.greenend.org.uk/~sgtatham/putty/0.78/puttydoc.txt
|
47
|
+
- http://www.chiark.greenend.org.uk/~sgtatham/putty/faq.html#faq-settings
|
48
|
+
"""
|
49
|
+
|
50
|
+
__namespace__ = "putty"
|
51
|
+
|
52
|
+
def __init__(self, target):
|
53
|
+
super().__init__(target)
|
54
|
+
|
55
|
+
self.regf_installs, self.path_installs = self._detect_putty()
|
56
|
+
|
57
|
+
def _detect_putty(
|
58
|
+
self,
|
59
|
+
) -> tuple[list[set[RegistryKey, Optional[UserDetails]]], list[set[TargetPath, Optional[UserDetails]]]]:
|
60
|
+
regf_installs, path_installs = [], []
|
61
|
+
|
62
|
+
if self.target.has_function("registry"):
|
63
|
+
for key in self.target.registry.keys("HKCU\\Software\\SimonTatham\\PuTTY"):
|
64
|
+
user_details = self.target.registry.get_user_details(key)
|
65
|
+
regf_installs.append((key, user_details))
|
66
|
+
|
67
|
+
for user_details in self.target.user_details.all_with_home():
|
68
|
+
if (putty_path := user_details.home_path.joinpath(".putty")).exists():
|
69
|
+
path_installs.append((putty_path, user_details))
|
70
|
+
|
71
|
+
return regf_installs, path_installs
|
72
|
+
|
73
|
+
def check_compatible(self) -> None:
|
74
|
+
if not any(self.regf_installs + self.path_installs):
|
75
|
+
raise UnsupportedPluginError("No PuTTY installations found")
|
76
|
+
|
77
|
+
@export(record=KnownHostRecord)
|
78
|
+
def known_hosts(self) -> Iterator[KnownHostRecord]:
|
79
|
+
"""Parse PuTTY saved SshHostKeys."""
|
80
|
+
|
81
|
+
for putty_key, user_details in self.regf_installs:
|
82
|
+
yield from self._regf_known_hosts(putty_key, user_details)
|
83
|
+
|
84
|
+
for putty_path, user_details in self.path_installs:
|
85
|
+
yield from self._path_known_hosts(putty_path, user_details)
|
86
|
+
|
87
|
+
def _regf_known_hosts(self, putty_key: RegistryKey, user_details: UserDetails) -> Iterator[KnownHostRecord]:
|
88
|
+
"""Parse PuTTY traces in Windows registry."""
|
89
|
+
|
90
|
+
try:
|
91
|
+
ssh_host_keys = putty_key.subkey("SshHostKeys")
|
92
|
+
except RegistryKeyNotFoundError:
|
93
|
+
return
|
94
|
+
|
95
|
+
for entry in ssh_host_keys.values():
|
96
|
+
key_type, host = entry.name.split("@")
|
97
|
+
port, host = host.split(":")
|
98
|
+
|
99
|
+
yield KnownHostRecord(
|
100
|
+
mtime_ts=ssh_host_keys.ts,
|
101
|
+
host=host,
|
102
|
+
port=port,
|
103
|
+
key_type=key_type,
|
104
|
+
public_key=construct_public_key(key_type, entry.value),
|
105
|
+
comment="",
|
106
|
+
marker=None,
|
107
|
+
path=windows_path(ssh_host_keys.path),
|
108
|
+
_target=self.target,
|
109
|
+
_user=user_details.user if user_details else None,
|
110
|
+
)
|
111
|
+
|
112
|
+
def _path_known_hosts(self, putty_path: TargetPath, user_details: UserDetails) -> Iterator[KnownHostRecord]:
|
113
|
+
"""Parse PuTTY traces in ``.putty`` folders"""
|
114
|
+
ssh_host_keys_path = putty_path.joinpath("sshhostkeys")
|
115
|
+
|
116
|
+
if ssh_host_keys_path.exists():
|
117
|
+
ts = ssh_host_keys_path.stat().st_mtime
|
118
|
+
|
119
|
+
for line in open_decompress(ssh_host_keys_path, "rt"):
|
120
|
+
parts = line.split()
|
121
|
+
key_type, host = parts[0].split("@")
|
122
|
+
port, host = host.split(":")
|
123
|
+
|
124
|
+
yield KnownHostRecord(
|
125
|
+
mtime_ts=ts,
|
126
|
+
host=host,
|
127
|
+
port=port,
|
128
|
+
key_type=key_type,
|
129
|
+
public_key=construct_public_key(key_type, parts[1]),
|
130
|
+
comment="",
|
131
|
+
marker=None,
|
132
|
+
path=posix_path(ssh_host_keys_path),
|
133
|
+
_target=self.target,
|
134
|
+
_user=user_details.user if user_details else None,
|
135
|
+
)
|
136
|
+
|
137
|
+
@export(record=PuTTYSessionRecord)
|
138
|
+
def sessions(self) -> Iterator[PuTTYSessionRecord]:
|
139
|
+
"""Parse PuTTY saved session configuration files."""
|
140
|
+
|
141
|
+
for putty_key, user_details in self.regf_installs:
|
142
|
+
yield from self._regf_sessions(putty_key, user_details)
|
143
|
+
|
144
|
+
for putty_path, user_details in self.path_installs:
|
145
|
+
yield from self._path_sessions(putty_path, user_details)
|
146
|
+
|
147
|
+
def _regf_sessions(self, putty_key: RegistryKey, user_details: UserDetails) -> Iterator[PuTTYSessionRecord]:
|
148
|
+
try:
|
149
|
+
sessions = putty_key.subkey("Sessions")
|
150
|
+
except RegistryKeyNotFoundError:
|
151
|
+
return
|
152
|
+
|
153
|
+
for session in sessions.subkeys():
|
154
|
+
cfg = {s.name: s.value for s in session.values()}
|
155
|
+
yield from self._build_session_record(
|
156
|
+
session.ts, session.name, windows_path(session.path), cfg, user_details
|
157
|
+
)
|
158
|
+
|
159
|
+
def _path_sessions(self, putty_path: TargetPath, user_details: UserDetails) -> Iterator[PuTTYSessionRecord]:
|
160
|
+
sessions_dir = putty_path.joinpath("sessions")
|
161
|
+
if sessions_dir.exists():
|
162
|
+
for session in sessions_dir.glob("*"):
|
163
|
+
if session.is_file():
|
164
|
+
cfg = dict(map(str.strip, line.split("=", maxsplit=1)) for line in session.open("rt").readlines())
|
165
|
+
yield from self._build_session_record(
|
166
|
+
session.stat().st_mtime, session.name, session, cfg, user_details
|
167
|
+
)
|
168
|
+
|
169
|
+
def _build_session_record(
|
170
|
+
self, ts: float, name: Union[float, datetime], source: Path, cfg: dict, user_details: UserDetails
|
171
|
+
) -> PuTTYSessionRecord:
|
172
|
+
host, user = parse_host_user(cfg.get("HostName"), cfg.get("UserName"))
|
173
|
+
|
174
|
+
yield PuTTYSessionRecord(
|
175
|
+
ts=ts,
|
176
|
+
session_name=name,
|
177
|
+
protocol=cfg.get("Protocol"),
|
178
|
+
host=host,
|
179
|
+
user=user,
|
180
|
+
port=cfg.get("PortNumber"),
|
181
|
+
remote_command=cfg.get("RemoteCommand"),
|
182
|
+
port_forward=cfg.get("PortForwardings"),
|
183
|
+
manual_ssh_host_keys=cfg.get("SSHManualHostKeys"),
|
184
|
+
path=source,
|
185
|
+
_target=self.target,
|
186
|
+
_user=user_details.user if user_details else None,
|
187
|
+
)
|
188
|
+
|
189
|
+
|
190
|
+
def parse_host_user(host: str, user: str) -> tuple[str, str]:
|
191
|
+
"""Parse host and user from PuTTY hostname component."""
|
192
|
+
if "@" in host:
|
193
|
+
parsed_user, parsed_host = host.split("@")
|
194
|
+
user = user or parsed_user
|
195
|
+
host = parsed_host
|
196
|
+
|
197
|
+
return host, user
|
198
|
+
|
199
|
+
|
200
|
+
def construct_public_key(key_type: str, iv: str) -> str:
|
201
|
+
"""Returns OpenSSH format public key calculated from PuTTY SshHostKeys format.
|
202
|
+
|
203
|
+
PuTTY stores raw public key components instead of OpenSSH-formatted public keys
|
204
|
+
or fingerprints. With RSA public keys the exponent and modulus are stored.
|
205
|
+
With ECC keys the x and y prime coordinates are stored together with the curve type.
|
206
|
+
|
207
|
+
Currently supports ``ssh-ed25519``, ``ecdsa-sha2-nistp256`` and ``rsa2`` key types.
|
208
|
+
|
209
|
+
NOTE:
|
210
|
+
- Sha256 fingerprints of the reconstructed public keys are currently not generated.
|
211
|
+
- More key types could be supported in the future.
|
212
|
+
|
213
|
+
Resources:
|
214
|
+
- https://github.com/github/putty/blob/master/contrib/kh2reg.py
|
215
|
+
- https://pycryptodome.readthedocs.io/en/latest/src/public_key/rsa.html
|
216
|
+
- https://pycryptodome.readthedocs.io/en/latest/src/public_key/ecc.html
|
217
|
+
- https://github.com/mkorthof/reg2kh
|
218
|
+
"""
|
219
|
+
|
220
|
+
if key_type == "ssh-ed25519":
|
221
|
+
x, y = iv.split(",")
|
222
|
+
key = ECC.construct(curve="ed25519", point_x=int(x, 16), point_y=int(y, 16))
|
223
|
+
return key.public_key().export_key(format="OpenSSH").split()[-1]
|
224
|
+
|
225
|
+
if key_type == "ecdsa-sha2-nistp256":
|
226
|
+
_, x, y = iv.split(",")
|
227
|
+
key = ECC.construct(curve="NIST P-256", point_x=int(x, 16), point_y=int(y, 16))
|
228
|
+
return key.public_key().export_key(format="OpenSSH").split()[-1]
|
229
|
+
|
230
|
+
if key_type == "rsa2":
|
231
|
+
exponent, modulus = iv.split(",")
|
232
|
+
key = RSA.construct((int(modulus, 16), int(exponent, 16)))
|
233
|
+
return key.public_key().export_key(format="OpenSSH").decode("utf-8").split()[-1]
|
234
|
+
|
235
|
+
log.warning("Could not reconstruct public key: type %s not implemented.", key_type)
|
236
|
+
return iv
|
@@ -0,0 +1,58 @@
|
|
1
|
+
from dissect.target.helpers.descriptor_extensions import UserRecordDescriptorExtension
|
2
|
+
from dissect.target.helpers.record import create_extended_descriptor
|
3
|
+
from dissect.target.plugin import NamespacePlugin
|
4
|
+
|
5
|
+
OpenSSHUserRecordDescriptor = create_extended_descriptor([UserRecordDescriptorExtension])
|
6
|
+
|
7
|
+
COMMON_ELLEMENTS = [
|
8
|
+
("string", "key_type"),
|
9
|
+
("string", "comment"),
|
10
|
+
("path", "path"),
|
11
|
+
]
|
12
|
+
|
13
|
+
AuthorizedKeysRecord = OpenSSHUserRecordDescriptor(
|
14
|
+
"application/openssh/authorized_keys",
|
15
|
+
[
|
16
|
+
*COMMON_ELLEMENTS,
|
17
|
+
("string", "public_key"),
|
18
|
+
("string", "options"),
|
19
|
+
],
|
20
|
+
)
|
21
|
+
|
22
|
+
|
23
|
+
KnownHostRecord = OpenSSHUserRecordDescriptor(
|
24
|
+
"application/openssh/known_host",
|
25
|
+
[
|
26
|
+
("datetime", "mtime_ts"),
|
27
|
+
*COMMON_ELLEMENTS,
|
28
|
+
("string", "host"),
|
29
|
+
("varint", "port"),
|
30
|
+
("string", "public_key"),
|
31
|
+
("string", "marker"),
|
32
|
+
],
|
33
|
+
)
|
34
|
+
|
35
|
+
|
36
|
+
PrivateKeyRecord = OpenSSHUserRecordDescriptor(
|
37
|
+
"application/openssh/private_key",
|
38
|
+
[
|
39
|
+
("datetime", "mtime_ts"),
|
40
|
+
*COMMON_ELLEMENTS,
|
41
|
+
("string", "key_format"),
|
42
|
+
("string", "public_key"),
|
43
|
+
("boolean", "encrypted"),
|
44
|
+
],
|
45
|
+
)
|
46
|
+
|
47
|
+
PublicKeyRecord = OpenSSHUserRecordDescriptor(
|
48
|
+
"application/openssh/public_key",
|
49
|
+
[
|
50
|
+
("datetime", "mtime_ts"),
|
51
|
+
*COMMON_ELLEMENTS,
|
52
|
+
("string", "public_key"),
|
53
|
+
],
|
54
|
+
)
|
55
|
+
|
56
|
+
|
57
|
+
class SSHPlugin(NamespacePlugin):
|
58
|
+
__namespace__ = "ssh"
|
@@ -329,7 +329,7 @@ class RegistryPlugin(Plugin):
|
|
329
329
|
@internal
|
330
330
|
def get_user_details(self, key: RegistryKey) -> UserDetails:
|
331
331
|
"""Return user details for the user who owns a registry hive that contains the provided key"""
|
332
|
-
if not key.hive or not key.hive
|
332
|
+
if not key.hive or not getattr(key.hive, "filepath", None):
|
333
333
|
return
|
334
334
|
|
335
335
|
return self._hives_to_users.get(key.hive)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: dissect.target
|
3
|
-
Version: 3.15.
|
3
|
+
Version: 3.15.dev14
|
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
|
@@ -117,8 +117,10 @@ dissect/target/plugins/apps/remoteaccess/teamviewer.py,sha256=SiEH36HM2NvdPuCjfL
|
|
117
117
|
dissect/target/plugins/apps/shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
118
118
|
dissect/target/plugins/apps/shell/powershell.py,sha256=biPSMRWxPI6kRqP0-75yMtrw0Ti2Bzfl_xI3xbmmF48,2641
|
119
119
|
dissect/target/plugins/apps/ssh/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
120
|
-
dissect/target/plugins/apps/ssh/openssh.py,sha256=
|
121
|
-
dissect/target/plugins/apps/ssh/opensshd.py,sha256=
|
120
|
+
dissect/target/plugins/apps/ssh/openssh.py,sha256=jDNP8aq9JHivosexPlxWRUgeJo1MHclb336dzO1zRJc,7086
|
121
|
+
dissect/target/plugins/apps/ssh/opensshd.py,sha256=DaXKdgGF3GYHHA4buEvphcm6FF4C8YFjgD96Dv6rRnM,5510
|
122
|
+
dissect/target/plugins/apps/ssh/putty.py,sha256=N8ssjutUVN50JNA5fEIVISbP5sJ7bGTFidRbX3uNG5Y,9404
|
123
|
+
dissect/target/plugins/apps/ssh/ssh.py,sha256=uCaoWlT2bgKLUHA1aL6XymJDWJ8JmLsN8PB1C66eidY,1409
|
122
124
|
dissect/target/plugins/apps/vpn/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
123
125
|
dissect/target/plugins/apps/vpn/openvpn.py,sha256=NZeFSFgGAifevGIQBusdbBRFOPxu0584Th8rKE-XSus,6875
|
124
126
|
dissect/target/plugins/apps/vpn/wireguard.py,sha256=45WvCqQQGrG3DVDH5ghcsGpM_BomF4RcTLzcIvnyuNs,6554
|
@@ -237,7 +239,7 @@ dissect/target/plugins/os/windows/locale.py,sha256=yXVdclpUqss9h8Nq7N4kg3OHwWGDf
|
|
237
239
|
dissect/target/plugins/os/windows/notifications.py,sha256=64xHHueHwtJCc8RTAF70oa0RxvqfCu_DBPWRSZBnYZc,17386
|
238
240
|
dissect/target/plugins/os/windows/prefetch.py,sha256=5hRxdIP9sIV5Q9TAScMjLbl_mImZ37abvdE_pAd6rh4,10398
|
239
241
|
dissect/target/plugins/os/windows/recyclebin.py,sha256=4GSj0Q3YvONufnqANbnG0ffiMQyToCiL5s35Wmu4JOQ,4898
|
240
|
-
dissect/target/plugins/os/windows/registry.py,sha256=
|
242
|
+
dissect/target/plugins/os/windows/registry.py,sha256=IBRqltJ_4fZpVuwMVCAH_nS8JUaNVjsC1jh9AZSNHL4,12788
|
241
243
|
dissect/target/plugins/os/windows/sam.py,sha256=Es_8ROQ6R6-akuTtegCdsJHXzZJNhzgoFuS8y9xNN8E,15267
|
242
244
|
dissect/target/plugins/os/windows/services.py,sha256=_6YkuoZD8LUxk72R3n1p1bOBab3A1wszdB1NuPavIGM,6037
|
243
245
|
dissect/target/plugins/os/windows/sru.py,sha256=sOM7CyMkW8XIXzI75GL69WoqUrSK2X99TFIfdQR2D64,17767
|
@@ -306,10 +308,10 @@ dissect/target/volumes/luks.py,sha256=v_mHW05KM5iG8JDe47i2V4Q9O0r4rnAMA9m_qc9cYw
|
|
306
308
|
dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
|
307
309
|
dissect/target/volumes/md.py,sha256=j1K1iKmspl0C_OJFc7-Q1BMWN2OCC5EVANIgVlJ_fIE,1673
|
308
310
|
dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
|
309
|
-
dissect.target-3.15.
|
310
|
-
dissect.target-3.15.
|
311
|
-
dissect.target-3.15.
|
312
|
-
dissect.target-3.15.
|
313
|
-
dissect.target-3.15.
|
314
|
-
dissect.target-3.15.
|
315
|
-
dissect.target-3.15.
|
311
|
+
dissect.target-3.15.dev14.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
|
312
|
+
dissect.target-3.15.dev14.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
313
|
+
dissect.target-3.15.dev14.dist-info/METADATA,sha256=a7gsrN05qksoHcTNVGfHVUklhofWCTLyKBiNfwWLru0,11107
|
314
|
+
dissect.target-3.15.dev14.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
315
|
+
dissect.target-3.15.dev14.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
|
316
|
+
dissect.target-3.15.dev14.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
|
317
|
+
dissect.target-3.15.dev14.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
{dissect.target-3.15.dev13.dist-info → dissect.target-3.15.dev14.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|