dissect.target 3.18.dev9__py3-none-any.whl → 3.18.dev11__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.
@@ -21,7 +21,7 @@ class WindowsPlugin(OSPlugin):
21
21
  self.add_mounts()
22
22
 
23
23
  target.props["sysvol_drive"] = next(
24
- (mnt for mnt, fs in target.fs.mounts.items() if fs is target.fs.mounts["sysvol"] and mnt != "sysvol"),
24
+ (mnt for mnt, fs in target.fs.mounts.items() if fs is target.fs.mounts.get("sysvol") and mnt != "sysvol"),
25
25
  None,
26
26
  )
27
27
 
@@ -78,13 +78,16 @@ class WindowsPlugin(OSPlugin):
78
78
  self.target.log.warning("Failed to map drive letters")
79
79
  self.target.log.debug("", exc_info=e)
80
80
 
81
+ sysvol_drive = self.target.fs.mounts.get("sysvol")
81
82
  # Fallback mount the sysvol to C: if we didn't manage to mount it to any other drive letter
82
- if operator.countOf(self.target.fs.mounts.values(), self.target.fs.mounts["sysvol"]) == 1:
83
+ if sysvol_drive and operator.countOf(self.target.fs.mounts.values(), sysvol_drive) == 1:
83
84
  if "c:" not in self.target.fs.mounts:
84
85
  self.target.log.debug("Unable to determine drive letter of sysvol, falling back to C:")
85
- self.target.fs.mount("c:", self.target.fs.mounts["sysvol"])
86
+ self.target.fs.mount("c:", sysvol_drive)
86
87
  else:
87
88
  self.target.log.warning("Unknown drive letter for sysvol")
89
+ else:
90
+ self.target.log.warning("No sysvol drive found")
88
91
 
89
92
  @export(property=True)
90
93
  def hostname(self) -> Optional[str]:
@@ -1,7 +1,10 @@
1
+ from __future__ import annotations
2
+
3
+ import re
1
4
  from datetime import datetime, timezone
2
5
  from io import BytesIO
3
6
  from pathlib import Path
4
- from typing import Any, BinaryIO, Generator, Iterable, Iterator, Union
7
+ from typing import Any, BinaryIO, Generator, Iterable, Iterator, TextIO, Union
5
8
 
6
9
  import dissect.util.ts as ts
7
10
  from dissect.cstruct import Structure, cstruct
@@ -10,6 +13,27 @@ from flow.record import Record
10
13
  from dissect.target import plugin
11
14
  from dissect.target.exceptions import UnsupportedPluginError
12
15
  from dissect.target.helpers.record import TargetRecordDescriptor
16
+ from dissect.target.plugins.os.windows.defender_helpers.defender_patterns import (
17
+ DEFENDER_MPLOG_BLOCK_PATTERNS,
18
+ DEFENDER_MPLOG_LINE,
19
+ DEFENDER_MPLOG_PATTERNS,
20
+ )
21
+ from dissect.target.plugins.os.windows.defender_helpers.defender_records import (
22
+ DefenderMPLogBMTelemetryRecord,
23
+ DefenderMPLogDetectionAddRecord,
24
+ DefenderMPLogDetectionEventRecord,
25
+ DefenderMPLogEMSRecord,
26
+ DefenderMPLogExclusionRecord,
27
+ DefenderMPLogLowfiRecord,
28
+ DefenderMPLogMinFilBlockedFileRecord,
29
+ DefenderMPLogMinFilUSSRecord,
30
+ DefenderMPLogOriginalFileNameRecord,
31
+ DefenderMPLogProcessImageRecord,
32
+ DefenderMPLogResourceScanRecord,
33
+ DefenderMPLogRTPRecord,
34
+ DefenderMPLogThreatActionRecord,
35
+ DefenderMPLogThreatRecord,
36
+ )
13
37
 
14
38
  DEFENDER_EVTX_FIELDS = [
15
39
  ("datetime", "ts"),
@@ -73,6 +97,7 @@ DEFENDER_LOG_FILENAME_GLOB = "Microsoft-Windows-Windows Defender*"
73
97
  EVTX_PROVIDER_NAME = "Microsoft-Windows-Windows Defender"
74
98
 
75
99
  DEFENDER_QUARANTINE_DIR = "sysvol/programdata/microsoft/windows defender/quarantine"
100
+ DEFENDER_MPLOG_DIR = "sysvol/programdata/microsoft/windows defender/support"
76
101
  DEFENDER_KNOWN_DETECTION_TYPES = [b"internalbehavior", b"regkey", b"runkey"]
77
102
 
78
103
  DEFENDER_EXCLUSION_KEY = "HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions"
@@ -494,6 +519,198 @@ class MicrosoftDefenderPlugin(plugin.Plugin):
494
519
  value=exclusion_value,
495
520
  )
496
521
 
522
+ def _mplog_processimage(self, data: dict) -> Iterator[DefenderMPLogProcessImageRecord]:
523
+ yield DefenderMPLogProcessImageRecord(**data)
524
+
525
+ def _mplog_minfiluss(self, data: dict) -> Iterator[DefenderMPLogMinFilUSSRecord]:
526
+ yield DefenderMPLogMinFilUSSRecord(**data)
527
+
528
+ def _mplog_blockedfile(self, data: dict) -> Iterator[DefenderMPLogMinFilBlockedFileRecord]:
529
+ yield DefenderMPLogMinFilBlockedFileRecord(**data)
530
+
531
+ def _mplog_bmtelemetry(self, data: dict) -> Iterator[DefenderMPLogBMTelemetryRecord]:
532
+ data["ts"] = datetime.strptime(data["ts"], "%m-%d-%Y %H:%M:%S")
533
+ yield DefenderMPLogBMTelemetryRecord(**data)
534
+
535
+ def _mplog_ems(self, data: dict) -> Iterator[DefenderMPLogEMSRecord]:
536
+ yield DefenderMPLogEMSRecord(**data)
537
+
538
+ def _mplog_originalfilename(self, data: dict) -> Iterator[DefenderMPLogOriginalFileNameRecord]:
539
+ yield DefenderMPLogOriginalFileNameRecord(**data)
540
+
541
+ def _mplog_exclusion(self, data: dict) -> Iterator[DefenderMPLogExclusionRecord]:
542
+ yield DefenderMPLogExclusionRecord(**data)
543
+
544
+ def _mplog_lowfi(self, data: dict) -> Iterator[DefenderMPLogLowfiRecord]:
545
+ yield DefenderMPLogLowfiRecord(**data)
546
+
547
+ def _mplog_detectionadd(self, data: dict) -> Iterator[DefenderMPLogDetectionAddRecord]:
548
+ yield DefenderMPLogDetectionAddRecord(**data)
549
+
550
+ def _mplog_threat(self, data: dict) -> Iterator[DefenderMPLogThreatRecord]:
551
+ yield DefenderMPLogThreatRecord(**data)
552
+
553
+ def _mplog_resourcescan(self, data: dict) -> Iterator[DefenderMPLogResourceScanRecord]:
554
+ data["start_time"] = datetime.strptime(data["start_time"], "%m-%d-%Y %H:%M:%S")
555
+ data["end_time"] = datetime.strptime(data["end_time"], "%m-%d-%Y %H:%M:%S")
556
+ data["ts"] = data["start_time"]
557
+ rest = data.pop("rest")
558
+ yield DefenderMPLogResourceScanRecord(
559
+ threats=re.findall("Threat Name:([^\n]+)", rest),
560
+ resources=re.findall("Resource Path:([^\n]+)", rest),
561
+ **data,
562
+ )
563
+
564
+ def _mplog_threataction(self, data: dict) -> Iterator[DefenderMPLogThreatActionRecord]:
565
+ data["ts"] = datetime.strptime(data["ts"], "%m-%d-%Y %H:%M:%S")
566
+ rest = data.pop("rest")
567
+ yield DefenderMPLogThreatActionRecord(
568
+ threats=re.findall("Threat Name:([^\n]+)", rest),
569
+ resources=re.findall("(?:Path|File Name):([^\n]+)", rest),
570
+ actions=re.findall("Action:([^\n]+)", rest),
571
+ **data,
572
+ )
573
+
574
+ def _mplog_rtp_log(self, data: dict) -> Iterator[DefenderMPLogRTPRecord]:
575
+ times = {}
576
+ for dtkey in ["ts", "last_perf", "first_rtp_scan"]:
577
+ try:
578
+ times[dtkey] = datetime.strptime(data[dtkey], "%m-%d-%Y %H:%M:%S")
579
+ except ValueError:
580
+ pass
581
+
582
+ yield DefenderMPLogRTPRecord(
583
+ _target=self.target,
584
+ source_log=data["source_log"],
585
+ **times,
586
+ plugin_states=re.findall(r"^\s+(.*)$", data["plugin_states"])[0],
587
+ process_exclusions=re.findall(DEFENDER_MPLOG_LINE, data["process_exclusions"]),
588
+ path_exclusions=re.findall(DEFENDER_MPLOG_LINE, data["path_exclusions"]),
589
+ ext_exclusions=re.findall(DEFENDER_MPLOG_LINE, data["ext_exclusions"]),
590
+ )
591
+
592
+ def _mplog_detectionevent(self, data: dict) -> Iterator[DefenderMPLogDetectionEventRecord]:
593
+ yield DefenderMPLogDetectionEventRecord(**data)
594
+
595
+ def _mplog_line(
596
+ self, mplog_line: str, source: Path
597
+ ) -> Iterator[
598
+ DefenderMPLogProcessImageRecord
599
+ | DefenderMPLogMinFilUSSRecord
600
+ | DefenderMPLogMinFilBlockedFileRecord
601
+ | DefenderMPLogEMSRecord
602
+ | DefenderMPLogOriginalFileNameRecord
603
+ | DefenderMPLogExclusionRecord
604
+ | DefenderMPLogLowfiRecord
605
+ | DefenderMPLogDetectionAddRecord
606
+ | DefenderMPLogThreatRecord
607
+ | DefenderMPLogDetectionEventRecord
608
+ ]:
609
+ for pattern, record in DEFENDER_MPLOG_PATTERNS:
610
+ if match := pattern.match(mplog_line):
611
+ data = match.groupdict()
612
+ data["_target"] = self.target
613
+ data["source_log"] = source
614
+ yield from getattr(self, f"_mplog_{record.name.split('/')[-1:][0]}")(data)
615
+
616
+ def _mplog_block(
617
+ self, mplog_line: str, mplog: TextIO, source: Path
618
+ ) -> Iterator[DefenderMPLogResourceScanRecord | DefenderMPLogThreatActionRecord | DefenderMPLogRTPRecord]:
619
+ block = ""
620
+ for prefix, suffix, pattern, record in DEFENDER_MPLOG_BLOCK_PATTERNS:
621
+ if prefix.search(mplog_line):
622
+ block += mplog_line
623
+ break
624
+ if block:
625
+ while mplog_line := mplog.readline():
626
+ block += mplog_line
627
+ if suffix.search(mplog_line):
628
+ break
629
+ match = pattern.match(block)
630
+ data = match.groupdict()
631
+ data["_target"] = self.target
632
+ data["source_log"] = source
633
+ yield from getattr(self, f"_mplog_{record.name.split('/')[-1:][0]}")(data)
634
+
635
+ def _mplog(
636
+ self, mplog: TextIO, source: Path
637
+ ) -> Iterator[
638
+ DefenderMPLogProcessImageRecord
639
+ | DefenderMPLogMinFilUSSRecord
640
+ | DefenderMPLogMinFilBlockedFileRecord
641
+ | DefenderMPLogBMTelemetryRecord
642
+ | DefenderMPLogEMSRecord
643
+ | DefenderMPLogOriginalFileNameRecord
644
+ | DefenderMPLogExclusionRecord
645
+ | DefenderMPLogLowfiRecord
646
+ | DefenderMPLogDetectionAddRecord
647
+ | DefenderMPLogThreatRecord
648
+ | DefenderMPLogDetectionEventRecord
649
+ | DefenderMPLogResourceScanRecord
650
+ | DefenderMPLogThreatActionRecord
651
+ | DefenderMPLogRTPRecord
652
+ ]:
653
+ while mplog_line := mplog.readline():
654
+ yield from self._mplog_line(mplog_line, source)
655
+ yield from self._mplog_block(mplog_line, mplog, source)
656
+
657
+ @plugin.export(
658
+ record=[
659
+ DefenderMPLogProcessImageRecord,
660
+ DefenderMPLogMinFilUSSRecord,
661
+ DefenderMPLogMinFilBlockedFileRecord,
662
+ DefenderMPLogBMTelemetryRecord,
663
+ DefenderMPLogEMSRecord,
664
+ DefenderMPLogOriginalFileNameRecord,
665
+ DefenderMPLogExclusionRecord,
666
+ DefenderMPLogLowfiRecord,
667
+ DefenderMPLogDetectionAddRecord,
668
+ DefenderMPLogThreatRecord,
669
+ DefenderMPLogDetectionEventRecord,
670
+ DefenderMPLogResourceScanRecord,
671
+ DefenderMPLogThreatActionRecord,
672
+ DefenderMPLogRTPRecord,
673
+ ]
674
+ )
675
+ def mplog(
676
+ self,
677
+ ) -> Iterator[
678
+ DefenderMPLogProcessImageRecord
679
+ | DefenderMPLogMinFilUSSRecord
680
+ | DefenderMPLogMinFilBlockedFileRecord
681
+ | DefenderMPLogBMTelemetryRecord
682
+ | DefenderMPLogEMSRecord
683
+ | DefenderMPLogOriginalFileNameRecord
684
+ | DefenderMPLogExclusionRecord
685
+ | DefenderMPLogLowfiRecord
686
+ | DefenderMPLogDetectionAddRecord
687
+ | DefenderMPLogThreatRecord
688
+ | DefenderMPLogDetectionEventRecord
689
+ | DefenderMPLogResourceScanRecord
690
+ | DefenderMPLogThreatActionRecord
691
+ | DefenderMPLogRTPRecord
692
+ ]:
693
+ """Return the contents of the Defender MPLog file.
694
+
695
+ References:
696
+ - https://www.crowdstrike.com/blog/how-to-use-microsoft-protection-logging-for-forensic-investigations/
697
+ - https://www.intrinsec.com/hunt-mplogs/
698
+ - https://github.com/Intrinsec/mplog_parser
699
+ """
700
+ mplog_directory = self.target.fs.path(DEFENDER_MPLOG_DIR)
701
+
702
+ if not (mplog_directory.exists() and mplog_directory.is_dir()):
703
+ return
704
+
705
+ for mplog_file in mplog_directory.glob("MPLog-*"):
706
+ for encoding in ["UTF-16", "UTF-8"]:
707
+ try:
708
+ with mplog_file.open("rt", encoding=encoding) as mplog:
709
+ yield from self._mplog(mplog, self.target.fs.path(mplog_file))
710
+ break
711
+ except UnicodeError:
712
+ continue
713
+
497
714
  @plugin.arg(
498
715
  "--output",
499
716
  "-o",
@@ -0,0 +1,282 @@
1
+ import re
2
+
3
+ from dissect.target.plugins.os.windows.defender_helpers.defender_records import (
4
+ DefenderMPLogBMTelemetryRecord,
5
+ DefenderMPLogDetectionAddRecord,
6
+ DefenderMPLogDetectionEventRecord,
7
+ DefenderMPLogEMSRecord,
8
+ DefenderMPLogExclusionRecord,
9
+ DefenderMPLogLowfiRecord,
10
+ DefenderMPLogMinFilBlockedFileRecord,
11
+ DefenderMPLogMinFilUSSRecord,
12
+ DefenderMPLogOriginalFileNameRecord,
13
+ DefenderMPLogProcessImageRecord,
14
+ DefenderMPLogResourceScanRecord,
15
+ DefenderMPLogRTPRecord,
16
+ DefenderMPLogThreatActionRecord,
17
+ DefenderMPLogThreatRecord,
18
+ )
19
+
20
+ DEFENDER_MPLOG_TS_PATTERN = r"(?P<ts>[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z) "
21
+
22
+ # Loosely based on https://github.com/Intrinsec/mplog_parser but feel free to add patterns
23
+
24
+ DEFENDER_MPLOG_PATTERNS = [
25
+ # Process Image
26
+ (
27
+ re.compile(
28
+ "".join(
29
+ [
30
+ DEFENDER_MPLOG_TS_PATTERN,
31
+ r"ProcessImageName: (?P<process_image_name>.*), ",
32
+ r"Pid: (?P<pid>\d*), ",
33
+ r"TotalTime: (?P<total_time>\d*), ",
34
+ r"Count: (?P<count>\d*), ",
35
+ r"MaxTime: (?P<max_time>\d*), ",
36
+ r"MaxTimeFile: (?P<max_time_file>.*), ",
37
+ r"EstimatedImpact: (?P<estimated_impact>\d*)",
38
+ ]
39
+ )
40
+ ),
41
+ DefenderMPLogProcessImageRecord,
42
+ ),
43
+ # Mini-filter Unsuccessful scan status
44
+ (
45
+ re.compile(
46
+ "".join(
47
+ [
48
+ DEFENDER_MPLOG_TS_PATTERN,
49
+ r"\[Mini-filter\] (Unsuccessful scan status)[^:]*: (?P<path>.+) ",
50
+ r"Process: (?P<process>.+), ",
51
+ r"Status: (?P<status>.+), ",
52
+ r"State: (?P<state>.+), ",
53
+ r"ScanRequest (?P<scan_request>.+), ",
54
+ r"FileId: (?P<file_id>.+), ",
55
+ r"Reason: (?P<reason>.+), ",
56
+ r"IoStatusBlockForNewFile: (?P<io_status_block_for_new_file>.+), ",
57
+ r"DesiredAccess:(?P<desired_access>.+), ",
58
+ r"FileAttributes:(?P<file_attributes>.+), ",
59
+ r"ScanAttributes:(?P<scan_attributes>.+), ",
60
+ r"AccessStateFlags:(?P<access_state_flags>.+), ",
61
+ r"BackingFileInfo: (?P<backing_file_info>.+)",
62
+ ]
63
+ )
64
+ ),
65
+ DefenderMPLogMinFilUSSRecord,
66
+ ),
67
+ # EMS Scan
68
+ (
69
+ re.compile(
70
+ "".join(
71
+ [
72
+ DEFENDER_MPLOG_TS_PATTERN,
73
+ r".*",
74
+ r"process: (?P<process>\w*) ",
75
+ r"pid: (?P<pid>\d*), ",
76
+ r"sigseq: (?P<sigseq>\w*), ",
77
+ r"sendMemoryScanReport: (?P<send_memory_scan_report>\d*), ",
78
+ r"source: (?P<source>\d*)",
79
+ ]
80
+ )
81
+ ),
82
+ DefenderMPLogEMSRecord,
83
+ ),
84
+ # Original filename
85
+ (
86
+ re.compile(
87
+ "".join(
88
+ [
89
+ DEFENDER_MPLOG_TS_PATTERN,
90
+ r".*",
91
+ r"original file name \"(?P<original_file_name>.*)\" ",
92
+ r"for \"(?P<full_path>.*)\", ",
93
+ r"hr=(?P<hr>\w*)",
94
+ ]
95
+ )
96
+ ),
97
+ DefenderMPLogOriginalFileNameRecord,
98
+ ),
99
+ # Mini-filter Blocked file
100
+ (
101
+ re.compile(
102
+ "".join(
103
+ [
104
+ DEFENDER_MPLOG_TS_PATTERN,
105
+ r".*",
106
+ r"\[Mini-filter\] Blocked file: (?P<blocked_file>.+) ",
107
+ r"Process: (?P<process>.+), ",
108
+ r"Status: (?P<status>.+), ",
109
+ r"State: (?P<state>.+), ",
110
+ r"ScanRequest (?P<scan_request>.+), ",
111
+ r"FileId: (?P<file_id>.+), ",
112
+ r"Reason: (?P<reason>.+), ",
113
+ r"IoStatusBlockForNewFile: (?P<io_status_block_for_new_file>.+), ",
114
+ r"DesiredAccess:(?P<desired_access>.+), ",
115
+ r"FileAttributes:(?P<file_attributes>.+), ",
116
+ r"ScanAttributes:(?P<scan_attributes>.+), ",
117
+ r"AccessStateFlags:(?P<access_state_flags>.+), ",
118
+ r"BackingFileInfo: (?P<backing_file_info>.+)",
119
+ ]
120
+ )
121
+ ),
122
+ DefenderMPLogMinFilBlockedFileRecord,
123
+ ),
124
+ # Exclusion
125
+ (
126
+ re.compile(
127
+ "".join(
128
+ [
129
+ DEFENDER_MPLOG_TS_PATTERN,
130
+ r"\[Exclusion\] (?P<full_path_with_drive_letter>.+) ",
131
+ r"-> (?P<full_path_with_device_path>.+)",
132
+ ]
133
+ )
134
+ ),
135
+ DefenderMPLogExclusionRecord,
136
+ ),
137
+ # Lowfi
138
+ (
139
+ re.compile(
140
+ "".join(
141
+ [
142
+ DEFENDER_MPLOG_TS_PATTERN,
143
+ r".*",
144
+ r"lowfi: (?P<lowfi>.+)",
145
+ ]
146
+ )
147
+ ),
148
+ DefenderMPLogLowfiRecord,
149
+ ),
150
+ # Detection add
151
+ (
152
+ re.compile(
153
+ "".join(
154
+ [
155
+ DEFENDER_MPLOG_TS_PATTERN,
156
+ r".*",
157
+ r"DETECTION_ADD\S* (?P<detection>.*)",
158
+ ]
159
+ )
160
+ ),
161
+ DefenderMPLogDetectionAddRecord,
162
+ ),
163
+ # Threat
164
+ (
165
+ re.compile(
166
+ "".join(
167
+ [
168
+ DEFENDER_MPLOG_TS_PATTERN,
169
+ r".*",
170
+ r"threat: (?P<threat>.*)",
171
+ ]
172
+ )
173
+ ),
174
+ DefenderMPLogThreatRecord,
175
+ ),
176
+ # Detection event
177
+ (
178
+ re.compile(
179
+ "".join(
180
+ [
181
+ DEFENDER_MPLOG_TS_PATTERN,
182
+ r".*",
183
+ r"DETECTIONEVENT MPSOURCE_\S+ HackTool:(?P<threat_type>.*) file:(?P<command>.*)",
184
+ ]
185
+ )
186
+ ),
187
+ DefenderMPLogDetectionEventRecord,
188
+ ),
189
+ ]
190
+
191
+
192
+ DEFENDER_MPLOG_BLOCK_PATTERNS = [
193
+ (
194
+ re.compile(r"Begin Resource Scan"),
195
+ re.compile(r"End Scan"),
196
+ re.compile(
197
+ "".join(
198
+ [
199
+ r"Begin Resource Scan.*\n",
200
+ r"Scan ID:(?P<scan_id>[^\n]+)\n",
201
+ r"Scan Source:(?P<scan_source>\d+)\n",
202
+ r"Start Time:(?P<start_time>[0-9\-\:\s]*)\n",
203
+ r"End Time:(?P<end_time>[0-9\-\:\s]*)\n",
204
+ r".*",
205
+ r"Resource Schema:(?P<resource_schema>[^\n]+)\n",
206
+ r"Resource Path:(?P<resource_path>[^\n]+)\n",
207
+ r"Result Count:(?P<result_count>\d+)\n",
208
+ r"(?P<rest>.*)\n",
209
+ r"End Scan",
210
+ ]
211
+ ),
212
+ re.MULTILINE | re.DOTALL,
213
+ ),
214
+ DefenderMPLogResourceScanRecord,
215
+ ),
216
+ # Threat actions
217
+ (
218
+ re.compile(r"Beginning threat actions"),
219
+ re.compile(r"Finished threat actions"),
220
+ re.compile(
221
+ "".join(
222
+ [
223
+ r"Beginning threat actions\n",
224
+ r"Start time:(?P<ts>[0-9\-\:\s]*)\n",
225
+ r"(?P<rest>.*)\n",
226
+ r"Finished threat actions",
227
+ ]
228
+ ),
229
+ re.MULTILINE | re.DOTALL,
230
+ ),
231
+ DefenderMPLogThreatActionRecord,
232
+ ),
233
+ # RTP
234
+ (
235
+ re.compile(r"\*\*RTP Perf Log\*\*"),
236
+ re.compile(r"\*\*END RTP Perf Log\*\*"),
237
+ re.compile(
238
+ "".join(
239
+ [
240
+ r"\*+RTP Perf Log\*+\n",
241
+ r"RTP Start:(?P<ts>.*)\n",
242
+ r"Last Perf:(?P<last_perf>.*)\n",
243
+ r"First RTP Scan:(?P<first_rtp_scan>.*)\n",
244
+ r"Plugin States:(?P<plugin_states>.*)\n",
245
+ r"Process Exclusions:\n(?P<process_exclusions>.*)",
246
+ r"Path Exclusions:\n(?P<path_exclusions>.*)",
247
+ r"Ext Exclusions:\n(?P<ext_exclusions>.*)",
248
+ r"Worker Threads",
249
+ ]
250
+ ),
251
+ re.MULTILINE | re.DOTALL,
252
+ ),
253
+ DefenderMPLogRTPRecord,
254
+ ),
255
+ # BM Telemetry (block)
256
+ (
257
+ re.compile(r"BEGIN BM telemetry"),
258
+ re.compile(r"END BM telemetry"),
259
+ re.compile(
260
+ "".join(
261
+ [
262
+ r"BEGIN BM telemetry\n",
263
+ r"(GUID):(?P<guid>.+)\n",
264
+ r"(SignatureID):(?P<signature_id>.+)\n",
265
+ r"(SigSha):(?P<sigsha>.+)\n",
266
+ r"(ThreatLevel):(?P<threat_level>.+)\n",
267
+ r"(ProcessID):(?P<process_id>.+)\n",
268
+ r"(ProcessCreationTime):(?P<process_creation_time>.+)\n",
269
+ r"(SessionID):(?P<session_id>.+)\n",
270
+ r"(CreationTime):(?P<ts>.+)\n",
271
+ r"(ImagePath):(?P<image_path>.+)\n",
272
+ r"(Taint Info):(?P<taint_info>.+)\n",
273
+ r"(Operations):(?P<operations>.+)\n",
274
+ r"END BM telemetry",
275
+ ]
276
+ )
277
+ ),
278
+ DefenderMPLogBMTelemetryRecord,
279
+ ),
280
+ ]
281
+
282
+ DEFENDER_MPLOG_LINE = re.compile(r"^\s+(.*)$", re.MULTILINE)
@@ -0,0 +1,191 @@
1
+ from dissect.target.helpers.record import TargetRecordDescriptor
2
+
3
+ DefenderMPLogProcessImageRecord = TargetRecordDescriptor(
4
+ "windows/defender/mplog/processimage",
5
+ [
6
+ ("datetime", "ts"),
7
+ ("path", "source_log"),
8
+ ("string", "process_image_name"),
9
+ ("varint", "pid"),
10
+ ("varint", "total_time"),
11
+ ("varint", "count"),
12
+ ("varint", "max_time"),
13
+ ("string", "max_time_file"),
14
+ ("varint", "estimated_impact"),
15
+ ],
16
+ )
17
+
18
+ DefenderMPLogMinFilUSSRecord = TargetRecordDescriptor(
19
+ "windows/defender/mplog/minfiluss",
20
+ [
21
+ ("datetime", "ts"),
22
+ ("path", "source_log"),
23
+ ("path", "path"),
24
+ ("string", "process"),
25
+ ("string", "status"),
26
+ ("string", "state"),
27
+ ("string", "scan_request"),
28
+ ("string", "file_id"),
29
+ ("string", "reason"),
30
+ ("string", "io_status_block_for_new_file"),
31
+ ("string", "desired_access"),
32
+ ("string", "file_attributes"),
33
+ ("string", "scan_attributes"),
34
+ ("string", "access_state_flags"),
35
+ ("string", "backing_file_info"),
36
+ ],
37
+ )
38
+
39
+ DefenderMPLogMinFilBlockedFileRecord = TargetRecordDescriptor(
40
+ "windows/defender/mplog/blockedfile",
41
+ [
42
+ ("datetime", "ts"),
43
+ ("path", "source_log"),
44
+ ("string", "blocked_file"),
45
+ ("string", "process"),
46
+ ("string", "status"),
47
+ ("string", "state"),
48
+ ("string", "scan_request"),
49
+ ("string", "file_id"),
50
+ ("string", "reason"),
51
+ ("string", "io_status_block_for_new_file"),
52
+ ("string", "desired_access"),
53
+ ("string", "file_attributes"),
54
+ ("string", "scan_attributes"),
55
+ ("string", "access_state_flags"),
56
+ ("string", "backing_file_info"),
57
+ ],
58
+ )
59
+
60
+
61
+ DefenderMPLogBMTelemetryRecord = TargetRecordDescriptor(
62
+ "windows/defender/mplog/bmtelemetry",
63
+ [
64
+ ("datetime", "ts"),
65
+ ("path", "source_log"),
66
+ ("string", "guid"),
67
+ ("varint", "signature_id"),
68
+ ("string", "sigsha"),
69
+ ("varint", "threat_level"),
70
+ ("varint", "process_id"),
71
+ ("varint", "process_creation_time"),
72
+ ("varint", "session_id"),
73
+ ("path", "image_path"),
74
+ ("string", "taint_info"),
75
+ ("string", "operations"),
76
+ ],
77
+ )
78
+
79
+ DefenderMPLogEMSRecord = TargetRecordDescriptor(
80
+ "windows/defender/mplog/ems",
81
+ [
82
+ ("datetime", "ts"),
83
+ ("path", "source_log"),
84
+ ("string", "process"),
85
+ ("varint", "pid"),
86
+ ("string", "sigseq"),
87
+ ("varint", "send_memory_scan_report"),
88
+ ("varint", "source"),
89
+ ],
90
+ )
91
+
92
+ DefenderMPLogOriginalFileNameRecord = TargetRecordDescriptor(
93
+ "windows/defender/mplog/originalfilename",
94
+ [
95
+ ("datetime", "ts"),
96
+ ("path", "source_log"),
97
+ ("string", "original_file_name"),
98
+ ("path", "full_path"),
99
+ ("string", "hr"),
100
+ ],
101
+ )
102
+
103
+ DefenderMPLogExclusionRecord = TargetRecordDescriptor(
104
+ "windows/defender/mplog/exclusion",
105
+ [
106
+ ("datetime", "ts"),
107
+ ("path", "source_log"),
108
+ ("path", "full_path_with_drive_letter"),
109
+ ("path", "full_path_with_device_path"),
110
+ ],
111
+ )
112
+
113
+ DefenderMPLogLowfiRecord = TargetRecordDescriptor(
114
+ "windows/defender/mplog/lowfi",
115
+ [
116
+ ("datetime", "ts"),
117
+ ("path", "source_log"),
118
+ ("command", "lowfi"),
119
+ ],
120
+ )
121
+
122
+ DefenderMPLogDetectionAddRecord = TargetRecordDescriptor(
123
+ "windows/defender/mplog/detectionadd",
124
+ [
125
+ ("datetime", "ts"),
126
+ ("path", "source_log"),
127
+ ("string", "detection"),
128
+ ],
129
+ )
130
+
131
+
132
+ DefenderMPLogThreatRecord = TargetRecordDescriptor(
133
+ "windows/defender/mplog/threat",
134
+ [
135
+ ("datetime", "ts"),
136
+ ("path", "source_log"),
137
+ ("command", "threat"),
138
+ ],
139
+ )
140
+
141
+ DefenderMPLogDetectionEventRecord = TargetRecordDescriptor(
142
+ "windows/defender/mplog/detectionevent",
143
+ [
144
+ ("datetime", "ts"),
145
+ ("path", "source_log"),
146
+ ("string", "threat_type"),
147
+ ("command", "command"),
148
+ ],
149
+ )
150
+
151
+ DefenderMPLogResourceScanRecord = TargetRecordDescriptor(
152
+ "windows/defender/mplog/resourcescan",
153
+ [
154
+ ("datetime", "ts"),
155
+ ("path", "source_log"),
156
+ ("string", "scan_id"),
157
+ ("varint", "scan_source"),
158
+ ("datetime", "start_time"),
159
+ ("datetime", "end_time"),
160
+ ("string", "resource_schema"),
161
+ ("path", "resource_path"),
162
+ ("varint", "result_count"),
163
+ ("string[]", "threats"),
164
+ ("path[]", "resources"),
165
+ ],
166
+ )
167
+
168
+ DefenderMPLogThreatActionRecord = TargetRecordDescriptor(
169
+ "windows/defender/mplog/threataction",
170
+ [
171
+ ("datetime", "ts"),
172
+ ("path", "source_log"),
173
+ ("string[]", "threats"),
174
+ ("path[]", "resources"),
175
+ ("string[]", "actions"),
176
+ ],
177
+ )
178
+
179
+ DefenderMPLogRTPRecord = TargetRecordDescriptor(
180
+ "windows/defender/mplog/rtp_log",
181
+ [
182
+ ("datetime", "ts"),
183
+ ("path", "source_log"),
184
+ ("datetime", "last_perf"),
185
+ ("datetime", "first_rtp_scan"),
186
+ ("string", "plugin_states"),
187
+ ("path[]", "process_exclusions"),
188
+ ("path[]", "path_exclusions"),
189
+ ("string[]", "ext_exclusions"),
190
+ ],
191
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dissect.target
3
- Version: 3.18.dev9
3
+ Version: 3.18.dev11
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
@@ -253,7 +253,7 @@ dissect/target/plugins/os/unix/log/lastlog.py,sha256=Wq89wRSFZSBsoKVCxjDofnC4yw9
253
253
  dissect/target/plugins/os/unix/log/messages.py,sha256=CXA-SkMPLaCgnTQg9nzII-7tO8Il_ENQmuYvDxo33rI,4698
254
254
  dissect/target/plugins/os/unix/log/utmp.py,sha256=1nPHIaBUHt_9z6PDrvyqg4huKLihUaWLrMmgMsbaeIo,7755
255
255
  dissect/target/plugins/os/windows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
256
- dissect/target/plugins/os/windows/_os.py,sha256=g5XGtruvyWx4YAhMpGZnAaIFWQqLNQpee_Ot7ROmD8w,12606
256
+ dissect/target/plugins/os/windows/_os.py,sha256=i9RPs99YD3KvZpAHAIuaQeGDy0nt5DIvfMbreqO_JIY,12723
257
257
  dissect/target/plugins/os/windows/activitiescache.py,sha256=Q2aILnhJ2rp2AwEbWwyBuSLjMbGqaYJTsavSbfkcFKE,6741
258
258
  dissect/target/plugins/os/windows/adpolicy.py,sha256=fULRFO_I_QxAn6G9SCwlLL-TLVliS13JEGnGotf7lSA,6983
259
259
  dissect/target/plugins/os/windows/amcache.py,sha256=ZZNOs3bILTf0AGkDkhoatndl0j39DXkstN7oOyxJECU,27188
@@ -262,7 +262,7 @@ dissect/target/plugins/os/windows/cim.py,sha256=jsrpu6TZpBUh7VWI9AV2Ib5bebTwsvqO
262
262
  dissect/target/plugins/os/windows/clfs.py,sha256=begVsZ-CY97Ksh6S1g03LjyBgu8ERY2hfNDWYPj0GXI,4872
263
263
  dissect/target/plugins/os/windows/credhist.py,sha256=YSjuyd53Augdy_lKKzZHtx5Ozt0HzF6LDYIOb-8P1Pw,7058
264
264
  dissect/target/plugins/os/windows/datetime.py,sha256=YKHUZU6lkKJocq15y0yCwvIIOb1Ej-kfvEBmHbrdIGw,9467
265
- dissect/target/plugins/os/windows/defender.py,sha256=lHHhyi8YqNTmBu3qbH7yskMAYcarYouPxKtBQLtXnnE,23713
265
+ dissect/target/plugins/os/windows/defender.py,sha256=VvcYsCc7gTJiz4LJotWqHU8k_4vo-mkCoBNx8bgtVEE,32608
266
266
  dissect/target/plugins/os/windows/env.py,sha256=-u9F9xWy6PUbQmu5Tv_MDoVmy6YB-7CbHokIK_T3S44,13891
267
267
  dissect/target/plugins/os/windows/generic.py,sha256=BSvDPfB9faU0uquMj0guw5tnR_97Nn0XAEE4k05BFSQ,22273
268
268
  dissect/target/plugins/os/windows/lnk.py,sha256=On1k0PODYggQM1j514qFepBACCV2Z2u61Q4Ba6e3Y2c,8179
@@ -280,6 +280,9 @@ dissect/target/plugins/os/windows/tasks.py,sha256=8DRsIAuIJPaH_G18l8RYfnK_WkEqVx
280
280
  dissect/target/plugins/os/windows/thumbcache.py,sha256=23YjOjTNoE7BYITmg8s9Zs8Wih2e73BkJJEaKlfotcI,4133
281
281
  dissect/target/plugins/os/windows/ual.py,sha256=TYF-R46klEa_HHb86UJd6mPrXwHlAMOUTzC0pZ8uiq0,9787
282
282
  dissect/target/plugins/os/windows/wer.py,sha256=ogecvKYxAvDXLptQj4cn0JLn1FxaXjeSuJWs4JgkoZs,8656
283
+ dissect/target/plugins/os/windows/defender_helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
284
+ dissect/target/plugins/os/windows/defender_helpers/defender_patterns.py,sha256=xsZH0WqMX_mC1q55jgp4RDHBRh2UQBXZVhJD0DRiwZU,9329
285
+ dissect/target/plugins/os/windows/defender_helpers/defender_records.py,sha256=_azaY5Y1cH-WPmkA5k94PMktZGYXmWJG8addFQxQ554,5177
283
286
  dissect/target/plugins/os/windows/dpapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
284
287
  dissect/target/plugins/os/windows/dpapi/blob.py,sha256=j3MMROXroes7pr_VLt8Xv6WEpv19hlgDpOxOJyZMRvo,5044
285
288
  dissect/target/plugins/os/windows/dpapi/crypto.py,sha256=_F1F2j1chQw-KLqfWvgL2mCkF3HSvdVnM78OZ0ph9hc,9337
@@ -340,10 +343,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z
340
343
  dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
341
344
  dissect/target/volumes/md.py,sha256=j1K1iKmspl0C_OJFc7-Q1BMWN2OCC5EVANIgVlJ_fIE,1673
342
345
  dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
343
- dissect.target-3.18.dev9.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
344
- dissect.target-3.18.dev9.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
345
- dissect.target-3.18.dev9.dist-info/METADATA,sha256=MhwBgTsOJRxjOgDeAphefB5vGoY0YAaydMIelDhkiRE,12722
346
- dissect.target-3.18.dev9.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
347
- dissect.target-3.18.dev9.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
348
- dissect.target-3.18.dev9.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
349
- dissect.target-3.18.dev9.dist-info/RECORD,,
346
+ dissect.target-3.18.dev11.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
347
+ dissect.target-3.18.dev11.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
348
+ dissect.target-3.18.dev11.dist-info/METADATA,sha256=mWlhvOaO7RcVbyJ0_fU7KHrnNaVL2vQ6a7uKhPvJ-kM,12723
349
+ dissect.target-3.18.dev11.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
350
+ dissect.target-3.18.dev11.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
351
+ dissect.target-3.18.dev11.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
352
+ dissect.target-3.18.dev11.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (70.1.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5