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.
@@ -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("--directory", "-d", dest="directory", default=None, help="Path to .lnk file in target")
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, directory: Optional[str] = None) -> Iterator[LnkRecord]:
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(directory):
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
- yield self.target.fs.path(path)
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.dev16
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=wUVnfygXKargH1cAojGbTfgLffXYhbMZOrDP0BUwzdI,25638
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=On1k0PODYggQM1j514qFepBACCV2Z2u61Q4Ba6e3Y2c,8179
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.dev16.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
348
- dissect.target-3.19.dev16.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
349
- dissect.target-3.19.dev16.dist-info/METADATA,sha256=1FP5TC7cQxQzrnIsKcUESZJZigSYAQFFwvZgrbl60TY,12719
350
- dissect.target-3.19.dev16.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
351
- dissect.target-3.19.dev16.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
352
- dissect.target-3.19.dev16.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
353
- dissect.target-3.19.dev16.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (71.1.0)
2
+ Generator: setuptools (72.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5