# Custom EVTX Logs

## SUMMARY

This lays out how to create a subscription (both source and collector initiated) that collects selected forwarded **`.evtx`** event logs from a workstation to a domain controller.

## ENVIRONMENT

| WINDOWS         | OS                           | BUILD NO.              | REMARKS           |
| --------------- | ---------------------------- | ---------------------- | ----------------- |
| WIN-BO2CT95INDP | Windows Server 2016 Standard | 10.0.14393 Build 14393 | Collector Machine |

## APPLICATIONS/TOOLS USED

1. Windows SDK (Development Kit):
   * ecmangen.exe
   * mc.exe (Message Compiler)
   * rc.exe (Resource Compiler)
2. csc.exe (C# Compiler)
3. wevtutil

* **ecmangen.exe** was removed from the Windows 10 SDK starting from 10.0.16299.15
  * Parallel installations of Windows SDK are allowed.
  * In this case, [Windows 10 SDK (10.0.14393.795)](https://go.microsoft.com/fwlink/p/?LinkId=838916) was installed alongside the latest SDK version.
* **csc.exe** is included in the ***Microsoft .NET Framework***.
  * **.NET Framework** is native to Windows Operating Systems.
  * The Framework's version depends on the OS installed.
* **wevtutil** is a command native to the ***Command Prompt***

## PROCEDURE

### 1. Create a manifest file

Open `ecmangen.exe`:

```
C:\Program Files (x86)\Windows Kits\10\bin\x64\ecmangen.exe
```

Create a new ***provider***:

1. On the left panel, right click on `Events Section` then select **New** -> **Provider**.
2. Fill up the following fields:

   | FIELD     | VALUE                              |
   | --------- | ---------------------------------- |
   | Name      | WEF-Events                         |
   | Symbol    | WEF\_Events                        |
   | GUID      | Press "New" beside the input field |
   | Resources | C:\Windows\System32\WEF-Events.dll |
   | Messages  | C:\Windows\System32\WEF-Events.dll |

On the right panel, click on `Save`. Then, create a new ***template***:

1. On the left panel, under `WEF-Events`, select `Templates`.
2. On the right panel, select `New Template`.&#x20;
3. Fill up the following fields:

   | FIELD | VALUE        |
   | ----- | ------------ |
   | Name  | WEF-Template |
4. Add `Field Attributes`:

   | Name    | InType            | OutType        | Count   | Length  |
   | ------- | ----------------- | -------------- | ------- | ------- |
   | Unicode | win:UnicodeString | xs:string      | default | default |
   | UInt32  | win:UInt32        | xs:unsignedInt | default | -       |
5. On the right panel, click `Save`.

Create ***channels*** (maximum of 8):

1. On the left panel, under `WEF-Events`, select `Channels`.
2. On the right panel, select `New Channel`.
3. Fill up the following fields:

   | NAME           | SYMBOL          | TYPE        | ENABLE | DESCRIPTION        | CHANNEL SECURITY |
   | -------------- | --------------- | ----------- | ------ | ------------------ | ---------------- |
   | WEF-Security   | WEF\_Security   | Operational | Yes    | DC Security Logs   | Default          |
   | WEF-System     | WEF\_System     | Operational | Yes    | DC System Logs     | Default          |
   | WEF-PowerShell | WEF\_PowerShell | Operational | Yes    | DC PowerShell Logs | Default          |
   | WEF-Sysmon     | WEF\_Sysmon     | Operational | Yes    | DC Sysmon Logs     | Default          |
4. On the right panel, click `Save`.

Create a new ***event***:

1. On the left panel, under `WEF-Events`, select `Events`.
2. On the right panel, select `New Event`.
3. Fill up the following fields:

   | FIELD    | VALUE                                      |
   | -------- | ------------------------------------------ |
   | Symbol   | WEF\_Event                                 |
   | Event ID | 6969                                       |
   | Message  | $(string.WEF-Events.event.6969.message)    |
   | Channel  | WEF-Security                               |
   | Template | WEF-Template                               |
   | Keywords | \`win:AuditSuccess\`, \`win:AuditFailure\` |
4. On the right panel, click on `Save`.

Save the manifest file as "**WEF\_Events.man**"

* Avoid using the character, '`-`', in the filename.
  * The generated C# file during compiling will face an error.
* Resulting manifest file (XML formatted):

  ```markup
  <?xml version="1.0"?>
  <instrumentationManifest xsi:schemaLocation="http://schemas.microsoft.com/win/2004/08/events eventman.xsd" xmlns="http://schemas.microsoft.com/win/2004/08/events" xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:trace="http://schemas.microsoft.com/win/2004/08/events/trace">
    <instrumentation>
   <events>
        <provider name="WEF-Events" guid="{CB3EB4AA-FEDD-41C4-A7BB-E173045E4DC7}" symbol="WEF_Events" resourceFileName="C:\Windows\System32\WEF_Events.dll" messageFileName="C:\Windows\System32\WEF_Events.dll">
          <events>
            <event symbol="WEF_Event" value="6969" version="0" channel="WEF-Security" template="WEF-Template" keywords="win:AuditSuccess win:AuditFailure " message="$(string.WEF-Events.event.6969.message)"></event>
          </events>
          <channels>
            <channel name="WEF-Security" chid="WEF-Security" symbol="WEF_Security" type="Operational" enabled="true" message="$(string.WEF-Events.channel.WEF_Security.message)"></channel>
            <channel name="WEF-System" chid="WEF-System" symbol="WEF_System" type="Operational" enabled="true" message="$(string.WEF-Events.channel.WEF_System.message)"></channel>
            <channel name="WEF-PowerShell" chid="WEF-PowerShell" symbol="WEF_PowerShell" type="Operational" enabled="true" message="$(string.WEF-Events.channel.WEF_PowerShell.message)"></channel>
            <channel name="WEF-Sysmon" chid="WEF-Sysmon" symbol="WEF_Sysmon" type="Operational" enabled="true" message="$(string.WEF-Events.channel.WEF_Sysmon.message)"></channel>
          </channels>
          <keywords></keywords>
          <templates>
            <template tid="WEF-Template">
              <data name="Unicode" inType="win:UnicodeString" outType="xs:string"></data>
          <data name="UInt32" inType="win:UInt32" outType="xs:unsignedInt"></data>
            </template>
          </templates>
        </provider>
      </events>
    </instrumentation>
    <localization>
      <resources culture="en-US">
        <stringTable>
          <string id="keyword.AuditSuccess" value="Audit Success"></string>
          <string id="keyword.AuditFailure" value="Audit Failure"></string>
          <string id="WEF-Events.event.6969.message" value="$(string.WEF-Events.event.6969.message)"></string>
          <string id="WEF-Events.channel.WEF_System.message" value="DC System Logs"></string>
          <string id="WEF-Events.channel.WEF_Sysmon.message" value="DC Sysmon Logs"></string>
          <string id="WEF-Events.channel.WEF_Security.message" value="DC Security Logs"></string>
          <string id="WEF-Events.channel.WEF_PowerShell.message" value="DC PowerShell Logs"></string>
        </stringTable>
      </resources>
    </localization>
  </instrumentationManifest>
  ```

### 2. Compile the manifest file and generate relevant files (e.g. WEF-Events.dll)

Press `Win` + `R` then enter `cmd` and navigate to where `WEF_Events.man` was saved. Then, enter the following commands:&#x20;

1\. **mc.exe** (Message Compiler)

```
   "C:\Program Files (x86)\Windows Kits\10\bin\x64\mc.exe" WEF_Events.man
   "C:\Program Files (x86)\Windows Kits\10\bin\x64\mc.exe" -css WEF_Events.DummyEvent WEF_Events.man
```

* The compiler generates the message resource files to which your application links.
* Switches used:

  | OPTION            | DESCRIPTION                                                                                                                                  |
  | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
  | -css \<namespace> | <ul><li>Generates a static C# class</li><li>It includes the methods that you would call to log the events defined in your manifest</li></ul> |

File(s) generated after execution:

* MSG00001.bin
* WEF\_Events.cs
* WEF\_Events.h
* WEF\_Events.rc
* WEF\_EventsTEMP.bin

2\. **rc.exe** (Resource Compiler)

```
"C:\Program Files (x86)\Windows Kits\10\bin\x64\rc.exe" WEF_Events.rc

# Microsoft (R) Windows (R) Resource Compiler Version 10.0.10011.16384
# Copyright (C) Microsoft Corporation.  All rights reserved.
```

* `rc.exe` compiles an application's resources and could be used to build Windows-based applications.
* File(s) generated after execution:
  * WEF\_Events.res

3\. **csc.exe** (C# Compiler)

```
"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe" /win32res:WEF_Events.res /unsafe /target:library /out:WEF_Events.dll WEF_Events.cs
```

* No output means the command was successfully executed&#x20;
* Switches used:

  | OPTION            | DESCRIPTION                                                                         |
  | ----------------- | ----------------------------------------------------------------------------------- |
  | /win32res:\<file> | Specify a Win32 resource file (.res)                                                |
  | /unsafe           | Allow 'unsafe' code                                                                 |
  | /target:library   | Build a library (Short form: /t:library)                                            |
  | /out:\<file>      | Specify output file name (default: base name of file with main class or first file) |
* File(s) generated after execution -- WEF\_Events.dll

### 3. Install the **manifest file** with the matching **dll file**:

1. Move both files to the `C:\Windows\System32` directory:

   ```
   copy .\WEF_Events.man C:\Windows\System32\WEF_Events.man
   copy .\WEF_Events.dll C:\Windows\System32\WEF_Events.dll
   ```
2. Install the manifest file using `wevtutil`:

   ```
   wevtutil im C:\Windows\System32\WEF_Events.man
   ```

### 4. The created logs should appear under `Applications and Services Logs` inside **Event Viewer**

* The logs generated could be used for created subscriptions.
* Additional columns could be added/removed from the logs (e.g. `Log`, `Computer`)&#x20;

## REFERENCES

```
- https://blogs.technet.microsoft.com/russellt/2016/05/18/creating-custom-windows-event-forwarding-logs/
- https://stackoverflow.com/questions/53028775/cannot-locate-ecmangen
- https://developer.microsoft.com/en-us/windows/downloads/sdk-archive
- https://blogs.msdn.microsoft.com/astebner/2007/03/14/mailbag-what-version-of-the-net-framework-is-included-in-what-version-of-the-os/
- https://docs.microsoft.com/en-us/windows/win32/wes/message-compiler--mc-exe-
- https://docs.microsoft.com/en-us/windows/win32/menurc/using-rc-the-rc-command-line-
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://seymour.hackstreetboys.ph/projects/blue-team/custom-evtx-logs.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
