dissect.target 3.19.dev16__py3-none-any.whl → 3.19.dev18__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/configutil.py +65 -1
- dissect/target/plugins/os/windows/lnk.py +12 -4
- {dissect.target-3.19.dev16.dist-info → dissect.target-3.19.dev18.dist-info}/METADATA +1 -1
- {dissect.target-3.19.dev16.dist-info → dissect.target-3.19.dev18.dist-info}/RECORD +9 -9
- {dissect.target-3.19.dev16.dist-info → dissect.target-3.19.dev18.dist-info}/WHEEL +1 -1
- {dissect.target-3.19.dev16.dist-info → dissect.target-3.19.dev18.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.19.dev16.dist-info → dissect.target-3.19.dev18.dist-info}/LICENSE +0 -0
- {dissect.target-3.19.dev16.dist-info → dissect.target-3.19.dev18.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.19.dev16.dist-info → dissect.target-3.19.dev18.dist-info}/top_level.txt +0 -0
@@ -240,6 +240,33 @@ class Default(ConfigurationParser):
|
|
240
240
|
self.parsed_data = information_dict
|
241
241
|
|
242
242
|
|
243
|
+
class CSVish(Default):
|
244
|
+
"""Parses CSV-ish config files (does not confirm to CSV standard!)"""
|
245
|
+
|
246
|
+
def __init__(self, *args, fields: tuple[str], **kwargs) -> None:
|
247
|
+
self.fields = fields
|
248
|
+
self.num_fields = len(self.fields)
|
249
|
+
self.maxsplit = self.num_fields - 1
|
250
|
+
super().__init__(*args, **kwargs)
|
251
|
+
|
252
|
+
def parse_file(self, fh: TextIO) -> None:
|
253
|
+
information_dict = {}
|
254
|
+
|
255
|
+
for i, raw_line in enumerate(self.line_reader(fh, strip_comments=True)):
|
256
|
+
line = raw_line.strip()
|
257
|
+
columns = re.split(self.SEPARATOR, line, maxsplit=self.maxsplit)
|
258
|
+
|
259
|
+
if len(columns) < self.num_fields:
|
260
|
+
# keep unparsed lines separate (often env vars)
|
261
|
+
data = {"line": line}
|
262
|
+
else:
|
263
|
+
data = dict(zip(self.fields, columns))
|
264
|
+
|
265
|
+
information_dict[str(i)] = data
|
266
|
+
|
267
|
+
self.parsed_data = information_dict
|
268
|
+
|
269
|
+
|
243
270
|
class Ini(ConfigurationParser):
|
244
271
|
"""Parses an ini file according using the built-in python ConfigParser"""
|
245
272
|
|
@@ -688,11 +715,12 @@ class ParserConfig:
|
|
688
715
|
collapse_inverse: Optional[bool] = None
|
689
716
|
separator: Optional[tuple[str]] = None
|
690
717
|
comment_prefixes: Optional[tuple[str]] = None
|
718
|
+
fields: Optional[tuple[str]] = None
|
691
719
|
|
692
720
|
def create_parser(self, options: Optional[ParserOptions] = None) -> ConfigurationParser:
|
693
721
|
kwargs = {}
|
694
722
|
|
695
|
-
for field_name in ["collapse", "collapse_inverse", "separator", "comment_prefixes"]:
|
723
|
+
for field_name in ["collapse", "collapse_inverse", "separator", "comment_prefixes", "fields"]:
|
696
724
|
value = getattr(options, field_name, None) or getattr(self, field_name)
|
697
725
|
if value:
|
698
726
|
kwargs.update({field_name: value})
|
@@ -721,6 +749,7 @@ CONFIG_MAP: dict[tuple[str, ...], ParserConfig] = {
|
|
721
749
|
"toml": ParserConfig(Toml),
|
722
750
|
}
|
723
751
|
|
752
|
+
|
724
753
|
KNOWN_FILES: dict[str, type[ConfigurationParser]] = {
|
725
754
|
"ulogd.conf": ParserConfig(Ini),
|
726
755
|
"sshd_config": ParserConfig(Indentation, separator=(r"\s",)),
|
@@ -730,6 +759,41 @@ KNOWN_FILES: dict[str, type[ConfigurationParser]] = {
|
|
730
759
|
"nsswitch.conf": ParserConfig(Default, separator=(":",)),
|
731
760
|
"lsb-release": ParserConfig(Default),
|
732
761
|
"catalog": ParserConfig(Xml),
|
762
|
+
"fstab": ParserConfig(
|
763
|
+
CSVish,
|
764
|
+
separator=(r"\s",),
|
765
|
+
comment_prefixes=("#",),
|
766
|
+
fields=("device", "mount", "type", "options", "dump", "pass"),
|
767
|
+
),
|
768
|
+
"crontab": ParserConfig(
|
769
|
+
CSVish,
|
770
|
+
separator=(r"\s",),
|
771
|
+
comment_prefixes=("#",),
|
772
|
+
fields=("minute", "hour", "day", "month", "weekday", "user", "command"),
|
773
|
+
),
|
774
|
+
"shadow": ParserConfig(
|
775
|
+
CSVish,
|
776
|
+
separator=(r"\:",),
|
777
|
+
comment_prefixes=("#",),
|
778
|
+
fields=(
|
779
|
+
"username",
|
780
|
+
"password",
|
781
|
+
"lastchange",
|
782
|
+
"minpassage",
|
783
|
+
"maxpassage",
|
784
|
+
"warning",
|
785
|
+
"inactive",
|
786
|
+
"expire",
|
787
|
+
"rest",
|
788
|
+
),
|
789
|
+
),
|
790
|
+
"passwd": ParserConfig(
|
791
|
+
CSVish,
|
792
|
+
separator=(r"\:",),
|
793
|
+
comment_prefixes=("#",),
|
794
|
+
fields=("username", "password", "uid", "gid", "gecos", "homedir", "shell"),
|
795
|
+
),
|
796
|
+
"mime.types": ParserConfig(CSVish, separator=(r"\s+",), comment_prefixes=("#",), fields=("name", "extensions")),
|
733
797
|
}
|
734
798
|
|
735
799
|
|
@@ -45,9 +45,9 @@ class LnkPlugin(Plugin):
|
|
45
45
|
return None
|
46
46
|
raise UnsupportedPluginError("No folders containing link files found")
|
47
47
|
|
48
|
-
@arg("--
|
48
|
+
@arg("--path", "-p", dest="path", default=None, help="Path to directory or .lnk file in target")
|
49
49
|
@export(record=LnkRecord)
|
50
|
-
def lnk(self,
|
50
|
+
def lnk(self, path: Optional[str] = None) -> Iterator[LnkRecord]:
|
51
51
|
"""Parse all .lnk files in /ProgramData, /Users, and /Windows or from a specified path in record format.
|
52
52
|
|
53
53
|
Yields a LnkRecord record with the following fields:
|
@@ -77,7 +77,7 @@ class LnkPlugin(Plugin):
|
|
77
77
|
# we need to get the active codepage from the system to properly decode some values
|
78
78
|
codepage = self.target.codepage or "ascii"
|
79
79
|
|
80
|
-
for entry in self.lnk_entries(
|
80
|
+
for entry in self.lnk_entries(path):
|
81
81
|
lnk_file = Lnk(entry.open())
|
82
82
|
lnk_net_name = lnk_device_name = None
|
83
83
|
|
@@ -168,7 +168,15 @@ class LnkPlugin(Plugin):
|
|
168
168
|
|
169
169
|
def lnk_entries(self, path: Optional[str] = None) -> Iterator[TargetPath]:
|
170
170
|
if path:
|
171
|
-
|
171
|
+
target_path = self.target.fs.path(path)
|
172
|
+
if not target_path.exists():
|
173
|
+
self.target.log.error("Provided path %s does not exist on target", target_path)
|
174
|
+
return
|
175
|
+
|
176
|
+
if target_path.is_file():
|
177
|
+
yield target_path
|
178
|
+
else:
|
179
|
+
yield from target_path.rglob("*.lnk")
|
172
180
|
else:
|
173
181
|
for folder in self.folders:
|
174
182
|
yield from self.target.fs.path("sysvol").joinpath(folder).rglob("*.lnk")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: dissect.target
|
3
|
-
Version: 3.19.
|
3
|
+
Version: 3.19.dev18
|
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
|
@@ -46,7 +46,7 @@ dissect/target/filesystems/zip.py,sha256=WT1bQhzX_1MXXVZTKrJniae4xqRqMZ8FsfbvhgG
|
|
46
46
|
dissect/target/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
47
47
|
dissect/target/helpers/cache.py,sha256=TXlJBdFRz6V9zKs903am4Yawr0maYw5kZY0RqklDQJM,8568
|
48
48
|
dissect/target/helpers/config.py,sha256=6917CZ6eDHaK_tOoiVEIndyhRXO6r6eCBIleq6f47PQ,2346
|
49
|
-
dissect/target/helpers/configutil.py,sha256=
|
49
|
+
dissect/target/helpers/configutil.py,sha256=SLJFt_k5ezm7CIr_mcZqVrV-2YrcX5D48KgyC9oyWGw,27645
|
50
50
|
dissect/target/helpers/cyber.py,sha256=WnJlk-HqAETmDAgLq92JPxyDLxvzSoFV_WrO-odVKBI,16805
|
51
51
|
dissect/target/helpers/descriptor_extensions.py,sha256=uT8GwznfDAiIgMM7JKKOY0PXKMv2c0GCqJTCkWFgops,2605
|
52
52
|
dissect/target/helpers/docs.py,sha256=J5U65Y3yOTqxDEZRCdrEmO63XQCeDzOJea1PwPM6Cyc,5146
|
@@ -266,7 +266,7 @@ dissect/target/plugins/os/windows/datetime.py,sha256=YKHUZU6lkKJocq15y0yCwvIIOb1
|
|
266
266
|
dissect/target/plugins/os/windows/defender.py,sha256=zh3brEvJmknD5ef0PGuLZ1G95Fgdh-dlgi-ZEbADKXo,32716
|
267
267
|
dissect/target/plugins/os/windows/env.py,sha256=-u9F9xWy6PUbQmu5Tv_MDoVmy6YB-7CbHokIK_T3S44,13891
|
268
268
|
dissect/target/plugins/os/windows/generic.py,sha256=BSvDPfB9faU0uquMj0guw5tnR_97Nn0XAEE4k05BFSQ,22273
|
269
|
-
dissect/target/plugins/os/windows/lnk.py,sha256=
|
269
|
+
dissect/target/plugins/os/windows/lnk.py,sha256=2zpzpPbxL1qrxdbiZfhOGWKNujcj9tMy75_KrBXB1QE,8485
|
270
270
|
dissect/target/plugins/os/windows/locale.py,sha256=yXVdclpUqss9h8Nq7N4kg3OHwWGDfjdfiLiUZR3wqv8,2324
|
271
271
|
dissect/target/plugins/os/windows/notifications.py,sha256=T1CIvQgpW__qDR0Rq5zpeWmRWwjNDpvdMnvJJ_6tZXs,17378
|
272
272
|
dissect/target/plugins/os/windows/prefetch.py,sha256=v4OgSKMwcihz0SOuA0o0Ec8wsAKuiuEmJolqZmHFgJA,10491
|
@@ -344,10 +344,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z
|
|
344
344
|
dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
|
345
345
|
dissect/target/volumes/md.py,sha256=j1K1iKmspl0C_OJFc7-Q1BMWN2OCC5EVANIgVlJ_fIE,1673
|
346
346
|
dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
|
347
|
-
dissect.target-3.19.
|
348
|
-
dissect.target-3.19.
|
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.
|
347
|
+
dissect.target-3.19.dev18.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
|
348
|
+
dissect.target-3.19.dev18.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
349
|
+
dissect.target-3.19.dev18.dist-info/METADATA,sha256=5gfwL4PP7a_vTLYBnbyfy1keo11MDR4aYuyMlPMv5Vs,12719
|
350
|
+
dissect.target-3.19.dev18.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
351
|
+
dissect.target-3.19.dev18.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
|
352
|
+
dissect.target-3.19.dev18.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
|
353
|
+
dissect.target-3.19.dev18.dist-info/RECORD,,
|
File without changes
|
File without changes
|
{dissect.target-3.19.dev16.dist-info → dissect.target-3.19.dev18.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|