Skip to content

SysLog Event Generation

When syslog event generation is enabled on the WCS service, it generates syslog events that can be fed to SIEMs and other cybersecurity analysis tools. Syslogs are generated with a 'wcsec' prefix.

SysLog Tags

System Status Events

Syslog Tag Event Description
livehosts Live Hosts Count Update Number of Live Hosts

Host Status Events

Syslog Tag Event Description
blockmode Blocking Mode Change The endpoint's blocking mode changed
version Agent Version Change The endpoint's agent version changed
certsonly CERTs Only Learn Mode The endpoint was set to only learn CERTs
certhands CERTs and Unsigned Learn Mode The endpoint was set to learn CERTs and unsigned apps
handsonly Handprints Only Learn Mode The endpoint was set to only handprints
learnall Learn All Mode The endpoint was set to learn all CERTs and handprints
exit Exit Learn Mode The endpoint's learn mode was stopped
timeout Agent Version Change The endpoint's learn mode session timed out

App Events

The panel type indicates which panel the event should be displayed in. Some events can be displayed in either the Blocked Apps or Monitor Mode Exceptions panel, depending upon the value of the event's "blocking" JSON attribute: 1 = Blocked, 0 = Exception.

Syslog Tag Event Panel Type Description
trusted Trusted App Allowed App was trusted by a handprint or CERT policy
hand Unsigned App Allowed App was allowed in unsigned learn mode
cert Signed App Allowed App was allowed in CERT learn mode
allowed Known Allowed Allowed App known to an advisor was allowed to run
mme Monitor Mode Exception Exception Unknown app was allowed in monitor mode
untrusted Known Blocked "blocking" flag App known to an advisor was blocked
soft Soft Block "blocking" flag Unknown app was soft blocked and stopped reporting
blocked Blocked Unknown Blocked Unknown app was blocked
ignored Blocked Unknown, Unreported Blocked Unknown app was blocked and stopped reporting
policy Block Policy Blocked App was blocked by an unknown policy
denied Deny Policy Blocked App was blocked by a specific deny policy
distrusted Distrust App Blocked App was blocked by a specific distrusted app policy
malware Marked as Malware Blocked App was blocked by a specific malware policy

Example Golang Structs

Common Fields

  • GID is the subgroup ID for the subgroup that generated the syslog.
  • Sub is the subgroup's name/nickname.
  • TID is the subgroup ID (SGID) of the group at the top of the inheritance tree.
  • TreeName is the name of the top of the tree.
  • OID is the Account ID for the account that this tree belongs to.
  • OwnerName is the account owner's name/nickname.
  • ORGID is the organization ID.
  • OrgName is the organization's name.

Live Host Count event

type LiveHostCount struct {
    MetricName string `json:"metricName"`
    Count      int    `json:"count"`
}

Agent Version Change Events

type VersionData struct {
    MetricName string `json:"metricName"`
    GID        int    `json:"gid"`
    Sub        string `json:"sub"`
    TID        int    `json:"tid"`
    TreeName   string `json:"tname"`
    OID        int    `json:"oid"`
    OwnerName  string `json:"oname"`
    ORGID      int    `json:"orgid"`
    OrgName    string `json:"org"`
    HID        int    `json:"hid"`
    Host       string `json:"host"`
    Nick       string `json:"nick"`
    Ver        string `json:"ver"`
}

Block Mode Change Events

type BlockModeData struct {
    MetricName string `json:"metricName"`
    GID        int    `json:"gid"`
    Sub        string `json:"sub"`
    TID        int    `json:"tid"`
    TreeName   string `json:"tname"`
    OID        int    `json:"oid"`
    OwnerName  string `json:"oname"`
    ORGID      int    `json:"orgid"`
    OrgName    string `json:"org"`
    HID        int    `json:"hid"`
    Host       string `json:"host"`
    Nick       string `json:"nick"`
    Mode       int    `json:"mode"`
}

App Events

type EventData struct {
    MetricName string `json:"metricName"`
    GID        int    `json:"gid"`
    Sub        string `json:"sub"`
    TID        int    `json:"tid"`
    TreeName   string `json:"tname"`
    OID        int    `json:"oid"`
    OwnerName  string `json:"oname"`
    ORGID      int    `json:"orgid"`
    OrgName    string `json:"org"`
    HID        int    `json:"hid"`
    Host       string `json:"host"`
    Nick       string `json:"nick"`
    User       string `json:"user"`
    Path       string `json:"path"`
    File       string `json:"file"`
    Blocking   int    `json:"blocking"`
}

For example, a "Trusted App" event would generate a syslog with a "wcsec" identifier and a "trusted" tag.

May 15 13:37:09 wcs wcsec[96038]: trusted {"gid":"1000001","sub":"domain-1000001\\user-1000001","hid":"2","host":"hostname-1000001","nick":"","metricName":"trusted","user":"domain-1000001\\user-1000001","path":"C:\\Windows\\SoftwareDistribution\\Download\\ab4d06812d580d4fc85d3fddd97a74bb\\Metadata","file":"UAOneSettings.dll","blocking":1}

The syslog consists of the following fields:

  • Date (Month DD HH:MM:SS)
  • wcs
  • [process_id]:
  • syslog_tag
  • Event JSON string

Here is a simple Golang example to parse these syslog records:

package main

import (
    "encoding/json"
    "fmt"
    "regexp"
    "strings"
    "time"
)

// Define functions for different syslog tags
func handleTrusted(syslogTag string, event map[string]interface{}) {
    fmt.Printf("Handling %s event: %s\n", syslogTag, event)
}

func handleBlocked(syslogTag string, event map[string]interface{}) {
    fmt.Printf("Handling %s event: %s\n", syslogTag, event)
}

// Dispatcher function to call appropriate handler based on syslog_tag
func dispatchSyslogTag(syslogTag string, event map[string]interface{}) {
    switch syslogTag {
    case "trusted":
        handleTrusted(syslogTag, event)
    case "blocked":
        handleBlocked(syslogTag, event)
    default:
        fmt.Println("Unknown syslog tag:", syslogTag)
    }
}

// Function to parse the syslog record and call the appropriate handler
func parseAndHandleSyslogRecord(record string) error {
    // Define regex pattern to match the syslog record
    pattern := `^([A-Za-z]{3} \d{2} \d{2}:\d{2}:\d{2}) (\w+) \[(\d+)\]: (\w+) (.+)$`
    re := regexp.MustCompile(pattern)
    matches := re.FindStringSubmatch(record)

    if len(matches) != 6 {
        return fmt.Errorf("record does not match expected format")
    }

    // Extract fields from the syslog record
    dateStr := matches[1]
    serverName := matches[2]
    processID := matches[3]
    syslogTag := matches[4]
    eventStr := matches[5]

    // Parse the date string
    date, err := time.Parse("Jan 02 15:04:05", dateStr)
    if err != nil {
        return fmt.Errorf("failed to parse date: %v", err)
    }

    // Parse the event JSON string
    var event map[string]interface{}
    err = json.Unmarshal([]byte(eventStr), &event)
    if err != nil {
        return fmt.Errorf("failed to parse event JSON: %v", err)
    }

    // Print the parsed information
    fmt.Println("Date:", date)
    fmt.Println("Server:", serverName)
    fmt.Println("Process ID:", processID)
    fmt.Println("Syslog Tag:", syslogTag)
    fmt.Println("Event:", event)

    // Dispatch to the appropriate handler based on the syslog tag
    dispatchSyslogTag(syslogTag, event)

    return nil
}

func main() {
    // Example syslog record
    record := "May 15 13:37:09 wcs wcsec[96038]: trusted {\"gid\":\"1000001\",\"sub