# Logging and SIEM Integration

## **Log Files**

By default, Enzoic for Active Directory stores logs in the following location on each Domain Controller:\
\&#xNAN;**`C:\ProgramData\Enzoic\Enzoic for Active Directory\Logs`**

For the Enzoic Client, log files can be found here:\
\&#xNAN;**`C:\ProgramData\Enzoic\Enzoic for Active Directory Client\Logs`**

The following log files are available:

<table data-full-width="true"><thead><tr><th width="91">LogType</th><th width="432">Filename(s)</th><th width="109">Format(s)</th><th>Description</th></tr></thead><tbody><tr><td>Console</td><td><em>EnzoicConsole_{logDate}.json</em><br><em>EnzoicConsole_{logDate}.log</em><br><em>EnzoicConsole_SystemDebugInformation.txt</em><br><em>__EnzoicConsole__FATAL_STARTUP_ERRORS.log</em></td><td>JSON<br>TXT</td><td>These are logs generated by the Enzoic console UI.</td></tr><tr><td>Service</td><td><em>EnzoicService_{logDate}.json</em><br><em>EnzoicService_{logDate}.log</em><br><em>EnzoicService_SystemDebugInformation.txt</em><br><em>__EnzoicService__FATAL_STARTUP_ERRORS.log</em></td><td>JSON<br>TXT</td><td>These are logs generated by the Enzoic service. These tend to be the most useful for troubleshooting and contain details for when a compromised password is found for a user by Compromised Password Protection as well as when a password change is blocked.</td></tr><tr><td>Filter</td><td><em>EnzoicFilter.txt</em></td><td>TXT</td><td>These are logs generated by the Enzoic password filter DLL.</td></tr><tr><td>Client</td><td><em>EnzoicForADClient_{logDate}.json</em><br><em>EnzoicForADClient_{logDate}.log</em><br><em>EnzoicForADClient_SystemDebugInformation.txt</em><br><em>__EnzoicForADClient__FATAL_STARTUP_ERRORS.log</em></td><td></td><td>These are logs generated by the Enzoic Client.</td></tr></tbody></table>

Log files are split after reaching 1 GB in size, with \_NNN being appended to the filename (e.g. EnzoicService\_20241218\_001.log). This generally won’t happen unless logging is left in\
Verbose mode for an extended period of time, but it can also occur if your domain has a\
&#x20;large number of users or password change/reset traffic.

Logs from previous days will be archived to ZIP files and placed into the Archive subfolder\
of the logs folder.  A maximum of 30 days of archived logs are maintained. Once this limit is reached, the oldest will be deleted first.

If for some reason the console, the service, or the client does not start at all, there will be\
an *\_\_Enzoic\*\*\*\_FATAL\_STARTUP\_ERRORS.log* for the failing module. This file, along with any\
other logs should be provided to Enzoic support to diagnose the problem, if requested.

## **SIEM Integration**

Enzoic for Active Directory logs important events to a JSON format log file which can be used for ingestion into SIEM systems. The following describes the information contained in these log entries.

Logs files are stored at:\
`C:\ProgramData\Enzoic\Enzoic for Active Directory\Logs`

### **1.1 Log Entry Fields / Structure**

Each JSON log entry has the following structure.

<table><thead><tr><th width="150">Field</th><th>Description</th></tr></thead><tbody><tr><td>time</td><td>Timestamp at which the event occurred.</td></tr><tr><td>threadId</td><td>The managed .NET thread ID which was running.</td></tr><tr><td>level</td><td>Level of event severity. This can be one of the following: INFO, WARN, ERROR.</td></tr><tr><td>eventData</td><td>A JSON object containing additional details, specific to the event. The object has one field, “data” containing an object with the actual details.</td></tr><tr><td>event</td><td>This is either a message or an enum value indicating the event kind. (see the eventKind field in table 1.2)</td></tr></tbody></table>

### **1.2 Event Data Fields – Common to All Events**

The content of eventData varies per the type of logged event, but the following fields are always present.

<table><thead><tr><th width="152">Field</th><th>Description</th></tr></thead><tbody><tr><td>eventKind</td><td>Indicates the nature of the event. See table 1.3 for possible values.</td></tr><tr><td>details</td><td>Either a free-form complex object or extended message. Can be null.</td></tr></tbody></table>

### **1.3 Event Kinds**

<table><thead><tr><th width="458">Name</th><th>Description</th></tr></thead><tbody><tr><td>Info</td><td>General informational message.</td></tr><tr><td>Warning</td><td>A recoverable problem or unusual event has occurred.</td></tr><tr><td>Error</td><td>A (possibly unrecoverable) problem has occurred, and may require user intervention or investigation.</td></tr><tr><td>PasswordChanged</td><td>User account password was changed.</td></tr><tr><td>PasswordChangeRejected</td><td>User account password change was attempted, but the password did not pass the integrity checks.</td></tr><tr><td>CompromiseDetectedDelayedRemediationScheduled</td><td>A compromised password was detected, and was either remediated, or scheduled for remediation after a delay.</td></tr><tr><td>DelayedRemediationActionTaken</td><td>A previously scheduled remediation was applied.</td></tr></tbody></table>

## **Log Entry Details for Each Event Kind**

### **1.4 Info**

Recorded when there is a general informational message.

Example:

```json
{
  "time": "2019-08-07 16:24:57.2758",
  "threadId": "22",
  "level": "INFO",
  "event": "Service shutdown.",
  "eventData": {
    "data": {
      "eventKind": "Info",
      "details": null
    }
  }
}
```

### **1.5 Warning**

Recorded when a recoverable problem or unusual event has occurred.

Example:

```json
{
  "time": "2019-08-07 15:02:37.3696",
  "threadId": "10",
  "level": "WARN",
  "event": "The user tu1 no longer exists. Cleaning up artifacts related to this user.",
  "eventData": {
    "data": {
      "eventKind": "Warning",
      "details": null
    }
  }
}
```

### **1.6 Error**

Recorded when a problem has occurred that may require user intervention or investigation. The eventData payload contains the exception details and can be helpful to support for further investigation.

<table><thead><tr><th width="199">Field</th><th>Description</th></tr></thead><tbody><tr><td>exceptionClass</td><td>The name of the .NET exception class, if there is an exception.</td></tr><tr><td>exceptionMessage</td><td>The exception message, if there is an exception.</td></tr></tbody></table>

Example:

```json
{
  "time": "2019-08-07 15:02:37.3696",
  "threadId": "10",
  "level": "ERROR",
  "event": "Something bad happened..",
  "eventData": {
    "data": {
      "eventKind": "Error",
      "details": null,
      "exceptionClass": "Exception",
      "exceptionMessage": "Exception text"
    }
  }
}
```

### **1.7 PasswordChanged**

Recorded when a user password was successfully changed.

<table><thead><tr><th width="213">Field</th><th>Description</th></tr></thead><tbody><tr><td>user</td><td>The SAM account name of the account that was updated.</td></tr></tbody></table>

Example:

```json
{
  "time": "2019-08-07 15:00:59.9008",
  "threadId": "16",
  "level": "INFO",
  "event": "PasswordChanged",
  "eventData": {
    "data": {
      "user": "tu1",
      "eventKind": "PasswordChanged",
      "details": null
    }
  }
}
```

### **1.8 PasswordChangeRejected**

Recorded when a user password change was rejected by Enzoic due to policy settings.

<table><thead><tr><th width="202">Field</th><th>Description</th></tr></thead><tbody><tr><td>user</td><td>The SAM account name of the account on which the password change was attempted.</td></tr><tr><td>detection methods</td><td>EnzoicApi,<br>LocalDictionary,<br>PasswordSimilarity,<br>UserDisplayName,<br>UserName,<br>UserEmail</td></tr><tr><td>match types</td><td>ExactMatch,<br>FuzzyMatch,<br>RootPasswordMatch</td></tr></tbody></table>

Example:

```json
{
  "time":"2020-09-02 14:15:08.5068",
  "threadId": "4",
  "level": "INFO",
  "event": "The password is compromised and cannot be used. Detected by EnzoicApi and matched on RootPasswordMatch",
  "eventData": {
    "data": {
      "user": "testfosmo",
      "detectionMethod":"EnzoicApi",
      "matchTypes":[
        "RootPasswordMatch"
      ],
      "eventKind": "PasswordChangeRejected",
      "details": null
    }
  }
}
```

### **1.9 CompromiseDetectedDelayedRemediationScheduled**

Recorded by User Password Monitoring when a user password was detected as compromised and a delayed remediation was scheduled (e.g. force password change after 24 hours)

<table><thead><tr><th width="213">Field</th><th>Description</th></tr></thead><tbody><tr><td>user</td><td>The SAM account name of the affected account.</td></tr><tr><td>detectionTimestamp</td><td>Timestamp of when the compromise was detected.</td></tr><tr><td>actionTaken</td><td>Indicates the action that was taken in response to the compromise. See table 1.11 for possible values.</td></tr><tr><td>actionDelayHours</td><td>The number of hours before the delayed remediation will take effect . This only applies when actionTaken is ForcePasswordChangeOnLoginDelayed or DisableAccountDelayed</td></tr></tbody></table>

Example:

```json
{
  "time": "2019-08-07 15:01:35.7445",
  "threadId": "10",
  "level": "INFO",
  "event": "CompromiseDetectedDelayedRemediationScheduled",
  "eventData": {
    "data": {
      "user": "tu1",
      "detectionTimestamp": "2019-08-07T15:01:35.7134337-04:00",
      "actionTaken": "ForcePasswordChangeOnLoginDelayed",
      "actionDelayHours": 1,
      "eventKind": "CompromiseDetectedDelayedRemediationScheduled",
      "details": null
    }
  }
}
```

### **1.10 DelayedRemediationActionTaken**

Recorded by User Password Monitoring when a previously scheduled delayed remediation was taken. For example, if a user was scheduled to force a password change after 24 hours, this event gets logged when the user is set to Force Password Change on Next Logon in AD.

<table><thead><tr><th width="217">Field</th><th>Description</th></tr></thead><tbody><tr><td>user</td><td>The SAM account name of the affected account.</td></tr><tr><td>detectionTimestamp</td><td>Timestamp of when the compromise was detected.</td></tr><tr><td>actionTaken</td><td>Possible values: ForcePasswordChangeOnLogin, DisableAccount</td></tr><tr><td>actionDelayHours</td><td>Always zero.</td></tr></tbody></table>

Example:

```json
{
  "time": "2019-08-07 15:01:35.7445",
  "threadId": "10",
  "level": "INFO",
  "event": "DelayedRemediationActionTaken",
  "eventData": {
    "data": {
      "user": "tu1",
      "detectionTimestamp": "2019-08-07T15:01:35.7134337-04:00",
      "actionTaken": "ForcePasswordChangeOnLogin",
      "actionDelayHours": 0,
      "eventKind": "DelayedRemediationActionTaken",
      "details": null
    }
  }
}
```

### **1.11 Remediation Actions**

The possible remediation action values for log events are listed below.

<table><thead><tr><th width="352">Name</th><th>Description</th></tr></thead><tbody><tr><td>ForcePasswordChangeOnLogin</td><td>The affected user account is updated to require the password to be changed on the next login attempt.</td></tr><tr><td>ForcePasswordChangeOnLoginDelayed</td><td>The affected user account is updated to require the password to be changed on the next login attempt. This action is delayed by the number of configured hours.</td></tr><tr><td>DisableAccount</td><td>The affected user account is disabled.</td></tr><tr><td>DisableAccountDelayed</td><td>The affected user account is disabled. This action is delayed by the number of configured hours.</td></tr><tr><td>NotifyOnly</td><td>An email notification is sent to the configured recipients. No further remediation is taken.</td></tr></tbody></table>

<br>
