dissect.target 3.19.dev12__py3-none-any.whl → 3.19.dev14__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/plugins/apps/remoteaccess/anydesk.py +70 -50
- dissect/target/plugins/apps/remoteaccess/remoteaccess.py +8 -8
- dissect/target/plugins/apps/remoteaccess/teamviewer.py +44 -31
- dissect/target/plugins/os/unix/_os.py +14 -3
- dissect/target/plugins/os/unix/shadow.py +47 -31
- {dissect.target-3.19.dev12.dist-info → dissect.target-3.19.dev14.dist-info}/METADATA +1 -1
- {dissect.target-3.19.dev12.dist-info → dissect.target-3.19.dev14.dist-info}/RECORD +12 -12
- {dissect.target-3.19.dev12.dist-info → dissect.target-3.19.dev14.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.19.dev12.dist-info → dissect.target-3.19.dev14.dist-info}/LICENSE +0 -0
- {dissect.target-3.19.dev12.dist-info → dissect.target-3.19.dev14.dist-info}/WHEEL +0 -0
- {dissect.target-3.19.dev12.dist-info → dissect.target-3.19.dev14.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.19.dev12.dist-info → dissect.target-3.19.dev14.dist-info}/top_level.txt +0 -0
@@ -1,91 +1,111 @@
|
|
1
|
-
|
1
|
+
import re
|
2
|
+
from datetime import datetime, timezone
|
3
|
+
from typing import Iterator
|
2
4
|
|
3
5
|
from dissect.target.exceptions import UnsupportedPluginError
|
6
|
+
from dissect.target.helpers.descriptor_extensions import UserRecordDescriptorExtension
|
7
|
+
from dissect.target.helpers.fsutil import TargetPath
|
8
|
+
from dissect.target.helpers.record import create_extended_descriptor
|
4
9
|
from dissect.target.plugin import export
|
5
10
|
from dissect.target.plugins.apps.remoteaccess.remoteaccess import (
|
11
|
+
GENERIC_LOG_RECORD_FIELDS,
|
6
12
|
RemoteAccessPlugin,
|
7
|
-
RemoteAccessRecord,
|
8
13
|
)
|
14
|
+
from dissect.target.plugins.general.users import UserDetails
|
9
15
|
|
10
16
|
|
11
17
|
class AnydeskPlugin(RemoteAccessPlugin):
|
12
|
-
"""
|
13
|
-
Anydesk plugin.
|
14
|
-
"""
|
18
|
+
"""Anydesk plugin."""
|
15
19
|
|
16
20
|
__namespace__ = "anydesk"
|
17
21
|
|
18
22
|
# Anydesk logs when installed as a service
|
19
23
|
SERVICE_GLOBS = [
|
20
|
-
|
21
|
-
"
|
22
|
-
|
24
|
+
# Standard client >= Windows 7
|
25
|
+
"sysvol/ProgramData/AnyDesk/*.trace",
|
26
|
+
# Custom client >= Windows 7
|
27
|
+
"sysvol/ProgramData/AnyDesk/ad_*/*.trace",
|
28
|
+
# Windows XP / 2003
|
29
|
+
"sysvol/Documents and Settings/Public/AnyDesk/*.trace",
|
30
|
+
"sysvol/Documents and Settings/Public/AnyDesk/ad_*/*.trace",
|
31
|
+
# Standard/Custom client Linux/MacOS
|
32
|
+
"var/log/anydesk*/*.trace",
|
23
33
|
]
|
24
34
|
|
25
35
|
# User specific Anydesk logs
|
26
36
|
USER_GLOBS = [
|
27
|
-
|
28
|
-
"
|
29
|
-
|
30
|
-
"
|
37
|
+
# Standard client Windows
|
38
|
+
"AppData/Roaming/AnyDesk/*.trace",
|
39
|
+
# Custom client Windows
|
40
|
+
"AppData/Roaming/AnyDesk/ad_*/*.trace",
|
41
|
+
# Windows XP / 2003
|
42
|
+
"AppData/AnyDesk/*.trace",
|
43
|
+
# Standard client Linux/MacOS
|
44
|
+
".anydesk/*.trace",
|
45
|
+
# Custom client Linux/MacOS
|
46
|
+
".anydesk_ad_*/*.trace",
|
31
47
|
]
|
32
48
|
|
49
|
+
RemoteAccessLogRecord = create_extended_descriptor([UserRecordDescriptorExtension])(
|
50
|
+
"remoteaccess/anydesk/log", GENERIC_LOG_RECORD_FIELDS
|
51
|
+
)
|
52
|
+
|
33
53
|
def __init__(self, target):
|
34
54
|
super().__init__(target)
|
35
55
|
|
36
|
-
self.
|
56
|
+
self.trace_files: set[tuple[TargetPath, UserDetails]] = set()
|
37
57
|
|
38
|
-
#
|
58
|
+
# Service globs
|
39
59
|
user = None
|
40
|
-
for
|
41
|
-
for
|
42
|
-
self.
|
60
|
+
for trace_glob in self.SERVICE_GLOBS:
|
61
|
+
for trace_file in self.target.fs.path().glob(trace_glob):
|
62
|
+
self.trace_files.add((trace_file, user))
|
43
63
|
|
44
|
-
#
|
64
|
+
# User globs
|
45
65
|
for user_details in self.target.user_details.all_with_home():
|
46
|
-
for
|
47
|
-
for
|
48
|
-
self.
|
66
|
+
for trace_glob in self.USER_GLOBS:
|
67
|
+
for trace_file in user_details.home_path.glob(trace_glob):
|
68
|
+
self.trace_files.add((trace_file, user_details.user))
|
49
69
|
|
50
70
|
def check_compatible(self) -> None:
|
51
|
-
if not
|
52
|
-
raise UnsupportedPluginError("No Anydesk
|
71
|
+
if not self.trace_files:
|
72
|
+
raise UnsupportedPluginError("No Anydesk trace files found on target")
|
53
73
|
|
54
|
-
@export(record=
|
55
|
-
def logs(self):
|
56
|
-
"""
|
74
|
+
@export(record=RemoteAccessLogRecord)
|
75
|
+
def logs(self) -> Iterator[RemoteAccessLogRecord]:
|
76
|
+
"""Parse AnyDesk trace files.
|
57
77
|
|
58
78
|
AnyDesk is a remote desktop application and can be used by adversaries to get (persistent) access to a machine.
|
59
|
-
Log files (.trace files)
|
79
|
+
Log files (.trace files) can be stored on various locations, based on target OS and client type.
|
80
|
+
Timestamps in trace files do not carry a time zone designator (TZD) but are in fact UTC.
|
60
81
|
|
61
82
|
References:
|
62
83
|
- https://www.inversecos.com/2021/02/forensic-analysis-of-anydesk-logs.html
|
63
84
|
- https://support.anydesk.com/knowledge/trace-files#trace-file-locations
|
64
85
|
"""
|
65
|
-
for
|
66
|
-
|
67
|
-
|
68
|
-
for line in logfile.open("rt"):
|
86
|
+
for trace_file, user in self.trace_files:
|
87
|
+
for line in trace_file.open("rt", errors="backslashreplace"):
|
69
88
|
line = line.strip()
|
70
89
|
|
71
|
-
|
72
|
-
if not line:
|
73
|
-
continue
|
74
|
-
|
75
|
-
if "* * * * * * * * * * * * * *" in line:
|
90
|
+
if not line or "* * * * * * * * * * * * * *" in line:
|
76
91
|
continue
|
77
92
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
93
|
+
try:
|
94
|
+
level, ts_date, ts_time, message = line.split(" ", 3)
|
95
|
+
|
96
|
+
timestamp = datetime.strptime(f"{ts_date} {ts_time}", "%Y-%m-%d %H:%M:%S.%f").replace(
|
97
|
+
tzinfo=timezone.utc
|
98
|
+
)
|
99
|
+
message = re.sub(r"\s\s+", " ", f"{level} {message}")
|
100
|
+
|
101
|
+
yield self.RemoteAccessLogRecord(
|
102
|
+
ts=timestamp,
|
103
|
+
message=message,
|
104
|
+
source=trace_file,
|
105
|
+
_target=self.target,
|
106
|
+
_user=user,
|
107
|
+
)
|
108
|
+
|
109
|
+
except ValueError as e:
|
110
|
+
self.target.log.warning("Could not parse log line in file %s: '%s'", trace_file, line)
|
111
|
+
self.target.log.debug("", exc_info=e)
|
@@ -2,14 +2,14 @@ from dissect.target.helpers.descriptor_extensions import UserRecordDescriptorExt
|
|
2
2
|
from dissect.target.helpers.record import create_extended_descriptor
|
3
3
|
from dissect.target.plugin import NamespacePlugin
|
4
4
|
|
5
|
-
|
6
|
-
"
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
GENERIC_LOG_RECORD_FIELDS = [
|
6
|
+
("datetime", "ts"),
|
7
|
+
("string", "message"),
|
8
|
+
("path", "source"),
|
9
|
+
]
|
10
|
+
|
11
|
+
RemoteAccessLogRecord = create_extended_descriptor([UserRecordDescriptorExtension])(
|
12
|
+
"remoteaccess/log", GENERIC_LOG_RECORD_FIELDS
|
13
13
|
)
|
14
14
|
|
15
15
|
|
@@ -1,60 +1,72 @@
|
|
1
1
|
import re
|
2
|
-
from datetime import datetime
|
2
|
+
from datetime import datetime, timezone
|
3
|
+
from typing import Iterator
|
3
4
|
|
4
5
|
from dissect.target.exceptions import UnsupportedPluginError
|
6
|
+
from dissect.target.helpers.descriptor_extensions import UserRecordDescriptorExtension
|
7
|
+
from dissect.target.helpers.fsutil import TargetPath
|
8
|
+
from dissect.target.helpers.record import create_extended_descriptor
|
5
9
|
from dissect.target.plugin import export
|
6
10
|
from dissect.target.plugins.apps.remoteaccess.remoteaccess import (
|
11
|
+
GENERIC_LOG_RECORD_FIELDS,
|
7
12
|
RemoteAccessPlugin,
|
8
|
-
RemoteAccessRecord,
|
9
13
|
)
|
14
|
+
from dissect.target.plugins.general.users import UserDetails
|
10
15
|
|
11
16
|
START_PATTERN = re.compile(r"^(\d{2}|\d{4})/")
|
12
17
|
|
13
18
|
|
14
|
-
class
|
15
|
-
"""
|
16
|
-
|
19
|
+
class TeamViewerPlugin(RemoteAccessPlugin):
|
20
|
+
"""TeamViewer client plugin.
|
21
|
+
|
22
|
+
Resources:
|
23
|
+
- https://teamviewer.com/en/global/support/knowledge-base/teamviewer-classic/contact-support/find-your-log-files
|
24
|
+
- https://www.systoolsgroup.com/forensics/teamviewer/
|
25
|
+
- https://benleeyr.wordpress.com/2020/05/19/teamviewer-forensics-tested-on-v15/
|
17
26
|
"""
|
18
27
|
|
19
28
|
__namespace__ = "teamviewer"
|
20
29
|
|
21
|
-
|
22
|
-
GLOBS = [
|
30
|
+
SYSTEM_GLOBS = [
|
23
31
|
"sysvol/Program Files/TeamViewer/*.log",
|
24
32
|
"sysvol/Program Files (x86)/TeamViewer/*.log",
|
25
33
|
]
|
26
34
|
|
35
|
+
USER_GLOBS = [
|
36
|
+
"AppData/Roaming/TeamViewer/teamviewer*_logfile.log",
|
37
|
+
]
|
38
|
+
|
39
|
+
RemoteAccessLogRecord = create_extended_descriptor([UserRecordDescriptorExtension])(
|
40
|
+
"remoteaccess/teamviewer/log", GENERIC_LOG_RECORD_FIELDS
|
41
|
+
)
|
42
|
+
|
27
43
|
def __init__(self, target):
|
28
44
|
super().__init__(target)
|
29
45
|
|
30
|
-
self.logfiles = []
|
46
|
+
self.logfiles: list[list[TargetPath, UserDetails]] = []
|
31
47
|
|
32
|
-
#
|
33
|
-
|
34
|
-
for log_glob in self.GLOBS:
|
48
|
+
# Find system service log files.
|
49
|
+
for log_glob in self.SYSTEM_GLOBS:
|
35
50
|
for logfile in self.target.fs.glob(log_glob):
|
36
|
-
self.logfiles.append([logfile,
|
51
|
+
self.logfiles.append([logfile, None])
|
37
52
|
|
38
|
-
#
|
53
|
+
# Find user log files.
|
39
54
|
for user_details in self.target.user_details.all_with_home():
|
40
|
-
for
|
41
|
-
|
55
|
+
for log_glob in self.USER_GLOBS:
|
56
|
+
for logfile in user_details.home_path.glob(log_glob):
|
57
|
+
self.logfiles.append([logfile, user_details])
|
42
58
|
|
43
59
|
def check_compatible(self) -> None:
|
44
60
|
if not len(self.logfiles):
|
45
61
|
raise UnsupportedPluginError("No Teamviewer logs found")
|
46
62
|
|
47
|
-
@export(record=
|
48
|
-
def logs(self):
|
49
|
-
"""
|
50
|
-
|
51
|
-
TeamViewer is a commercial remote desktop application. An adversary may use it to gain persistence on a
|
52
|
-
system.
|
63
|
+
@export(record=RemoteAccessLogRecord)
|
64
|
+
def logs(self) -> Iterator[RemoteAccessLogRecord]:
|
65
|
+
"""Yield TeamViewer client logs.
|
53
66
|
|
54
|
-
|
55
|
-
- https://www.teamviewer.com/nl/
|
67
|
+
TeamViewer is a commercial remote desktop application. An adversary may use it to gain persistence on a system.
|
56
68
|
"""
|
57
|
-
for logfile,
|
69
|
+
for logfile, user_details in self.logfiles:
|
58
70
|
logfile = self.target.fs.path(logfile)
|
59
71
|
|
60
72
|
start_date = None
|
@@ -83,7 +95,7 @@ class TeamviewerPlugin(RemoteAccessPlugin):
|
|
83
95
|
if not re.match(START_PATTERN, line):
|
84
96
|
continue
|
85
97
|
|
86
|
-
ts_day, ts_time,
|
98
|
+
ts_day, ts_time, message = line.split(" ", 2)
|
87
99
|
ts_time = ts_time.split(".")[0]
|
88
100
|
|
89
101
|
# Correct for use of : as millisecond separator
|
@@ -99,13 +111,14 @@ class TeamviewerPlugin(RemoteAccessPlugin):
|
|
99
111
|
if ts_day.count("/") == 2 and len(ts_day.split("/")[0]) == 2:
|
100
112
|
ts_day = "20" + ts_day
|
101
113
|
|
102
|
-
timestamp = datetime.strptime(f"{ts_day} {ts_time}", "%Y/%m/%d %H:%M:%S")
|
114
|
+
timestamp = datetime.strptime(f"{ts_day} {ts_time}", "%Y/%m/%d %H:%M:%S").replace(
|
115
|
+
tzinfo=timezone.utc
|
116
|
+
)
|
103
117
|
|
104
|
-
yield
|
105
|
-
tool="teamviewer",
|
118
|
+
yield self.RemoteAccessLogRecord(
|
106
119
|
ts=timestamp,
|
107
|
-
|
108
|
-
|
120
|
+
message=message,
|
121
|
+
source=logfile,
|
109
122
|
_target=self.target,
|
110
|
-
_user=user,
|
123
|
+
_user=user_details.user if user_details else None,
|
111
124
|
)
|
@@ -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
|
-
"""
|
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
|
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
|
-
|
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
|
-
"""
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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.
|
3
|
+
Version: 3.19.dev14
|
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,9 +128,9 @@ dissect/target/plugins/apps/browser/iexplore.py,sha256=g_xw0toaiyjevxO8g9XPCOqc-
|
|
128
128
|
dissect/target/plugins/apps/container/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
129
129
|
dissect/target/plugins/apps/container/docker.py,sha256=KxQRbKGgxkf3YFBMa7fjeJ7qo8qjFys7zEmfQhDTnLw,15305
|
130
130
|
dissect/target/plugins/apps/remoteaccess/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
131
|
-
dissect/target/plugins/apps/remoteaccess/anydesk.py,sha256=
|
132
|
-
dissect/target/plugins/apps/remoteaccess/remoteaccess.py,sha256=
|
133
|
-
dissect/target/plugins/apps/remoteaccess/teamviewer.py,sha256=
|
131
|
+
dissect/target/plugins/apps/remoteaccess/anydesk.py,sha256=IdijK3F6ppaB_IgKL-xDljlEbb8l9S2U0xSWKqK9xRs,4294
|
132
|
+
dissect/target/plugins/apps/remoteaccess/remoteaccess.py,sha256=DWXkRDVUpFr1icK2fYwSXdZD204Xz0yRuO7rcJOwIwc,825
|
133
|
+
dissect/target/plugins/apps/remoteaccess/teamviewer.py,sha256=0nGjgbzzrhESr1PeiXlGxYQ66-aOATO59CnVSwcGn4E,4889
|
134
134
|
dissect/target/plugins/apps/shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
135
135
|
dissect/target/plugins/apps/shell/powershell.py,sha256=biPSMRWxPI6kRqP0-75yMtrw0Ti2Bzfl_xI3xbmmF48,2641
|
136
136
|
dissect/target/plugins/apps/ssh/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -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=
|
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=
|
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.
|
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.dev14.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
|
348
|
+
dissect.target-3.19.dev14.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
349
|
+
dissect.target-3.19.dev14.dist-info/METADATA,sha256=QY-pX_0ABwGcA1nW1mG6NJZ_K2DoaG6-lOaFvH-ZORI,12719
|
350
|
+
dissect.target-3.19.dev14.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
|
351
|
+
dissect.target-3.19.dev14.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
|
352
|
+
dissect.target-3.19.dev14.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
|
353
|
+
dissect.target-3.19.dev14.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
{dissect.target-3.19.dev12.dist-info → dissect.target-3.19.dev14.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|