dissect.target 3.19.dev12__py3-none-any.whl → 3.19.dev13__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.
@@ -40,12 +40,18 @@ class UnixPlugin(OSPlugin):
40
40
  @export(record=UnixUserRecord)
41
41
  @arg("--sessions", action="store_true", help="Parse syslog for recent user sessions")
42
42
  def users(self, sessions: bool = False) -> Iterator[UnixUserRecord]:
43
- """Recover users from /etc/passwd, /etc/master.passwd or /var/log/syslog session logins."""
43
+ """Yield unix user records from passwd files or syslog session logins.
44
+
45
+ Resources:
46
+ - https://manpages.ubuntu.com/manpages/oracular/en/man5/passwd.5.html
47
+ """
48
+
49
+ PASSWD_FILES = ["/etc/passwd", "/etc/passwd-", "/etc/master.passwd"]
44
50
 
45
51
  seen_users = set()
46
52
 
47
53
  # Yield users found in passwd files.
48
- for passwd_file in ["/etc/passwd", "/etc/master.passwd"]:
54
+ for passwd_file in PASSWD_FILES:
49
55
  if (path := self.target.fs.path(passwd_file)).exists():
50
56
  for line in path.open("rt"):
51
57
  line = line.strip()
@@ -53,7 +59,12 @@ class UnixPlugin(OSPlugin):
53
59
  continue
54
60
 
55
61
  pwent = dict(enumerate(line.split(":")))
56
- seen_users.add((pwent.get(0), pwent.get(5), pwent.get(6)))
62
+
63
+ current_user = (pwent.get(0), pwent.get(5), pwent.get(6))
64
+ if current_user in seen_users:
65
+ continue
66
+
67
+ seen_users.add(current_user)
57
68
  yield UnixUserRecord(
58
69
  name=pwent.get(0),
59
70
  passwd=pwent.get(1),
@@ -29,39 +29,55 @@ class ShadowPlugin(Plugin):
29
29
  if not self.target.fs.path("/etc/shadow").exists():
30
30
  raise UnsupportedPluginError("No shadow file found")
31
31
 
32
+ SHADOW_FILES = ["/etc/shadow", "/etc/shadow-"]
33
+
32
34
  @export(record=UnixShadowRecord)
33
35
  def passwords(self) -> Iterator[UnixShadowRecord]:
34
- """Recover shadow records from /etc/shadow files."""
35
-
36
- if (path := self.target.fs.path("/etc/shadow")).exists():
37
- for line in path.open("rt"):
38
- line = line.strip()
39
- if line == "" or line.startswith("#"):
40
- continue
41
-
42
- shent = dict(enumerate(line.split(":")))
43
- crypt = extract_crypt_details(shent)
44
-
45
- # do not return a shadow record if we have no hash
46
- if crypt.get("hash") is None or crypt.get("hash") == "":
47
- continue
48
-
49
- yield UnixShadowRecord(
50
- name=shent.get(0),
51
- crypt=shent.get(1),
52
- algorithm=crypt.get("algo"),
53
- crypt_param=crypt.get("param"),
54
- salt=crypt.get("salt"),
55
- hash=crypt.get("hash"),
56
- last_change=shent.get(2),
57
- min_age=shent.get(3),
58
- max_age=shent.get(4),
59
- warning_period=shent.get(5),
60
- inactivity_period=shent.get(6),
61
- expiration_date=shent.get(7),
62
- unused_field=shent.get(8),
63
- _target=self.target,
64
- )
36
+ """Yield shadow records from /etc/shadow files.
37
+
38
+ Resources:
39
+ - https://manpages.ubuntu.com/manpages/oracular/en/man5/passwd.5.html#file:/etc/shadow
40
+ """
41
+
42
+ seen_hashes = set()
43
+
44
+ for shadow_file in self.SHADOW_FILES:
45
+ if (path := self.target.fs.path(shadow_file)).exists():
46
+ for line in path.open("rt"):
47
+ line = line.strip()
48
+ if line == "" or line.startswith("#"):
49
+ continue
50
+
51
+ shent = dict(enumerate(line.split(":")))
52
+ crypt = extract_crypt_details(shent)
53
+
54
+ # do not return a shadow record if we have no hash
55
+ if crypt.get("hash") is None or crypt.get("hash") == "":
56
+ continue
57
+
58
+ # prevent duplicate user hashes
59
+ current_hash = (shent.get(0), crypt.get("hash"))
60
+ if current_hash in seen_hashes:
61
+ continue
62
+
63
+ seen_hashes.add(current_hash)
64
+
65
+ yield UnixShadowRecord(
66
+ name=shent.get(0),
67
+ crypt=shent.get(1),
68
+ algorithm=crypt.get("algo"),
69
+ crypt_param=crypt.get("param"),
70
+ salt=crypt.get("salt"),
71
+ hash=crypt.get("hash"),
72
+ last_change=shent.get(2),
73
+ min_age=shent.get(3),
74
+ max_age=shent.get(4),
75
+ warning_period=shent.get(5),
76
+ inactivity_period=shent.get(6),
77
+ expiration_date=shent.get(7),
78
+ unused_field=shent.get(8),
79
+ _target=self.target,
80
+ )
65
81
 
66
82
 
67
83
  def extract_crypt_details(shent: dict) -> dict:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dissect.target
3
- Version: 3.19.dev12
3
+ Version: 3.19.dev13
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
@@ -183,7 +183,7 @@ dissect/target/plugins/general/scrape.py,sha256=Fz7BNXflvuxlnVulyyDhLpyU8D_hJdH6
183
183
  dissect/target/plugins/general/users.py,sha256=cQXPQ2XbkPjckCPHYTUW4JEhYN0_CT8JI8hJPZn3qSs,3030
184
184
  dissect/target/plugins/os/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
185
185
  dissect/target/plugins/os/unix/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
186
- dissect/target/plugins/os/unix/_os.py,sha256=VQHx8PDhJ0NHzNuo3RIN3DGXkLqpGXbQe8M5ZbtI5nM,14277
186
+ dissect/target/plugins/os/unix/_os.py,sha256=GcbP8HbK1XtwYFGbl8x0BdfoLAC2ROv9xieeFGI5dWM,14557
187
187
  dissect/target/plugins/os/unix/cronjobs.py,sha256=2ssj97UVJueyATVl7NMJmqd9uHflQ2tXUqdOCFIEje8,3182
188
188
  dissect/target/plugins/os/unix/datetime.py,sha256=gKfBdPyUirt3qmVYfOJ1oZXRPn8wRzssbZxR_ARrtk8,1518
189
189
  dissect/target/plugins/os/unix/etc.py,sha256=HoPEC1hxqurSnAXQAK-jf_HxdBIDe-1z_qSw_n-ViI4,258
@@ -191,7 +191,7 @@ dissect/target/plugins/os/unix/generic.py,sha256=6_MJrV1LbIxNQJwAZR0HEQljoxwF5BP
191
191
  dissect/target/plugins/os/unix/history.py,sha256=ptNGHkHOLJ5bE4r1PqtkQFcQHqzS6-qe5ms1tTGOJp8,6620
192
192
  dissect/target/plugins/os/unix/locale.py,sha256=V3R7mEyrH3f-h7SGAucByaYYDA2SIil9Qb-s3dPmDEA,3961
193
193
  dissect/target/plugins/os/unix/packagemanager.py,sha256=Wm2AAJOD_B3FAcZNXgWtSm_YwbvrHBYOP8bPmOXNjG4,2427
194
- dissect/target/plugins/os/unix/shadow.py,sha256=TvN04uzFnUttNMZAa6_1XdXSP-8V6ztbZNoetDvfD0w,3535
194
+ dissect/target/plugins/os/unix/shadow.py,sha256=W6W6rMru7IVnuBc6sl5wsRWTOrJdS1s7_2_q7QRf7Is,4148
195
195
  dissect/target/plugins/os/unix/bsd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
196
196
  dissect/target/plugins/os/unix/bsd/_os.py,sha256=e5rttTOFOmd7e2HqP9ZZFMEiPLBr-8rfH0XH1IIeroQ,1372
197
197
  dissect/target/plugins/os/unix/bsd/citrix/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -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.dev12.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
348
- dissect.target-3.19.dev12.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
349
- dissect.target-3.19.dev12.dist-info/METADATA,sha256=UR_OR6Mke9csuzDPtguApwOU8mClzRRkkWmmiqNv364,12719
350
- dissect.target-3.19.dev12.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
351
- dissect.target-3.19.dev12.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
352
- dissect.target-3.19.dev12.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
353
- dissect.target-3.19.dev12.dist-info/RECORD,,
347
+ dissect.target-3.19.dev13.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
348
+ dissect.target-3.19.dev13.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
349
+ dissect.target-3.19.dev13.dist-info/METADATA,sha256=oFZiiry3QZEqrgYijsGOlPjZn1DfUM3GBMdf8WZaIFc,12719
350
+ dissect.target-3.19.dev13.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
351
+ dissect.target-3.19.dev13.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
352
+ dissect.target-3.19.dev13.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
353
+ dissect.target-3.19.dev13.dist-info/RECORD,,