dissect.target 3.18.dev9__py3-none-any.whl → 3.18.dev11__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -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