dissect.target 3.16.dev29__py3-none-any.whl → 3.16.dev31__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- dissect/target/plugins/apps/webserver/iis.py +2 -1
- dissect/target/plugins/os/unix/esxi/_os.py +61 -9
- dissect/target/plugins/os/windows/log/etl.py +3 -1
- dissect/target/plugins/os/windows/log/evtx.py +1 -1
- dissect/target/plugins/os/windows/registry.py +3 -1
- {dissect.target-3.16.dev29.dist-info → dissect.target-3.16.dev31.dist-info}/METADATA +1 -1
- {dissect.target-3.16.dev29.dist-info → dissect.target-3.16.dev31.dist-info}/RECORD +12 -12
- {dissect.target-3.16.dev29.dist-info → dissect.target-3.16.dev31.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.16.dev29.dist-info → dissect.target-3.16.dev31.dist-info}/LICENSE +0 -0
- {dissect.target-3.16.dev29.dist-info → dissect.target-3.16.dev31.dist-info}/WHEEL +0 -0
- {dissect.target-3.16.dev29.dist-info → dissect.target-3.16.dev31.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.16.dev29.dist-info → dissect.target-3.16.dev31.dist-info}/top_level.txt +0 -0
@@ -60,6 +60,8 @@ class IISLogsPlugin(WebserverPlugin):
|
|
60
60
|
super().__init__(target)
|
61
61
|
self.config = self.target.fs.path(self.APPLICATION_HOST_CONFIG)
|
62
62
|
|
63
|
+
self._create_extended_descriptor = lru_cache(4096)(self._create_extended_descriptor)
|
64
|
+
|
63
65
|
def check_compatible(self) -> None:
|
64
66
|
if not self.config.exists() and not self.target.fs.path("sysvol/files").exists():
|
65
67
|
raise UnsupportedPluginError("No ApplicationHost config file found")
|
@@ -157,7 +159,6 @@ class IISLogsPlugin(WebserverPlugin):
|
|
157
159
|
row = replace_dash_with_none(row)
|
158
160
|
yield BasicRecordDescriptor(**row)
|
159
161
|
|
160
|
-
@lru_cache(maxsize=4096)
|
161
162
|
def _create_extended_descriptor(self, extra_fields: tuple[tuple[str, str]]) -> TargetRecordDescriptor:
|
162
163
|
return TargetRecordDescriptor(LOG_RECORD_NAME, BASIC_RECORD_FIELDS + list(extra_fields))
|
163
164
|
|
@@ -4,6 +4,7 @@ import gzip
|
|
4
4
|
import json
|
5
5
|
import lzma
|
6
6
|
import struct
|
7
|
+
import subprocess
|
7
8
|
from configparser import ConfigParser
|
8
9
|
from configparser import Error as ConfigParserError
|
9
10
|
from io import BytesIO
|
@@ -13,6 +14,8 @@ from defusedxml import ElementTree
|
|
13
14
|
from dissect.hypervisor.util import vmtar
|
14
15
|
from dissect.sql import sqlite3
|
15
16
|
|
17
|
+
from dissect.target.helpers.fsutil import TargetPath
|
18
|
+
|
16
19
|
try:
|
17
20
|
from dissect.hypervisor.util.envelope import Envelope, KeyStore
|
18
21
|
|
@@ -217,23 +220,72 @@ def _mount_local(target: Target, local_layer: VirtualFilesystem):
|
|
217
220
|
local_fs = tar.TarFilesystem(local_tgz.open())
|
218
221
|
else:
|
219
222
|
local_tgz_ve = target.fs.path("local.tgz.ve")
|
220
|
-
|
223
|
+
# In the case "encryption.info" does not exist, but ".#encryption.info" does
|
224
|
+
encryption_info = next(target.fs.path("/").glob("*encryption.info"), None)
|
221
225
|
if not local_tgz_ve.exists() or not encryption_info.exists():
|
222
226
|
raise ValueError("Unable to find valid configuration archive")
|
223
227
|
|
224
|
-
|
225
|
-
target.log.info("local.tgz is encrypted, attempting to decrypt")
|
226
|
-
envelope = Envelope(local_tgz_ve.open())
|
227
|
-
keystore = KeyStore.from_text(encryption_info.read_text("utf-8"))
|
228
|
-
local_tgz = BytesIO(envelope.decrypt(keystore.key, aad=b"ESXConfiguration"))
|
229
|
-
local_fs = tar.TarFilesystem(local_tgz)
|
230
|
-
else:
|
231
|
-
target.log.warning("local.tgz is encrypted but no crypto module available!")
|
228
|
+
local_fs = _create_local_fs(target, local_tgz_ve, encryption_info)
|
232
229
|
|
233
230
|
if local_fs:
|
234
231
|
local_layer.mount("/", local_fs)
|
235
232
|
|
236
233
|
|
234
|
+
def _decrypt_envelope(local_tgz_ve: TargetPath, encryption_info: TargetPath) -> BinaryIO:
|
235
|
+
"""Decrypt ``local.tgz.ve`` ourselves with hard-coded keys."""
|
236
|
+
envelope = Envelope(local_tgz_ve.open())
|
237
|
+
keystore = KeyStore.from_text(encryption_info.read_text("utf-8"))
|
238
|
+
local_tgz = BytesIO(envelope.decrypt(keystore.key, aad=b"ESXConfiguration"))
|
239
|
+
return local_tgz
|
240
|
+
|
241
|
+
|
242
|
+
def _decrypt_crypto_util(local_tgz_ve: TargetPath) -> Optional[BytesIO]:
|
243
|
+
"""Decrypt ``local.tgz.ve`` using ESXi ``crypto-util``.
|
244
|
+
|
245
|
+
We write to stdout, but this results in ``crypto-util`` exiting with a non-zero return code
|
246
|
+
and stderr containing an I/O error message. The file does get properly decrypted, so we return
|
247
|
+
``None`` if there are no bytes in stdout which would indicate it actually failed.
|
248
|
+
"""
|
249
|
+
|
250
|
+
result = subprocess.run(
|
251
|
+
["crypto-util", "envelope", "extract", "--aad", "ESXConfiguration", f"/{local_tgz_ve.as_posix()}", "-"],
|
252
|
+
capture_output=True,
|
253
|
+
)
|
254
|
+
|
255
|
+
if len(result.stdout) == 0:
|
256
|
+
return None
|
257
|
+
|
258
|
+
return BytesIO(result.stdout)
|
259
|
+
|
260
|
+
|
261
|
+
def _create_local_fs(
|
262
|
+
target: Target, local_tgz_ve: TargetPath, encryption_info: TargetPath
|
263
|
+
) -> Optional[tar.TarFilesystem]:
|
264
|
+
local_tgz = None
|
265
|
+
|
266
|
+
if HAS_ENVELOPE:
|
267
|
+
try:
|
268
|
+
local_tgz = _decrypt_envelope(local_tgz_ve, encryption_info)
|
269
|
+
except NotImplementedError:
|
270
|
+
target.log.debug("Failed to decrypt %s, likely TPM encrypted", local_tgz_ve)
|
271
|
+
else:
|
272
|
+
target.log.debug("Skipping static decryption because of missing crypto module")
|
273
|
+
|
274
|
+
if not local_tgz and target.name == "local":
|
275
|
+
target.log.info(
|
276
|
+
"local.tgz is encrypted but static decryption failed, attempting dynamic decryption using crypto-util"
|
277
|
+
)
|
278
|
+
local_tgz = _decrypt_crypto_util(local_tgz_ve)
|
279
|
+
|
280
|
+
if local_tgz is None:
|
281
|
+
target.log.warning("Dynamic decryption of %s failed.", local_tgz_ve)
|
282
|
+
else:
|
283
|
+
target.log.warning("local.tgz is encrypted but static decryption failed and no dynamic decryption available!")
|
284
|
+
|
285
|
+
if local_tgz:
|
286
|
+
return tar.TarFilesystem(local_tgz)
|
287
|
+
|
288
|
+
|
237
289
|
def _mount_filesystems(target: Target, sysvol: Filesystem, cfg: dict[str, str]):
|
238
290
|
version = cfg["build"]
|
239
291
|
|
@@ -13,6 +13,9 @@ from dissect.target.plugins.os.windows.datetime import parse_tzi
|
|
13
13
|
class EtlRecordBuilder:
|
14
14
|
RECORD_NAME = "filesystem/windows/etl"
|
15
15
|
|
16
|
+
def __init__(self):
|
17
|
+
self._create_event_descriptor = lru_cache(4096)(self._create_event_descriptor)
|
18
|
+
|
16
19
|
def _build_record(self, etl_event: Event, etl_path: Path, target: Target):
|
17
20
|
"""Builds an ETL event record"""
|
18
21
|
|
@@ -51,7 +54,6 @@ class EtlRecordBuilder:
|
|
51
54
|
desc = self._create_event_descriptor(tuple(record_fields))
|
52
55
|
return desc(**record_values)
|
53
56
|
|
54
|
-
@lru_cache(maxsize=4096)
|
55
57
|
def _create_event_descriptor(self, record_fields):
|
56
58
|
return TargetRecordDescriptor(self.RECORD_NAME, record_fields)
|
57
59
|
|
@@ -29,6 +29,7 @@ class EvtxPlugin(WindowsEventlogsMixin, plugin.Plugin):
|
|
29
29
|
|
30
30
|
def __init__(self, target):
|
31
31
|
super().__init__(target)
|
32
|
+
self._create_event_descriptor = lru_cache(4096)(self._create_event_descriptor)
|
32
33
|
|
33
34
|
@plugin.arg("--logs-dir", help="logs directory to scan")
|
34
35
|
@plugin.arg("--log-file-glob", default=EVTX_GLOB, help="glob pattern to match a log file name")
|
@@ -145,7 +146,6 @@ class EvtxPlugin(WindowsEventlogsMixin, plugin.Plugin):
|
|
145
146
|
desc = self._create_event_descriptor(tuple(record_fields))
|
146
147
|
return desc(**record_values)
|
147
148
|
|
148
|
-
@lru_cache(maxsize=4096)
|
149
149
|
def _create_event_descriptor(self, record_fields) -> TargetRecordDescriptor:
|
150
150
|
return TargetRecordDescriptor(self.RECORD_NAME, record_fields)
|
151
151
|
|
@@ -72,6 +72,7 @@ class RegistryPlugin(Plugin):
|
|
72
72
|
|
73
73
|
def __init__(self, target: Target) -> None:
|
74
74
|
super().__init__(target)
|
75
|
+
|
75
76
|
self._root = VirtualHive()
|
76
77
|
self._hive_collections = defaultdict(HiveCollection)
|
77
78
|
self._hive_paths = []
|
@@ -83,6 +84,8 @@ class RegistryPlugin(Plugin):
|
|
83
84
|
self._users_loaded = False
|
84
85
|
self._init_registry()
|
85
86
|
|
87
|
+
self.key = lru_cache(4096)(self.key)
|
88
|
+
|
86
89
|
def _init_registry(self) -> None:
|
87
90
|
dirs = [
|
88
91
|
("sysvol/windows/system32/config", False),
|
@@ -217,7 +220,6 @@ class RegistryPlugin(Plugin):
|
|
217
220
|
return self.key()
|
218
221
|
|
219
222
|
@internal
|
220
|
-
@lru_cache(4096)
|
221
223
|
def key(self, key: Optional[str] = None) -> KeyCollection:
|
222
224
|
"""Query the virtual registry on the given key.
|
223
225
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: dissect.target
|
3
|
-
Version: 3.16.
|
3
|
+
Version: 3.16.dev31
|
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
|
@@ -143,7 +143,7 @@ dissect/target/plugins/apps/webserver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCe
|
|
143
143
|
dissect/target/plugins/apps/webserver/apache.py,sha256=bD6_XObfO7W-cFlLRWyhdwEfw-Y57JBi47rWnXCx-vg,15026
|
144
144
|
dissect/target/plugins/apps/webserver/caddy.py,sha256=qZsAK_tILGvroV4SWkDKc-Otwd41bUEtv9H9TuHmt-0,6422
|
145
145
|
dissect/target/plugins/apps/webserver/citrix.py,sha256=FEPdBteEJeeGg3B95W_27O9wLJVhenEc5A5fSLDmK18,3044
|
146
|
-
dissect/target/plugins/apps/webserver/iis.py,sha256=
|
146
|
+
dissect/target/plugins/apps/webserver/iis.py,sha256=t92JGTuMbBlUma5BVurdOuzUYvrjpgT8NEHpu9Xz5F0,14734
|
147
147
|
dissect/target/plugins/apps/webserver/nginx.py,sha256=WA5soi1FU1c44oHRcyOoHK3gH8Jzc_Qi5uXcimDYukw,4129
|
148
148
|
dissect/target/plugins/apps/webserver/webserver.py,sha256=a7a2lLrhsa9c1AXnwiLP-tqVv-IUbmaVaSZI5S0fKa8,1500
|
149
149
|
dissect/target/plugins/child/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -201,7 +201,7 @@ dissect/target/plugins/os/unix/bsd/osx/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JC
|
|
201
201
|
dissect/target/plugins/os/unix/bsd/osx/_os.py,sha256=KvP7YJ7apVwoIop7MR-8q5QbVGoB6MdR42l6ssEe6es,4081
|
202
202
|
dissect/target/plugins/os/unix/bsd/osx/user.py,sha256=qopB0s3n7e6Q7NjWzn8Z-dKtDtU7e6In4Vm7hIvvedo,2322
|
203
203
|
dissect/target/plugins/os/unix/esxi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
204
|
-
dissect/target/plugins/os/unix/esxi/_os.py,sha256=
|
204
|
+
dissect/target/plugins/os/unix/esxi/_os.py,sha256=jqw71St-L_BiREai8bw27oFOrLK4_GuEDLUTK5FMGLU,17498
|
205
205
|
dissect/target/plugins/os/unix/linux/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
206
206
|
dissect/target/plugins/os/unix/linux/_os.py,sha256=YJYwuq_iAinOrPqTE49Q4DLYMWBeRCly1uTbDvPhp6Q,2796
|
207
207
|
dissect/target/plugins/os/unix/linux/cmdline.py,sha256=XIvaTL42DzeQGhqHN_RTMI5g8hbI2_wjzb7KZ0kPOM0,1591
|
@@ -261,7 +261,7 @@ dissect/target/plugins/os/windows/locale.py,sha256=yXVdclpUqss9h8Nq7N4kg3OHwWGDf
|
|
261
261
|
dissect/target/plugins/os/windows/notifications.py,sha256=64xHHueHwtJCc8RTAF70oa0RxvqfCu_DBPWRSZBnYZc,17386
|
262
262
|
dissect/target/plugins/os/windows/prefetch.py,sha256=5hRxdIP9sIV5Q9TAScMjLbl_mImZ37abvdE_pAd6rh4,10398
|
263
263
|
dissect/target/plugins/os/windows/recyclebin.py,sha256=4GSj0Q3YvONufnqANbnG0ffiMQyToCiL5s35Wmu4JOQ,4898
|
264
|
-
dissect/target/plugins/os/windows/registry.py,sha256=
|
264
|
+
dissect/target/plugins/os/windows/registry.py,sha256=EfqUkgbzaqTuq1kIPYNG1TfvJxhJE5X-TEjV3K_xsPU,12814
|
265
265
|
dissect/target/plugins/os/windows/sam.py,sha256=Es_8ROQ6R6-akuTtegCdsJHXzZJNhzgoFuS8y9xNN8E,15267
|
266
266
|
dissect/target/plugins/os/windows/services.py,sha256=_6YkuoZD8LUxk72R3n1p1bOBab3A1wszdB1NuPavIGM,6037
|
267
267
|
dissect/target/plugins/os/windows/sru.py,sha256=sOM7CyMkW8XIXzI75GL69WoqUrSK2X99TFIfdQR2D64,17767
|
@@ -280,9 +280,9 @@ dissect/target/plugins/os/windows/exchange/__init__.py,sha256=47DEQpj8HBSa-_TImW
|
|
280
280
|
dissect/target/plugins/os/windows/exchange/exchange.py,sha256=ofoapuDQXefIX4sTzwNboyk5RztN2JEyw1OWl5cx-wo,1564
|
281
281
|
dissect/target/plugins/os/windows/log/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
282
282
|
dissect/target/plugins/os/windows/log/amcache.py,sha256=TabtjNx9Ve-u-Fn0K95A0v_SLGzn2YeNPHrcQvjVKJc,5877
|
283
|
-
dissect/target/plugins/os/windows/log/etl.py,sha256=
|
283
|
+
dissect/target/plugins/os/windows/log/etl.py,sha256=Rau1zqPJ5LL91j59nC4Jg81KF2t1uuMx-oQp9JK0a00,7049
|
284
284
|
dissect/target/plugins/os/windows/log/evt.py,sha256=vK9XHc-hOxf6BbLKMNzGNlbCRWN2nlksQoCLdHqPgnw,7049
|
285
|
-
dissect/target/plugins/os/windows/log/evtx.py,sha256=
|
285
|
+
dissect/target/plugins/os/windows/log/evtx.py,sha256=C1JM64GW7z82qT9K9hIiyCv0EFxszFD9GVvtUZUHdL4,6096
|
286
286
|
dissect/target/plugins/os/windows/log/pfro.py,sha256=BCjg3OZzkIP4-HzRa1b1dPkDv_B4sbd78fl40obUVkM,2706
|
287
287
|
dissect/target/plugins/os/windows/log/schedlgu.py,sha256=vzMOcCSrGRTMNQUZzvyQorZzbTNgs1UJiPe0zeOOupQ,5515
|
288
288
|
dissect/target/plugins/os/windows/regf/7zip.py,sha256=Vc336zhS6R8W98GGlLtPJ_OR0vEP014QnBtYwbx_HUo,3217
|
@@ -331,10 +331,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z
|
|
331
331
|
dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
|
332
332
|
dissect/target/volumes/md.py,sha256=j1K1iKmspl0C_OJFc7-Q1BMWN2OCC5EVANIgVlJ_fIE,1673
|
333
333
|
dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
|
334
|
-
dissect.target-3.16.
|
335
|
-
dissect.target-3.16.
|
336
|
-
dissect.target-3.16.
|
337
|
-
dissect.target-3.16.
|
338
|
-
dissect.target-3.16.
|
339
|
-
dissect.target-3.16.
|
340
|
-
dissect.target-3.16.
|
334
|
+
dissect.target-3.16.dev31.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
|
335
|
+
dissect.target-3.16.dev31.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
336
|
+
dissect.target-3.16.dev31.dist-info/METADATA,sha256=bQJydAA40PRNfKgAuW4LJCissMW3rELgyfBIyapzadU,11107
|
337
|
+
dissect.target-3.16.dev31.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
338
|
+
dissect.target-3.16.dev31.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
|
339
|
+
dissect.target-3.16.dev31.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
|
340
|
+
dissect.target-3.16.dev31.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
{dissect.target-3.16.dev29.dist-info → dissect.target-3.16.dev31.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|