Parses several Windows Error Reporting (WER) files that contain information about crashed programs.
This can include:
After Windows 10, Report.wer files in the ProgramData directory also contain a SHA1 hash (similar to Amcache) which can assist investigators tracking down processes that have since been deleted.
name: Windows.System.WindowsErrorReporting
author: Zach Stanford - @svch0st
description: |
Parses several Windows Error Reporting (WER) files that contain information about crashed programs.
This can include:
* evidence historical malware execution that have crashed,
* unstable executables after being injected into, and
* loaded DLLs by other executables (eg rundll32.exe and regsvr32.exe)
After Windows 10, Report.wer files in the ProgramData directory also contain a SHA1 hash (similar to Amcache) which can assist investigators tracking down processes that have since been deleted.
reference:
- http://0xdabbad00.com/wp-content/uploads/2014/01/notes_on_wer.pdf
- https://medium.com/dfir-dudes/amcache-is-not-alone-using-wer-files-to-hunt-evil-86bdfdb216d7
type: CLIENT
sources:
- name: AppCrashReport
query: |
LET files = SELECT FullPath FROM glob(globs=["C:/Users/*/AppData/Local/Microsoft/Windows/WER/*/*/Report.wer",
"C:/ProgramData/Microsoft/Windows/WER/*/*/Report.wer"])
LET parsed_reports = SELECT * FROM foreach(row=files,
query={
SELECT FullPath,
to_dict(item={
SELECT _key,_value
FROM parse_records_with_regex(file=utf16(string=read_file(filename=FullPath)),
accessor="data",
regex="(?P<_key>.*)=(?P<_value>.*)\r\n")
}
) as Report
FROM scope()
})
SELECT timestamp(winfiletime=int(int=Report.EventTime)) as timestamp,
Report.EventType,
Report.FriendlyEventName,
Report.AppName,
Report.AppPath,
Report.ApplicationIdentity,
if(condition=Report.TargetAppId=~'^W', -- Appears non-microsoft apps that have a hash only start with "W".
then=strip(string=split(sep='!',string=Report.TargetAppId)[1],prefix='0000'), -- Prefix of 0000 similar th hash format in Amcache
else="No hash information") as SHA1,
Report.OriginalFilename,
Report,
FullPath as ReportFileName
FROM parsed_reports
- name: WERInternalMetadata
query: |
LET files = SELECT FullPath FROM glob(globs=["C:/Users/*/AppData/Local/Microsoft/Windows/WER/*/*/*InternalMetadata.xml",
"C:/ProgramData/Microsoft/Windows/WER/*/*/*InternalMetadata.xml"])
LET parsed_reports = SELECT * FROM foreach(row=files,
query={
SELECT FullPath, parse_xml(
accessor='data',
file=regex_replace(
source=utf16(string=Data),
re='<[?].+?>',
replace='')) AS XML
FROM read_file(filenames=FullPath)
})
SELECT XML.WERReportMetadata.ReportInformation.CreationTime as timestamp,
XML.WERReportMetadata.ProcessInformation.ImageName as ImageName,
XML.WERReportMetadata.ProcessInformation.Pid as Pid,
XML.WERReportMetadata.ProcessInformation.ParentProcess.ProcessInformation.ImageName as ParentImageName,
XML.WERReportMetadata.ProcessInformation.ParentProcess.ProcessInformation.Pid As ParentPid,
XML.WERReportMetadata.ProblemSignatures.EventType as EventType,
XML.WERReportMetadata.ProblemSignatures.Parameter0 as Parameter0,
XML,
FullPath
FROM parsed_reports
- name: WERProcessTree
query: |
LET files = SELECT FullPath FROM glob(globs=["C:/Users/*/AppData/Local/Microsoft/Windows/WER/*/*/*.csv",
"C:/ProgramData/Microsoft/Windows/WER/*/*/*.csv"])
LET parsed_reports = SELECT * FROM foreach(row=files,
query={
SELECT *
FROM parse_csv(filename=utf16(string=read_file(filename=FullPath)),accessor="data")
})
SELECT *
FROM parsed_reports