dissect.target 3.19.dev36__py3-none-any.whl → 3.19.dev38__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/helpers/record.py +37 -0
- dissect/target/loaders/libvirt.py +40 -0
- dissect/target/plugins/child/qemu.py +21 -0
- dissect/target/plugins/general/network.py +82 -0
- {dissect.target-3.19.dev36.dist-info → dissect.target-3.19.dev38.dist-info}/METADATA +1 -1
- {dissect.target-3.19.dev36.dist-info → dissect.target-3.19.dev38.dist-info}/RECORD +11 -8
- {dissect.target-3.19.dev36.dist-info → dissect.target-3.19.dev38.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.19.dev36.dist-info → dissect.target-3.19.dev38.dist-info}/LICENSE +0 -0
- {dissect.target-3.19.dev36.dist-info → dissect.target-3.19.dev38.dist-info}/WHEEL +0 -0
- {dissect.target-3.19.dev36.dist-info → dissect.target-3.19.dev38.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.19.dev36.dist-info → dissect.target-3.19.dev38.dist-info}/top_level.txt +0 -0
dissect/target/helpers/record.py
CHANGED
@@ -142,3 +142,40 @@ EmptyRecord = RecordDescriptor(
|
|
142
142
|
"empty",
|
143
143
|
[],
|
144
144
|
)
|
145
|
+
|
146
|
+
COMMON_INTERFACE_ELEMENTS = [
|
147
|
+
("string", "name"),
|
148
|
+
("string", "type"),
|
149
|
+
("boolean", "enabled"),
|
150
|
+
("string", "mac"),
|
151
|
+
("net.ipaddress[]", "dns"),
|
152
|
+
("net.ipaddress[]", "ip"),
|
153
|
+
("net.ipaddress[]", "gateway"),
|
154
|
+
("string", "source"),
|
155
|
+
]
|
156
|
+
|
157
|
+
|
158
|
+
UnixInterfaceRecord = TargetRecordDescriptor(
|
159
|
+
"unix/network/interface",
|
160
|
+
COMMON_INTERFACE_ELEMENTS,
|
161
|
+
)
|
162
|
+
|
163
|
+
WindowsInterfaceRecord = TargetRecordDescriptor(
|
164
|
+
"windows/network/interface",
|
165
|
+
[
|
166
|
+
*COMMON_INTERFACE_ELEMENTS,
|
167
|
+
("varint", "vlan"),
|
168
|
+
("string", "metric"),
|
169
|
+
("datetime", "last_connected"),
|
170
|
+
],
|
171
|
+
)
|
172
|
+
|
173
|
+
MacInterfaceRecord = TargetRecordDescriptor(
|
174
|
+
"macos/network/interface",
|
175
|
+
[
|
176
|
+
*COMMON_INTERFACE_ELEMENTS,
|
177
|
+
("varint", "vlan"),
|
178
|
+
("string", "proxy"),
|
179
|
+
("varint", "interface_service_order"),
|
180
|
+
],
|
181
|
+
)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
|
3
|
+
from defusedxml import ElementTree
|
4
|
+
|
5
|
+
from dissect.target import container
|
6
|
+
from dissect.target.helpers import fsutil
|
7
|
+
from dissect.target.loader import Loader
|
8
|
+
from dissect.target.target import Target
|
9
|
+
|
10
|
+
|
11
|
+
class LibvirtLoader(Loader):
|
12
|
+
"""Load libvirt xml configuration files."""
|
13
|
+
|
14
|
+
def __init__(self, path: Path, **kwargs):
|
15
|
+
path = path.resolve()
|
16
|
+
self.base_dir = path.parent
|
17
|
+
super().__init__(path)
|
18
|
+
|
19
|
+
@staticmethod
|
20
|
+
def detect(path: Path) -> bool:
|
21
|
+
if path.suffix.lower() != ".xml":
|
22
|
+
return False
|
23
|
+
|
24
|
+
with path.open("rb") as fh:
|
25
|
+
lines = fh.read(512).split(b"\n")
|
26
|
+
# From what I've seen, these are are always at the start of the file
|
27
|
+
# If its generated using virt-install
|
28
|
+
needles = [b"<domain", b"<name>", b"<uuid>"]
|
29
|
+
return all(any(needle in line for line in lines) for needle in needles)
|
30
|
+
|
31
|
+
def map(self, target: Target) -> None:
|
32
|
+
xml_data = ElementTree.fromstring(self.path.read_text())
|
33
|
+
for disk in xml_data.findall("devices/disk/source"):
|
34
|
+
if not (file := disk.get("file")):
|
35
|
+
continue
|
36
|
+
|
37
|
+
for part in [fsutil.basename(file), file]:
|
38
|
+
if (path := self.base_dir.joinpath(part)).exists():
|
39
|
+
target.disks.add(container.open(path))
|
40
|
+
break
|
@@ -0,0 +1,21 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import Iterator
|
4
|
+
|
5
|
+
from dissect.target.exceptions import UnsupportedPluginError
|
6
|
+
from dissect.target.helpers.record import ChildTargetRecord
|
7
|
+
from dissect.target.plugin import ChildTargetPlugin
|
8
|
+
|
9
|
+
|
10
|
+
class QemuChildTargetPlugin(ChildTargetPlugin):
|
11
|
+
"""Child target plugin that yields all QEMU domains from a KVM libvirt deamon."""
|
12
|
+
|
13
|
+
__type__ = "qemu"
|
14
|
+
|
15
|
+
def check_compatible(self) -> None:
|
16
|
+
if not self.target.fs.path("/etc/libvirt/qemu").exists():
|
17
|
+
raise UnsupportedPluginError("No libvirt QEMU installation found")
|
18
|
+
|
19
|
+
def list_children(self) -> Iterator[ChildTargetRecord]:
|
20
|
+
for domain in self.target.fs.path("/etc/libvirt/qemu").glob("*.xml"):
|
21
|
+
yield ChildTargetRecord(type=self.__type__, path=domain)
|
@@ -0,0 +1,82 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import Any, Iterator, Union
|
4
|
+
|
5
|
+
from flow.record.fieldtypes.net import IPAddress, IPNetwork
|
6
|
+
|
7
|
+
from dissect.target.helpers.record import (
|
8
|
+
MacInterfaceRecord,
|
9
|
+
UnixInterfaceRecord,
|
10
|
+
WindowsInterfaceRecord,
|
11
|
+
)
|
12
|
+
from dissect.target.plugin import Plugin, export, internal
|
13
|
+
from dissect.target.target import Target
|
14
|
+
|
15
|
+
InterfaceRecord = Union[UnixInterfaceRecord, WindowsInterfaceRecord, MacInterfaceRecord]
|
16
|
+
|
17
|
+
|
18
|
+
class NetworkPlugin(Plugin):
|
19
|
+
__namespace__ = "network"
|
20
|
+
|
21
|
+
def __init__(self, target: Target):
|
22
|
+
super().__init__(target)
|
23
|
+
self._interface_list: list[InterfaceRecord] | None = None
|
24
|
+
|
25
|
+
def check_compatible(self) -> None:
|
26
|
+
pass
|
27
|
+
|
28
|
+
def _interfaces(self) -> Iterator[InterfaceRecord]:
|
29
|
+
yield from ()
|
30
|
+
|
31
|
+
def _get_record_type(self, field_name: str) -> Iterator[Any]:
|
32
|
+
for record in self.interfaces():
|
33
|
+
if (output := getattr(record, field_name, None)) is None:
|
34
|
+
continue
|
35
|
+
|
36
|
+
if isinstance(output, list):
|
37
|
+
yield from output
|
38
|
+
else:
|
39
|
+
yield output
|
40
|
+
|
41
|
+
@export(record=InterfaceRecord)
|
42
|
+
def interfaces(self) -> Iterator[InterfaceRecord]:
|
43
|
+
# Only search for the interfaces once
|
44
|
+
if self._interface_list is None:
|
45
|
+
self._interface_list = list(self._interfaces())
|
46
|
+
|
47
|
+
yield from self._interface_list
|
48
|
+
|
49
|
+
@export
|
50
|
+
def ips(self) -> list[IPAddress]:
|
51
|
+
return list(self._get_record_type("ip"))
|
52
|
+
|
53
|
+
@export
|
54
|
+
def gateways(self) -> list[IPAddress]:
|
55
|
+
return list(self._get_record_type("gateway"))
|
56
|
+
|
57
|
+
@export
|
58
|
+
def macs(self) -> list[str]:
|
59
|
+
return list(self._get_record_type("mac"))
|
60
|
+
|
61
|
+
@export
|
62
|
+
def dns(self) -> list[str]:
|
63
|
+
return list(self._get_record_type("dns"))
|
64
|
+
|
65
|
+
@internal
|
66
|
+
def with_ip(self, ip_addr: str) -> Iterator[InterfaceRecord]:
|
67
|
+
for interface in self.interfaces():
|
68
|
+
if ip_addr in interface.ip:
|
69
|
+
yield interface
|
70
|
+
|
71
|
+
@internal
|
72
|
+
def with_mac(self, mac: str) -> Iterator[InterfaceRecord]:
|
73
|
+
for interface in self.interfaces():
|
74
|
+
if interface.mac == mac:
|
75
|
+
yield interface
|
76
|
+
|
77
|
+
@internal
|
78
|
+
def in_cidr(self, cidr: str) -> Iterator[InterfaceRecord]:
|
79
|
+
cidr = IPNetwork(cidr)
|
80
|
+
for interface in self.interfaces():
|
81
|
+
if any(ip_addr in cidr for ip_addr in interface.ip):
|
82
|
+
yield interface
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: dissect.target
|
3
|
-
Version: 3.19.
|
3
|
+
Version: 3.19.dev38
|
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
|
@@ -61,7 +61,7 @@ dissect/target/helpers/mui.py,sha256=i-7XoHbu4WO2fYapK9yGAMW04rFlgRispknc1KQIS5Q
|
|
61
61
|
dissect/target/helpers/network_managers.py,sha256=ByBSe2K3c8hgQC6dokcf-hHdmPcD8PmrOj0xs1C3yhs,25743
|
62
62
|
dissect/target/helpers/polypath.py,sha256=h8p7m_OCNiQljGwoZh5Aflr9H2ot6CZr6WKq1OSw58o,2175
|
63
63
|
dissect/target/helpers/protobuf.py,sha256=b4DsnqrRLrefcDjx7rQno-_LBcwtJXxuKf5RdOegzfE,1537
|
64
|
-
dissect/target/helpers/record.py,sha256=
|
64
|
+
dissect/target/helpers/record.py,sha256=zwqEnFSgxgX6JdhhF4zycMMZK09crCTWWEFzRxZSuC8,5658
|
65
65
|
dissect/target/helpers/record_modifier.py,sha256=3I_rC5jqvl0TsW3V8OQ6Dltz_D8J4PU1uhhzbJGKm9c,3245
|
66
66
|
dissect/target/helpers/regutil.py,sha256=kX-sSZbW8Qkg29Dn_9zYbaQrwLumrr4Y8zJ1EhHXIAM,27337
|
67
67
|
dissect/target/helpers/shell_folder_ids.py,sha256=Behhb8oh0kMxrEk6YYKYigCDZe8Hw5QS6iK_d2hTs2Y,24978
|
@@ -84,6 +84,7 @@ dissect/target/loaders/dir.py,sha256=F-PgvBw82XmL0rdKyBxznUkDc5Oct6-_Y9xM4fhvA6I
|
|
84
84
|
dissect/target/loaders/hyperv.py,sha256=_IOUJEO0BXaCBZ6sjIX0DZTkG9UNW5Vs9VcNHYv073w,5928
|
85
85
|
dissect/target/loaders/itunes.py,sha256=rKOhlDRypQBGkuSZudMDS1Mlb9XV6BD5FRvM7tGq9jU,13128
|
86
86
|
dissect/target/loaders/kape.py,sha256=t5TfrGLqPeIpUUpXzIl6aHsqXMEGDqJ5YwDCs07DiBA,1237
|
87
|
+
dissect/target/loaders/libvirt.py,sha256=_3EFIytMGbiLMISHx4QXVrDebsRO6J6sMkE3TH68qsg,1374
|
87
88
|
dissect/target/loaders/local.py,sha256=Ul-LCd_fY7SyWOVR6nH-NqbkuNpxoZVmffwrkvQElU8,16453
|
88
89
|
dissect/target/loaders/log.py,sha256=cCkDIRS4aPlX3U-n_jUKaI2FPSV3BDpfqKceaU7rBbo,1507
|
89
90
|
dissect/target/loaders/mqtt.py,sha256=pn2VtFh0jeYXMod4CuZOKGhe2ScQixJ1Xhx6MHe0rzk,16540
|
@@ -155,6 +156,7 @@ dissect/target/plugins/child/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
|
|
155
156
|
dissect/target/plugins/child/docker.py,sha256=frBZ8UUzbtkT9VrK1fwUzXDAdkHESdPCb-QI_OP9Jj4,872
|
156
157
|
dissect/target/plugins/child/esxi.py,sha256=GfgQzxntcHcyxAE2QjMJ-TrFhklweSXLbYh0uuv-klg,693
|
157
158
|
dissect/target/plugins/child/hyperv.py,sha256=R2qVeu4p_9V53jO-65znN0LwX9v3FVA-9jbbtOQcEz8,2236
|
159
|
+
dissect/target/plugins/child/qemu.py,sha256=vNzQwzFO964jYaI67MlX8vpWyHxpegjIU5F29zHKOGI,791
|
158
160
|
dissect/target/plugins/child/virtuozzo.py,sha256=Mx4ZxEl21g7IYkzraw4FBZup5EfrkFDv4WuTE3hxguw,1206
|
159
161
|
dissect/target/plugins/child/vmware_workstation.py,sha256=8wkA_tSufvBUyp4XQHzRzFETf5ROlyyO_MVS3TExyfw,1570
|
160
162
|
dissect/target/plugins/child/wsl.py,sha256=IssQgYET1T-XR5ZX2lGlNFJ_u_3QECpMF_7kXu09HTE,2469
|
@@ -178,6 +180,7 @@ dissect/target/plugins/general/config.py,sha256=Mdy9uhWn4OJ96zfXpLgjVifV5SrViqHn
|
|
178
180
|
dissect/target/plugins/general/default.py,sha256=8W_9JV3jKEeETlyTrB25sACoIIFmmO8wlVU5Zoi51W0,1425
|
179
181
|
dissect/target/plugins/general/example.py,sha256=6B_YOqajRBLNWBEOfIL_HnLaEANBF8KKoc0mweihiug,6034
|
180
182
|
dissect/target/plugins/general/loaders.py,sha256=6iUxhlSAgo7qSE8_XFxgiihK8sdMiP-s4k0W5Iv8m9k,879
|
183
|
+
dissect/target/plugins/general/network.py,sha256=Ol4Ls1w78-7zpmVaQQOZG27rvYOhJLFVhomZj5kwibs,2430
|
181
184
|
dissect/target/plugins/general/osinfo.py,sha256=RdK5mw3-H9H3sGXz8yP8U_p3wUG1Ww7_HBKZpFdsbTE,1358
|
182
185
|
dissect/target/plugins/general/plugins.py,sha256=4URjS6DN1Ey6Cqlbyx6NfFGgQZpWDrqxl8KLcZFODGE,4479
|
183
186
|
dissect/target/plugins/general/scrape.py,sha256=Fz7BNXflvuxlnVulyyDhLpyU8D_hJdH6vWVtER9vjTg,6651
|
@@ -346,10 +349,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z
|
|
346
349
|
dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
|
347
350
|
dissect/target/volumes/md.py,sha256=7ShPtusuLGaIv27SvEETtgsuoQyAa4iAAeOR1NEaajI,1689
|
348
351
|
dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
|
349
|
-
dissect.target-3.19.
|
350
|
-
dissect.target-3.19.
|
351
|
-
dissect.target-3.19.
|
352
|
-
dissect.target-3.19.
|
353
|
-
dissect.target-3.19.
|
354
|
-
dissect.target-3.19.
|
355
|
-
dissect.target-3.19.
|
352
|
+
dissect.target-3.19.dev38.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
|
353
|
+
dissect.target-3.19.dev38.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
354
|
+
dissect.target-3.19.dev38.dist-info/METADATA,sha256=moRisLjdf7BN29AYj8cVY3tFh8VxpOVFuU-EfD8f8W0,12719
|
355
|
+
dissect.target-3.19.dev38.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
356
|
+
dissect.target-3.19.dev38.dist-info/entry_points.txt,sha256=BWuxAb_6AvUAQpIQOQU0IMTlaF6TDht2AIZK8bHd-zE,492
|
357
|
+
dissect.target-3.19.dev38.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
|
358
|
+
dissect.target-3.19.dev38.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
{dissect.target-3.19.dev36.dist-info → dissect.target-3.19.dev38.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|