Skip to content
Please update to the latest release 0.77.2 to address Multiple CVEs.
Windows.System.WindowsErrorReporting

Windows.System.WindowsErrorReporting

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 (e.g. 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.


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 (e.g. 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 OSPath 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 OSPath,
                                                             to_dict(item={
                                                                        SELECT _key,_value
                                                                        FROM parse_records_with_regex(file=utf16(string=read_file(filename=OSPath)),
                                                                                                    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,
                OSPath as ReportFileName
        FROM parsed_reports

  - name: WERInternalMetadata
    query: |

        LET files = SELECT OSPath 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 OSPath, parse_xml(
                                                               accessor='data',
                                                               file=regex_replace(
                                                                    source=utf16(string=Data),
                                                                    re='<[?].+?>',
                                                                    replace='')) AS XML
                                                      FROM read_file(filenames=OSPath)
                                                  })

        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,
                OSPath
        FROM parsed_reports

  - name: WERProcessTree
    query: |

        LET files = SELECT OSPath 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=OSPath)),accessor="data")
                                                  })

        SELECT *
        FROM parsed_reports