AutoLogger-Diagtrack-Listener.etl is a potential source of evidence of execution and other system diagnostic data.
If AutoLogger-Diagtrack-Listener.etl exists, we use the built-in tracerpt to parse and extract each XML record as a row.
NOTE: A good workflow is running Windows.Search.FileFinder or Yara.Glob targeting strings of interest, then running AutoLoggerDiagtrackListener to parse hits.
ETL Globs:C:/ProgramData/Microsoft/Diagnosis/ETLLogs/**/*.etlC:/Windows/System32/LogFiles/**/*.etlC:/Windows/System32/WDI/**/*.etl
name: Windows.System.AutoLoggerDiagtrackListener
author: Matt Green - @mgreen27
description: |
AutoLogger-Diagtrack-Listener.etl is a potential source of evidence of
execution and other system diagnostic data.
If AutoLogger-Diagtrack-Listener.etl exists, we use the built-in tracerpt to
parse and extract each XML record as a row.
NOTE: A good workflow is running Windows.Search.FileFinder or Yara.Glob
targeting strings of interest, then running AutoLoggerDiagtrackListener to
parse hits.
ETL Globs:
`C:/ProgramData/Microsoft/Diagnosis/ETLLogs/**/*.etl`
`C:/Windows/System32/LogFiles/**/*.etl`
`C:/Windows/System32/WDI/**/*.etl`
reference:
- https://www.fortinet.com/blog/threat-research/uncovering-hidden-forensic-evidence-in-windows-mystery-of-autologger
type: CLIENT
parameters:
- name: TargetGlob
default: C:\\ProgramData\\Microsoft\\Diagnosis\\ETLLogs\\AutoLogger\\AutoLogger-Diagtrack-Listener.etl
- name: EventNameRegex
default: .
description: Regex to filter on EventName - E.g ProcessStarted
- name: EventDataRegex
default: .
description: Regex to filter rows returned on EventData
required_permissions:
- EXECVE
- FILESYSTEM_WRITE
sources:
- precondition:
SELECT OS From info() where OS = 'windows'
query: |
LET out_folder <= tempdir(remove_last=true)
LET target_files = SELECT
OSPath,
Size,
Mtime,
Btime,
path_join(components=[out_folder, str(str=count()) + "parsed_etl.xml"],
path_type='windows') AS ParsedOutput
FROM glob(globs=TargetGlob)
LET parse_etl(path, out) = SELECT *
FROM execve(argv=['cmd.exe', '/c', 'tracerpt', path, '-o', out, '-y'])
LET run_parser <= SELECT *
FROM foreach(row=target_files,
query={
SELECT OSPath,
ParsedOutput,
*
FROM parse_etl(path=OSPath, out=ParsedOutput)
WHERE Stdout =~ 'The command completed successfully.'
})
LET event_records = SELECT *
FROM foreach(row=run_parser,
query={
SELECT parse_xml(accessor='data', file=Record) AS Parsed,
OSPath
FROM parse_records_with_regex(file=ParsedOutput,
regex='(?s)(?P<Record><Event .*?</Event>)')
})
SELECT
Parsed.Event.System.TimeCreated.AttrSystemTime AS EventTime,
Parsed.Event.System.Provider.AttrName AS Provider,
Parsed.Event.RenderingInfo.Task || Parsed.Event.RenderingInfo.Opcode AS EventName,
Parsed.Event.System.Execution.AttrProcessID AS SourcePid,
Parsed.Event.System.EventID AS EventID,
if(
condition=Parsed.Event.EventData.Data,
then=to_dict(
item={
SELECT
AttrName AS _key,
`#text` AS _value
FROM Parsed.Event.EventData.Data
}),
else=Parsed.Event.EventData) AS EventData,
OSPath
FROM event_records
WHERE EventName =~ EventNameRegex
AND EventData =~ EventDataRegex