dissect.target 3.20.dev59__py3-none-any.whl → 3.20.dev61__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
File without changes
@@ -0,0 +1,103 @@
1
+ import re
2
+ from datetime import datetime, timezone
3
+ from typing import Iterator
4
+
5
+ from dissect.target.exceptions import UnsupportedPluginError
6
+ from dissect.target.helpers.fsutil import TargetPath
7
+ from dissect.target.helpers.record import TargetRecordDescriptor
8
+ from dissect.target.plugin import Plugin, export
9
+ from dissect.target.target import Target
10
+
11
+ MssqlErrorlogRecord = TargetRecordDescriptor(
12
+ "microsoft/sql/errorlog",
13
+ [
14
+ ("datetime", "ts"),
15
+ ("string", "instance"),
16
+ ("string", "process"),
17
+ ("string", "message"),
18
+ ("path", "path"),
19
+ ],
20
+ )
21
+
22
+ RE_TIMESTAMP_PATTERN = re.compile(r"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{2}")
23
+
24
+
25
+ class MssqlPlugin(Plugin):
26
+ """Return information related to Microsoft SQL Server.
27
+
28
+ Currently returns ERRORLOG messages. These log files contain information such as:
29
+ - Logon failures
30
+ - Enabling/disabling of features, such as xp_cmdshell
31
+
32
+ References:
33
+ - https://learn.microsoft.com/en-us/sql/relational-databases/logs/view-offline-log-files
34
+ """
35
+
36
+ __namespace__ = "mssql"
37
+
38
+ MSSQL_KEY = "HKLM\\SOFTWARE\\Microsoft\\Microsoft SQL Server"
39
+ FILE_GLOB = "ERRORLOG*"
40
+
41
+ def __init__(self, target: Target):
42
+ super().__init__(target)
43
+ self.instances = self._find_instances()
44
+
45
+ def check_compatible(self) -> None:
46
+ if not self.instances:
47
+ raise UnsupportedPluginError("System does not seem to be running SQL Server")
48
+
49
+ @export(record=MssqlErrorlogRecord)
50
+ def errorlog(self) -> Iterator[MssqlErrorlogRecord]:
51
+ """Return all Microsoft SQL Server ERRORLOG messages.
52
+
53
+ These log files contain information such as:
54
+ - Logon failures
55
+ - Enabling/disabling of features, such as xp_cmdshell
56
+
57
+ Yields MssqlErrorlogRecord instances with fields:
58
+
59
+ .. code-block:: text
60
+
61
+ ts (datetime): Timestamp of the log line.
62
+ instance (str): SQL Server instance name.
63
+ process (str): Process name.
64
+ message (str): Log message.
65
+ path (Path): Path to the log file.
66
+
67
+ References:
68
+ - https://learn.microsoft.com/en-us/sql/relational-databases/logs/view-offline-log-files
69
+ """
70
+
71
+ for instance, log_path in self.instances:
72
+ for errorlog in log_path.glob(self.FILE_GLOB):
73
+ # The errorlog includes a BOM, so endianess gets determined automatically
74
+ fh = errorlog.open(mode="rt", encoding="utf-16", errors="surrogateescape")
75
+ buf = ""
76
+
77
+ for line in fh:
78
+ if ts := RE_TIMESTAMP_PATTERN.match(line):
79
+ yield MssqlErrorlogRecord(
80
+ ts=datetime.strptime(ts.group(), "%Y-%m-%d %H:%M:%S.%f").replace(tzinfo=timezone.utc),
81
+ instance=instance,
82
+ # The process name is a fixed-width field and is always 12 characters long.
83
+ process=buf[23:35].strip(),
84
+ message=buf[35:].strip(),
85
+ path=errorlog,
86
+ _target=self.target,
87
+ )
88
+ buf = ""
89
+
90
+ buf += line
91
+
92
+ def _find_instances(self) -> list[str, TargetPath]:
93
+ instances = []
94
+
95
+ for subkey in self.target.registry.key(self.MSSQL_KEY).subkeys():
96
+ if subkey.name.startswith("MSSQL") and "." in subkey.name:
97
+ instances.append(
98
+ (
99
+ subkey.name,
100
+ self.target.fs.path(subkey.subkey("SQLServerAgent").value("ErrorLogFile").value).parent,
101
+ )
102
+ )
103
+ return instances
@@ -257,7 +257,8 @@ class WindowsNetworkPlugin(NetworkPlugin):
257
257
  continue
258
258
 
259
259
  # Extract the network device configuration for given interface id
260
- config = self._extract_network_device_config(net_cfg_instance_id)
260
+ if not (config := self._extract_network_device_config(net_cfg_instance_id)):
261
+ continue
261
262
 
262
263
  # Extract a network device name for given interface id
263
264
  try:
@@ -313,9 +314,7 @@ class WindowsNetworkPlugin(NetworkPlugin):
313
314
  _target=self.target,
314
315
  )
315
316
 
316
- def _extract_network_device_config(
317
- self, interface_id: str
318
- ) -> list[dict[str, str | list], dict[str, str | list]] | None:
317
+ def _extract_network_device_config(self, interface_id: str) -> list[dict[str, set | bool | None]]:
319
318
  """Extract network device configuration from the given interface_id for all ControlSets on the system."""
320
319
 
321
320
  dhcp_config = {
@@ -344,10 +343,10 @@ class WindowsNetworkPlugin(NetworkPlugin):
344
343
  )
345
344
  )
346
345
  except RegistryKeyNotFoundError:
347
- return None
346
+ return []
348
347
 
349
348
  if not len(keys):
350
- return None
349
+ return []
351
350
 
352
351
  for key in keys:
353
352
  # Extract DHCP configuration from the registry
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dissect.target
3
- Version: 3.20.dev59
3
+ Version: 3.20.dev61
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
@@ -128,6 +128,7 @@ dissect/target/plugins/apps/browser/firefox.py,sha256=mZBBagFfIdiz9kUyK4Hi989I4g
128
128
  dissect/target/plugins/apps/browser/iexplore.py,sha256=g_xw0toaiyjevxO8g9XPCOqc-CXZp39FVquRhPFGdTE,8801
129
129
  dissect/target/plugins/apps/container/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
130
130
  dissect/target/plugins/apps/container/docker.py,sha256=LTsZplaECSfO1Ysp_Y-9WsnNocsreu_iHO8fbSif3g0,16221
131
+ dissect/target/plugins/apps/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
131
132
  dissect/target/plugins/apps/editor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
132
133
  dissect/target/plugins/apps/editor/editor.py,sha256=yJctXY0XTfwW3GKy6XLO2WaWFQLssdBck9ZOcZSyf80,495
133
134
  dissect/target/plugins/apps/editor/windowsnotepad.py,sha256=A9cfFrqbU2zjHRrzYsCnXr-uxKAIsVIKdXXJPYMt6MU,15068
@@ -288,7 +289,7 @@ dissect/target/plugins/os/windows/generic.py,sha256=RJ1znzsIa4CFxmdMh91SjMY_pnjw
288
289
  dissect/target/plugins/os/windows/jumplist.py,sha256=3gZk6O1B3lKK2Jxe0B-HapOCEehk94CYNvCVDpQC9nQ,11773
289
290
  dissect/target/plugins/os/windows/lnk.py,sha256=KTqhw0JMW-KjAxe4xlRDNSRSx-th-_nPVgTGyBaKmW0,7891
290
291
  dissect/target/plugins/os/windows/locale.py,sha256=QiLWGgWrGBGHiXgep5iSOo6VNim4YC-xd4MdW0BUJPA,2486
291
- dissect/target/plugins/os/windows/network.py,sha256=cffJmQwHJmTAGZkAEKKGxNi1ZYLiDomfOcPczZn85Fo,11284
292
+ dissect/target/plugins/os/windows/network.py,sha256=ni-qK1PyA3UJD3lRJZGEBLAXcwDVKXPa3rIor9G5OSw,11283
292
293
  dissect/target/plugins/os/windows/notifications.py,sha256=xxfMEY_noDxMVqvT3QS1a3j-X3qAYikOtT6v2owxuCY,17480
293
294
  dissect/target/plugins/os/windows/prefetch.py,sha256=wbbYoy05gWbJfRsM2ci4wPG7kM58OocVwXD3hkQlbRw,10647
294
295
  dissect/target/plugins/os/windows/recyclebin.py,sha256=zx58hDCvcrD_eJl9nJmr_i80krSN03ya8nQzWFr2Tw0,4917
@@ -327,6 +328,7 @@ dissect/target/plugins/os/windows/log/amcache.py,sha256=TabtjNx9Ve-u-Fn0K95A0v_S
327
328
  dissect/target/plugins/os/windows/log/etl.py,sha256=t5GpunjzYMvAO9CBOP1ynH6053_PlasnIEIvlLNLU10,7255
328
329
  dissect/target/plugins/os/windows/log/evt.py,sha256=pYRVK3u309yK5pJoogohHWV2a_Lev8FK2zte_ys4SN8,7133
329
330
  dissect/target/plugins/os/windows/log/evtx.py,sha256=eSnMkU7HRmIDZ19WRsF9li08HuEOo51pRJDN2JOua5U,6148
331
+ dissect/target/plugins/os/windows/log/mssql.py,sha256=sn9LZvKTaam15G1Vl2BZp2P6uph7_jw03L8P9NjlMKw,3745
330
332
  dissect/target/plugins/os/windows/log/pfro.py,sha256=d53Mm7ovZa9crSwVRPwjMVxTd_jCGtE1Kv07GslX9_s,2789
331
333
  dissect/target/plugins/os/windows/log/schedlgu.py,sha256=JaP8H8eTEypWXhx2aFSR_IMam6rQiksbLKhMr_U4fz8,5570
332
334
  dissect/target/plugins/os/windows/regf/7zip.py,sha256=Ox8cLyQtbyYQS7m4eY3onNv1K8N2IkS5wexrC55Urd4,3444
@@ -378,10 +380,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z
378
380
  dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
379
381
  dissect/target/volumes/md.py,sha256=7ShPtusuLGaIv27SvEETtgsuoQyAa4iAAeOR1NEaajI,1689
380
382
  dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
381
- dissect.target-3.20.dev59.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
382
- dissect.target-3.20.dev59.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
383
- dissect.target-3.20.dev59.dist-info/METADATA,sha256=jkede6QAkD-RIMxW9TfSPDOO8cQxqBbjazWLI3vudys,13025
384
- dissect.target-3.20.dev59.dist-info/WHEEL,sha256=a7TGlA-5DaHMRrarXjVbQagU3Man_dCnGIWMJr5kRWo,91
385
- dissect.target-3.20.dev59.dist-info/entry_points.txt,sha256=BWuxAb_6AvUAQpIQOQU0IMTlaF6TDht2AIZK8bHd-zE,492
386
- dissect.target-3.20.dev59.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
387
- dissect.target-3.20.dev59.dist-info/RECORD,,
383
+ dissect.target-3.20.dev61.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
384
+ dissect.target-3.20.dev61.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
385
+ dissect.target-3.20.dev61.dist-info/METADATA,sha256=-UoGAGzSWeMRJrJOnPGHVZc5KAIQZmIlaomMH2tLE68,13025
386
+ dissect.target-3.20.dev61.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
387
+ dissect.target-3.20.dev61.dist-info/entry_points.txt,sha256=BWuxAb_6AvUAQpIQOQU0IMTlaF6TDht2AIZK8bHd-zE,492
388
+ dissect.target-3.20.dev61.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
389
+ dissect.target-3.20.dev61.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.4.0)
2
+ Generator: setuptools (75.5.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5