EVTX Parser and Event Log Analysis: !!!!README

# EvtxECmd Maps

Map files are used to convert the EventData (the unique part of an event) to a more standardized format. Map files are specific to a certain type of event log, such as Security, Application, etc.

Because different event logs may reuse Event IDs, Maps need to be specific to a certain kind of log. This specificity is done by using a unique identifier for a given event log, the Channel. We will see more about this in a moment.

Once you know what event log and Event ID you want to make a Map for, the first thing to do is dump the log's records to XML, using EvtxECmd.exe as follows:

```
EvtxECmd.exe -f <your eventlog> --xml c:\temp\xml
```

When the command finishes, open the generated xml file in c:\temp\ and find your Event ID of interest. Let's say its from the Security log and its Event ID 4624, It might look like this:

```xml
<Event>
  <System>
    <Provider Name="Microsoft-Windows-Security-Auditing" Guid="[PII_REDACTED]-a5ba-3e3b0328c30d" />
    <EventID>4624</EventID>
    <Version>2</Version>
    <Level>0</Level>
    <Task>12544</Task>
    <Opcode>0</Opcode>
    <Keywords>0x[PII_REDACTED]000000</Keywords>
    <TimeCreated SystemTime="2018-05-04 22:14:31.3192953" />
    <EventRecordID>495</EventRecordID>
    <Correlation ActivityID="69aa9df0-e3d4-0007-f39d-aa69d4e3d301" />
    <Execution ProcessID="716" ThreadID="6724" />
    <Channel>Security</Channel>
    <Computer>win10-test</Computer>
    <Security />
  </System>
  <EventData>
    <Data Name="SubjectUserSid">S-1-5-18</Data>
    <Data Name="SubjectUserName">WIN10-TEST$</Data>
    <Data Name="SubjectDomainName">TEMP</Data>
    <Data Name="SubjectLogonId">0x3E7</Data>
    <Data Name="TargetUserSid">S-1-5-18</Data>
    <Data Name="TargetUserName">SYSTEM</Data>
    <Data Name="TargetDomainName">NT AUTHORITY</Data>
    <Data Name="TargetLogonId">0x3E7</Data>
    <Data Name="LogonType">5</Data>
    <Data Name="LogonProcessName">Advapi  </Data>
    <Data Name="AuthenticationPackageName">Negotiate</Data>
    <Data Name="WorkstationName">-</Data>
    <Data Name="LogonGuid">[PII_REDACTED]-[PII_REDACTED]</Data>
    <Data Name="TransmittedServices">-</Data>
    <Data Name="LmPackageName">-</Data>
    <Data Name="KeyLength">0</Data>
    <Data Name="ProcessId">0x2C4</Data>
    <Data Name="ProcessName">C:\Windows\System32\services.exe</Data>
    <Data Name="IpAddress">-</Data>
    <Data Name="IpPort">-</Data>
    <Data Name="ImpersonationLevel">%%1833</Data>
    <Data Name="RestrictedAdminMode">-</Data>
    <Data Name="TargetOutboundUserName">-</Data>
    <Data Name="TargetOutboundDomainName">-</Data>
    <Data Name="VirtualAccount">%%1843</Data>
    <Data Name="TargetLinkedLogonId">0x0</Data>
    <Data Name="ElevatedToken">%%1842</Data>
  </EventData>
</Event>
```

Just about everything in the `<System>` element is normalized by default, but if you want to include anything from there you can do so using the techniques we will see below.

In most cases, the data in the `<EventData>` block is what you want to process. This is where xpath queries come into play.

So let's take a look at a Map to make things a bit more clear.

In the example below, there are four header properties that describe the Map: who wrote it, what its for, the Channel, and the Event ID the Map corresponds to.

The Channel and Event ID property are what make a Map unique, not the name of the file. As long as the Map ends with '.Map' it will be processed.

The Channel is a useful identifier for a given log type. It can be seen in the `<Channel>` element ("Security" in the example above).

The Maps collection contains configurations for how to look for data in an events EventData and extract out particular properties into variables. These variables are then combined and Mapped to the event record's first class properties.

For example, consider the first Map, for `UserName`, below.

The `PropertyValue` defines the pattern that will be used to build the final value that will be assigned to the UserName field in the CSV. Variables in patterns are surrounded by % on both sides, so we see two variables defined: `%domain%` and `%user%`

In the Map entries `Values` collection, we actually populate these variables by giving the value a name (domain in the first case) and an xpath query that will be used to set the value for the variable (`"/Event/EventData/Data[@Name=\"SubjectDomainName\"]"` in the first case).

When a Map is processed, each Map entry has its `Values` items processed so the variables are populated with data. Then the `PropertyValue` is updated and the variables are replaced with the actual values. This final PropertyValue is then updated in the event record which then ends up in the CSV/JSON, etc.

It is that simple! Be sure to surround things in double quotes and/or escape quotes as in the examples. When in doubt, test your Map against real data!

NOTE! The filenames for Maps should be in the following format:

`Channel-Name_Provider-Name_EventID.Map`

Where Channel is EXACTLY what is in the XML `<Channel>` element with any '/' characters, hyphens, or spaces replaced with a hyphen. Hyphens are the catch all for each element of the Map filename.

Only underscores should separate each element (Channel Name, Provider Name, EventID). Hyphens separates words. Underscores separate elements.

For example, for Event ID `201` and Channel `Microsoft-Windows-TaskScheduler/Operational` the file should be named:

`Microsoft-Windows-TaskScheduler-Operational_Microsoft-Windows-TaskScheduler_201.Map`

`Provider` is now mandatory. Provider is used at the header level and looks like this:

`Provider: "Microsoft-Windows-Power-Troubleshooter"`

This lets you further narrow down when a Map will be used. Every Map will have a working example of this now.

As of v06 or so, you can also add optional properties such as `Lookups`.

Lookups allow you to define lookup tables that match one value and replace them with another. Here is an example, also from `System_Microsoft-Windows-Kernel-General_1.Map`:

Lookups:
```
  -
    Name: WakeSourceType
    Default: Unknown code
    Values:
        0: Unknown
        1: Power button
        3: Waking from sleep to hibernate
        5: Device (See WakeSourceText for details)
        6: Timer (See WakeSourceText for details)
```

The name of the lookup table determines when it will be used and should match the name of the property you want to apply the lookup to. Example:

```
  -
    Property: PayloadData2
    PropertyValue: Wake source "%WakeSourceType%"
    Values:
      -
        Name: WakeSourceType
        Value: "/Event/EventData/Data[@Name=\"WakeSourceType\"]"
```

Here, when the Map is applied, the numerical value for WakeSourceType is filtered through the Lookup with the same name, and the value is updated to reflect the more human readable version. If you want BOTH the original value and  the lookup value, simply reference the original using a different Name under Values, then reference that adjust