diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 6183bdb2d8d7..42c86a507bba 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -70,6 +70,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Improve ECS field mappings in Sysmon module. `file.name`, `file.directory`, and `file.extension` are now populated. {issue}18364[18364] - Improve ECS field mappings in Sysmon module. `rule.name` is populated for all events when present. {issue}18364[18364] - Remove top level `hash` property from sysmon events {pull}20653[20653] +- Move module processing from local Javascript processor to ingest node {issue}29184[29184] {pull}29435[29435] *Functionbeat* diff --git a/filebeat/fileset/compatibility.go b/filebeat/fileset/compatibility.go index 8a38e6158ccc..63631e86b88b 100644 --- a/filebeat/fileset/compatibility.go +++ b/filebeat/fileset/compatibility.go @@ -211,7 +211,7 @@ func (p *Processor) String() string { // adaptPipelineForCompatibility iterates over all processors in the pipeline // and adapts them for version of Elasticsearch used. Adapt can mean modifying // processor options or removing the processor. -func adaptPipelineForCompatibility(esVersion common.Version, pipelineID string, content map[string]interface{}, log *logp.Logger) (err error) { +func AdaptPipelineForCompatibility(esVersion common.Version, pipelineID string, content map[string]interface{}, log *logp.Logger) (err error) { log = log.With("pipeline_id", pipelineID) // Adapt the main processors in the pipeline. if err = adaptProcessorsForCompatibility(esVersion, content, "processors", false, log); err != nil { diff --git a/filebeat/fileset/compatibility_test.go b/filebeat/fileset/compatibility_test.go index 82e584b046fe..79b10eb263df 100644 --- a/filebeat/fileset/compatibility_test.go +++ b/filebeat/fileset/compatibility_test.go @@ -128,7 +128,7 @@ func TestAdaptPipelineForCompatibility(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { @@ -305,7 +305,7 @@ func TestReplaceSetIgnoreEmptyValue(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { @@ -507,7 +507,7 @@ func TestReplaceAppendAllowDuplicates(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { @@ -632,7 +632,7 @@ func TestRemoveURIPartsProcessor(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { @@ -767,7 +767,7 @@ func TestRemoveNetworkDirectionProcessor(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { @@ -950,7 +950,7 @@ func TestReplaceConvertIPWithGrok(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { @@ -1070,7 +1070,7 @@ func TestRemoveRegisteredDomainProcessor(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { @@ -1331,7 +1331,7 @@ func TestReplaceAlternativeFlowProcessors(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { @@ -1446,7 +1446,7 @@ func TestRemoveDescription(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - err := adaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) + err := AdaptPipelineForCompatibility(*test.esVersion, "foo-pipeline", test.content, logp.NewLogger(logName)) if test.isErrExpected { assert.Error(t, err) } else { diff --git a/filebeat/fileset/fileset.go b/filebeat/fileset/fileset.go index 09a2738bb172..dae801738f90 100644 --- a/filebeat/fileset/fileset.go +++ b/filebeat/fileset/fileset.go @@ -237,13 +237,13 @@ func (fs *Fileset) turnOffElasticsearchVars(vars map[string]interface{}, esVersi func resolveVariable(vars map[string]interface{}, value interface{}) (interface{}, error) { switch v := value.(type) { case string: - return applyTemplate(vars, v, false) + return ApplyTemplate(vars, v, false) case []interface{}: transformed := []interface{}{} for _, val := range v { s, ok := val.(string) if ok { - transf, err := applyTemplate(vars, s, false) + transf, err := ApplyTemplate(vars, s, false) if err != nil { return nil, fmt.Errorf("array: %v", err) } @@ -257,10 +257,10 @@ func resolveVariable(vars map[string]interface{}, value interface{}) (interface{ return value, nil } -// applyTemplate applies a Golang text/template. If specialDelims is set to true, +// ApplyTemplate applies a Golang text/template. If specialDelims is set to true, // the delimiters are set to `{<` and `>}` instead of `{{` and `}}`. These are easier to use // in pipeline definitions. -func applyTemplate(vars map[string]interface{}, templateString string, specialDelims bool) (string, error) { +func ApplyTemplate(vars map[string]interface{}, templateString string, specialDelims bool) (string, error) { tpl := template.New("text").Option("missingkey=error") if specialDelims { tpl = tpl.Delims("{<", ">}") @@ -307,7 +307,7 @@ func getTemplateFunctions(vars map[string]interface{}) (template.FuncMap, error) return buf.String(), err }, "IngestPipeline": func(shortID string) string { - return formatPipelineID( + return FormatPipelineID( builtinVars["prefix"].(string), builtinVars["module"].(string), builtinVars["fileset"].(string), @@ -343,7 +343,7 @@ func (fs *Fileset) getBuiltinVars(info beat.Info) (map[string]interface{}, error } func (fs *Fileset) getInputConfig() (*common.Config, error) { - path, err := applyTemplate(fs.vars, fs.manifest.Input, false) + path, err := ApplyTemplate(fs.vars, fs.manifest.Input, false) if err != nil { return nil, fmt.Errorf("Error expanding vars on the input path: %v", err) } @@ -352,7 +352,7 @@ func (fs *Fileset) getInputConfig() (*common.Config, error) { return nil, fmt.Errorf("Error reading input file %s: %v", path, err) } - yaml, err := applyTemplate(fs.vars, string(contents), false) + yaml, err := ApplyTemplate(fs.vars, string(contents), false) if err != nil { return nil, fmt.Errorf("Error interpreting the template of the input: %v", err) } @@ -409,12 +409,12 @@ func (fs *Fileset) getInputConfig() (*common.Config, error) { func (fs *Fileset) getPipelineIDs(info beat.Info) ([]string, error) { var pipelineIDs []string for _, ingestPipeline := range fs.manifest.IngestPipeline { - path, err := applyTemplate(fs.vars, ingestPipeline, false) + path, err := ApplyTemplate(fs.vars, ingestPipeline, false) if err != nil { return nil, fmt.Errorf("Error expanding vars on the ingest pipeline path: %v", err) } - pipelineIDs = append(pipelineIDs, formatPipelineID(info.IndexPrefix, fs.mcfg.Module, fs.name, path, info.Version)) + pipelineIDs = append(pipelineIDs, FormatPipelineID(info.IndexPrefix, fs.mcfg.Module, fs.name, path, info.Version)) } return pipelineIDs, nil @@ -428,7 +428,7 @@ func (fs *Fileset) GetPipelines(esVersion common.Version) (pipelines []pipeline, } for idx, ingestPipeline := range fs.manifest.IngestPipeline { - path, err := applyTemplate(fs.vars, ingestPipeline, false) + path, err := ApplyTemplate(fs.vars, ingestPipeline, false) if err != nil { return nil, fmt.Errorf("Error expanding vars on the ingest pipeline path: %v", err) } @@ -438,7 +438,7 @@ func (fs *Fileset) GetPipelines(esVersion common.Version) (pipelines []pipeline, return nil, fmt.Errorf("Error reading pipeline file %s: %v", path, err) } - encodedString, err := applyTemplate(vars, string(strContents), true) + encodedString, err := ApplyTemplate(vars, string(strContents), true) if err != nil { return nil, fmt.Errorf("Error interpreting the template of the ingest pipeline: %v", err) } @@ -453,7 +453,7 @@ func (fs *Fileset) GetPipelines(esVersion common.Version) (pipelines []pipeline, if err = yaml.Unmarshal([]byte(encodedString), &content); err != nil { return nil, fmt.Errorf("Error YAML decoding the pipeline file: %s: %v", path, err) } - newContent, err := fixYAMLMaps(content) + newContent, err := FixYAMLMaps(content) if err != nil { return nil, fmt.Errorf("Failed to sanitize the YAML pipeline file: %s: %v", path, err) } @@ -474,11 +474,11 @@ func (fs *Fileset) GetPipelines(esVersion common.Version) (pipelines []pipeline, return pipelines, nil } -// This function recursively converts maps with interface{} keys, as returned by +// FixYAMLMaps recursively converts maps with interface{} keys, as returned by // yaml.Unmarshal, to maps of string keys, as expected by the json encoder // that will be used when delivering the pipeline to Elasticsearch. // Will return an error when something other than a string is used as a key. -func fixYAMLMaps(elem interface{}) (_ interface{}, err error) { +func FixYAMLMaps(elem interface{}) (_ interface{}, err error) { switch v := elem.(type) { case map[interface{}]interface{}: result := make(map[string]interface{}, len(v)) @@ -487,20 +487,20 @@ func fixYAMLMaps(elem interface{}) (_ interface{}, err error) { if !ok { return nil, fmt.Errorf("key '%v' is not string but %T", key, key) } - if result[keyS], err = fixYAMLMaps(value); err != nil { + if result[keyS], err = FixYAMLMaps(value); err != nil { return nil, err } } return result, nil case map[string]interface{}: for key, value := range v { - if v[key], err = fixYAMLMaps(value); err != nil { + if v[key], err = FixYAMLMaps(value); err != nil { return nil, err } } case []interface{}: for idx, value := range v { - if v[idx], err = fixYAMLMaps(value); err != nil { + if v[idx], err = FixYAMLMaps(value); err != nil { return nil, err } } @@ -508,8 +508,11 @@ func fixYAMLMaps(elem interface{}) (_ interface{}, err error) { return elem, nil } -// formatPipelineID generates the ID to be used for the pipeline ID in Elasticsearch -func formatPipelineID(prefix, module, fileset, path, version string) string { +// FormatPipelineID generates the ID to be used for the pipeline ID in Elasticsearch +func FormatPipelineID(prefix, module, fileset, path, version string) string { + if module == "" && fileset == "" { + return fmt.Sprintf("%s-%s-%s", prefix, version, removeExt(filepath.Base(path))) + } return fmt.Sprintf("%s-%s-%s-%s-%s", prefix, version, module, fileset, removeExt(filepath.Base(path))) } diff --git a/filebeat/fileset/modules_integration_test.go b/filebeat/fileset/modules_integration_test.go index 6b9e86cac84b..f17be7c8d73f 100644 --- a/filebeat/fileset/modules_integration_test.go +++ b/filebeat/fileset/modules_integration_test.go @@ -62,7 +62,7 @@ func TestLoadPipeline(t *testing.T) { } log := logp.NewLogger(logName) - err := loadPipeline(client, "my-pipeline-id", content, false, log) + err := LoadPipeline(client, "my-pipeline-id", content, false, log) require.NoError(t, err) status, _, err := client.Request("GET", "/_ingest/pipeline/my-pipeline-id", "", nil, nil) @@ -71,12 +71,12 @@ func TestLoadPipeline(t *testing.T) { // loading again shouldn't actually update the pipeline content["description"] = "describe pipeline 2" - err = loadPipeline(client, "my-pipeline-id", content, false, log) + err = LoadPipeline(client, "my-pipeline-id", content, false, log) require.NoError(t, err) checkUploadedPipeline(t, client, "describe pipeline") // loading again updates the pipeline - err = loadPipeline(client, "my-pipeline-id", content, true, log) + err = LoadPipeline(client, "my-pipeline-id", content, true, log) require.NoError(t, err) checkUploadedPipeline(t, client, "describe pipeline 2") } diff --git a/filebeat/fileset/pipelines.go b/filebeat/fileset/pipelines.go index a3ce0b3de423..c93825ad09e4 100644 --- a/filebeat/fileset/pipelines.go +++ b/filebeat/fileset/pipelines.go @@ -86,7 +86,7 @@ func (reg *ModuleRegistry) LoadPipelines(esClient PipelineLoader, overwrite bool var pipelineIDsLoaded []string for _, pipeline := range pipelines { - err = loadPipeline(esClient, pipeline.id, pipeline.contents, overwrite, reg.log.With("pipeline", pipeline.id)) + err = LoadPipeline(esClient, pipeline.id, pipeline.contents, overwrite, reg.log.With("pipeline", pipeline.id)) if err != nil { err = fmt.Errorf("error loading pipeline for fileset %s/%s: %v", module, name, err) break @@ -100,7 +100,7 @@ func (reg *ModuleRegistry) LoadPipelines(esClient PipelineLoader, overwrite bool // error, validate all pipelines before loading any of them. This requires https://github.com/elastic/elasticsearch/issues/35495. errs := multierror.Errors{err} for _, pipelineID := range pipelineIDsLoaded { - err = deletePipeline(esClient, pipelineID) + err = DeletePipeline(esClient, pipelineID) if err != nil { errs = append(errs, err) } @@ -112,7 +112,7 @@ func (reg *ModuleRegistry) LoadPipelines(esClient PipelineLoader, overwrite bool return nil } -func loadPipeline(esClient PipelineLoader, pipelineID string, content map[string]interface{}, overwrite bool, log *logp.Logger) error { +func LoadPipeline(esClient PipelineLoader, pipelineID string, content map[string]interface{}, overwrite bool, log *logp.Logger) error { path := makeIngestPipelinePath(pipelineID) if !overwrite { status, _, _ := esClient.Request("GET", path, "", nil, nil) @@ -122,7 +122,7 @@ func loadPipeline(esClient PipelineLoader, pipelineID string, content map[string } } - if err := adaptPipelineForCompatibility(esClient.GetVersion(), pipelineID, content, log); err != nil { + if err := AdaptPipelineForCompatibility(esClient.GetVersion(), pipelineID, content, log); err != nil { return fmt.Errorf("failed to adapt pipeline with backwards compatibility changes: %w", err) } @@ -134,7 +134,7 @@ func loadPipeline(esClient PipelineLoader, pipelineID string, content map[string return nil } -func deletePipeline(esClient PipelineLoader, pipelineID string) error { +func DeletePipeline(esClient PipelineLoader, pipelineID string) error { path := makeIngestPipelinePath(pipelineID) _, _, err := esClient.Request("DELETE", path, "", nil, nil) return err diff --git a/libbeat/docs/command-reference.asciidoc b/libbeat/docs/command-reference.asciidoc index d761c7f4b169..eddee911d7fa 100644 --- a/libbeat/docs/command-reference.asciidoc +++ b/libbeat/docs/command-reference.asciidoc @@ -19,6 +19,7 @@ :apikey-command-short-desc: Manage API Keys for communication between APM agents and server. +ifndef::export_pipeline[] ifndef::serverless[] ifndef::no_dashboards[] :export-command-short-desc: Exports the configuration, index template, ILM policy, or a dashboard to stdout @@ -32,6 +33,11 @@ endif::serverless[] ifdef::serverless[] :export-command-short-desc: Exports the configuration, index template, or {cloudformation-ref} template to stdout endif::serverless[] +endif::export_pipeline[] + +ifdef::export_pipeline[] +:export-command-short-desc: Exports the configuration, index template, pipeline, or ILM policy to stdout +endif::export_pipeline[] :help-command-short-desc: Shows help for any command :keystore-command-short-desc: Manages the <> @@ -262,6 +268,7 @@ endif::[] [[export-command]] ==== `export` command +ifndef::export_pipeline[] ifndef::serverless[] ifndef::no_dashboards[] {export-command-short-desc}. You can use this @@ -281,6 +288,14 @@ ifdef::serverless[] command to quickly view your configuration, see the contents of the index template and the ILM policy, or export an CloudFormation template. endif::serverless[] +endif::export_pipeline[] + +ifdef::export_pipeline[] +{export-command-short-desc}. You can use this +command to quickly view your configuration, see the contents of the index +template and the ILM policy, export a dashboard from {kib}, or export ingest +pipelines. +endif::export_pipeline[] *SYNOPSIS* @@ -336,6 +351,14 @@ ifdef::serverless[] Exports an {cloudformation-ref} template to stdout. endif::serverless[] +ifdef::export_pipeline[] +[[pipeline-subcommand]] +*`pipeline`*:: +Exports the ingest piplines. You must specify the `--es.version` to which +the pipelines should be exported. You can optionally specify `--dir` to control +where the pipelines are written. +endif::export_pipeline[] + *FLAGS* *`--es.version VERSION`*:: diff --git a/winlogbeat/_meta/config/header.yml.tmpl b/winlogbeat/_meta/config/header.yml.tmpl index 7d966b365242..b12d31c47d93 100644 --- a/winlogbeat/_meta/config/header.yml.tmpl +++ b/winlogbeat/_meta/config/header.yml.tmpl @@ -21,6 +21,11 @@ # batch of events has been published successfully. The default value is 5s. #winlogbeat.registry_flush: 5s +# By default Ingest pipelines are not updated if a pipeline with the same ID +# already exists. If this option is enabled Winlogbeat overwrites pipelines +# every time a new Elasticsearch connection is established. +#winlogbeat.overwrite_pipelines: false + {{end -}} # event_logs specifies a list of event logs to monitor as well as any # accompanying options. The YAML data type of event_logs is a list of diff --git a/winlogbeat/beater/winlogbeat.go b/winlogbeat/beater/winlogbeat.go index 568bb911539d..ec7ebf90ef6f 100644 --- a/winlogbeat/beater/winlogbeat.go +++ b/winlogbeat/beater/winlogbeat.go @@ -29,14 +29,21 @@ import ( "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/esleg/eslegclient" "github.com/elastic/beats/v7/libbeat/logp" + "github.com/elastic/beats/v7/libbeat/outputs/elasticsearch" "github.com/elastic/beats/v7/libbeat/paths" + "github.com/elastic/beats/v7/winlogbeat/module" "github.com/elastic/beats/v7/winlogbeat/checkpoint" "github.com/elastic/beats/v7/winlogbeat/config" "github.com/elastic/beats/v7/winlogbeat/eventlog" ) +const pipelinesWarning = "Winlogbeat is unable to load the ingest pipelines" + + " because the Elasticsearch output is not configured/enabled. If you have" + + " already loaded the ingest pipelines, you can ignore this warning." + // Time the application was started. var startTime = time.Now().UTC() @@ -100,7 +107,14 @@ func (eb *Winlogbeat) init(b *beat.Beat) error { eb.eventLogs = append(eb.eventLogs, logger) } - + b.OverwritePipelinesCallback = func(esConfig *common.Config) error { + overwritePipelines := config.OverwritePipelines + esClient, err := eslegclient.NewConnectedClient(esConfig, "Winlogbeat") + if err != nil { + return err + } + return module.UploadPipelines(b.Info, esClient, overwritePipelines) + } return nil } @@ -125,6 +139,18 @@ func (eb *Winlogbeat) Run(b *beat.Beat) error { return err } + if b.Config.Output.Name() == "elasticsearch" { + callback := func(esClient *eslegclient.Connection) error { + return module.UploadPipelines(b.Info, esClient, eb.config.OverwritePipelines) + } + _, err := elasticsearch.RegisterConnectCallback(callback) + if err != nil { + return err + } + } else { + eb.log.Warn(pipelinesWarning) + } + acker := newEventACKer(eb.checkpoint) persistedState := eb.checkpoint.States() diff --git a/winlogbeat/config/config.go b/winlogbeat/config/config.go index 1b8eab40c0a1..ed8f2195d026 100644 --- a/winlogbeat/config/config.go +++ b/winlogbeat/config/config.go @@ -41,10 +41,11 @@ var ( // WinlogbeatConfig contains all of Winlogbeat configuration data. type WinlogbeatConfig struct { - EventLogs []*common.Config `config:"event_logs"` - RegistryFile string `config:"registry_file"` - RegistryFlush time.Duration `config:"registry_flush"` - ShutdownTimeout time.Duration `config:"shutdown_timeout"` + EventLogs []*common.Config `config:"event_logs"` + RegistryFile string `config:"registry_file"` + RegistryFlush time.Duration `config:"registry_flush"` + ShutdownTimeout time.Duration `config:"shutdown_timeout"` + OverwritePipelines bool `config:"overwrite_pipelines"` } // Validate validates the WinlogbeatConfig data and returns an error describing diff --git a/winlogbeat/docs/index.asciidoc b/winlogbeat/docs/index.asciidoc index d953f0d641c2..97c1023d4c26 100644 --- a/winlogbeat/docs/index.asciidoc +++ b/winlogbeat/docs/index.asciidoc @@ -21,6 +21,7 @@ include::{asciidoc-dir}/../../shared/attributes.asciidoc[] :no_decode_cef_processor: :no_decode_csv_fields_processor: :include_translate_sid_processor: +:export_pipeline: include::{libbeat-dir}/shared-beats-attributes.asciidoc[] diff --git a/winlogbeat/docs/winlogbeat-options.asciidoc b/winlogbeat/docs/winlogbeat-options.asciidoc index 23e63803089b..e703406061da 100644 --- a/winlogbeat/docs/winlogbeat-options.asciidoc +++ b/winlogbeat/docs/winlogbeat-options.asciidoc @@ -514,3 +514,12 @@ There are a few notable differences in the events: `winlog.event_data`. * Setting `include_xml: true` has no effect. + +[float] +==== `overwrite_pipelines` + +By default Ingest pipelines are not updated if a pipeline with the same ID +already exists. If this option is enabled Winlogbeat overwrites pipelines +every time a new Elasticsearch connection is established. + +The default value is `false`. diff --git a/winlogbeat/module/pipeline.go b/winlogbeat/module/pipeline.go new file mode 100644 index 000000000000..c134bd9068b4 --- /dev/null +++ b/winlogbeat/module/pipeline.go @@ -0,0 +1,212 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package module + +import ( + "embed" + "encoding/json" + "errors" + "fmt" + "os" + "path" + "path/filepath" + "strings" + + "github.com/joeshaw/multierror" + "gopkg.in/yaml.v2" + + "github.com/elastic/beats/v7/filebeat/fileset" + "github.com/elastic/beats/v7/libbeat/beat" + "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/esleg/eslegclient" + "github.com/elastic/beats/v7/libbeat/logp" +) + +// PipelinesFS is used from the x-pack/winlogbeat code to inject modules. The +// OSS version does not have modules. +var PipelinesFS *embed.FS + +var errNoFS = errors.New("no embedded file system") + +const logName = "pipeline" + +type pipeline struct { + id string + contents map[string]interface{} +} + +// UploadPipelines reads all pipelines embedded in the Winlogbeat executable +// and adapts the pipeline for a given ES version, converts to JSON if +// necessary and creates or updates ingest pipeline in ES. +func UploadPipelines(info beat.Info, esClient *eslegclient.Connection, overwritePipelines bool) error { + pipelines, err := readAll(info) + if err != nil { + return err + } + return load(esClient, pipelines, overwritePipelines) +} + +// ExportPipelines reads all pipelines embedded in the Winlogbeat executable +// and adapts the pipelines for a given ES version and writes the +// converted pipelines to the given directory in JSON format. +func ExportPipelines(info beat.Info, version common.Version, directory string) error { + log := logp.NewLogger(logName) + pipelines, err := readAll(info) + if err != nil { + return err + } + + for _, pipeline := range pipelines { + if err := fileset.AdaptPipelineForCompatibility(version, pipeline.id, pipeline.contents, log); err != nil { + return fmt.Errorf("failed to adapt pipeline with backwards compatibility changes for version %s: %w", version.String(), err) + } + f, err := os.Create(filepath.Join(directory, pipeline.id+".json")) + if err != nil { + return fmt.Errorf("unable to create file to export pipeline to: %w", err) + } + enc := json.NewEncoder(f) + enc.SetEscapeHTML(false) + err = enc.Encode(pipeline.contents) + if err != nil { + return fmt.Errorf("unable to JSON encode pipeline %s: %w", f.Name(), err) + } + } + return nil +} + +// readAll reads pipelines from the the embedded filesystem and +// returns a slice of pipelines suitable for sending to Elasticsearch +// with load. +func readAll(info beat.Info) (pipelines []pipeline, err error) { + p, err := readDir(".", info) + if err == errNoFS { + return nil, nil + } + return p, err +} + +func readDir(dir string, info beat.Info) (pipelines []pipeline, err error) { + if PipelinesFS == nil { + return nil, errNoFS + } + dirEntries, err := PipelinesFS.ReadDir(dir) + if err != nil { + return nil, err + } + for _, de := range dirEntries { + if de.IsDir() { + subPipelines, err := readDir(path.Join(dir, de.Name()), info) + if err != nil { + return nil, err + } + pipelines = append(pipelines, subPipelines...) + continue + } + p, err := readFile(path.Join(dir, de.Name()), info) + if err == errNoFS { + continue + } + if err != nil { + return nil, err + } + pipelines = append(pipelines, p) + } + return pipelines, nil +} + +func readFile(filename string, info beat.Info) (p pipeline, err error) { + if PipelinesFS == nil { + return pipeline{}, errNoFS + } + contents, err := PipelinesFS.ReadFile(filename) + if err != nil { + return pipeline{}, err + } + updatedContent, err := applyTemplates(info.IndexPrefix, info.Version, filename, contents) + if err != nil { + return pipeline{}, err + } + p = pipeline{ + id: fileset.FormatPipelineID(info.IndexPrefix, "", "", filename, info.Version), + contents: updatedContent, + } + return p, nil +} + +// load uses esClient to load pipelines to Elasticsearch cluster. +// Will only overwrite existing pipelines if overwritePipelines is +// true. An error in loading one of the pipelines will cause the +// successfully loaded ones to be deleted. +func load(esClient *eslegclient.Connection, pipelines []pipeline, overwritePipelines bool) (err error) { + var pipelineIDsLoaded []string + log := logp.NewLogger(logName) + + for _, pipeline := range pipelines { + err = fileset.LoadPipeline(esClient, pipeline.id, pipeline.contents, overwritePipelines, log) + if err != nil { + err = fmt.Errorf("error loading pipeline %s: %w", pipeline.id, err) + break + } + pipelineIDsLoaded = append(pipelineIDsLoaded, pipeline.id) + } + + if err != nil { + errs := multierror.Errors{err} + for _, pipelineID := range pipelineIDsLoaded { + err = fileset.DeletePipeline(esClient, pipelineID) + if err != nil { + errs = append(errs, err) + } + } + return errs.Err() + } + return nil +} + +func applyTemplates(prefix string, version string, filename string, original []byte) (converted map[string]interface{}, err error) { + vars := map[string]interface{}{ + "builtin": map[string]interface{}{ + "prefix": prefix, + "module": "", + "fileset": "", + "beatVersion": version, + }, + } + + encodedString, err := fileset.ApplyTemplate(vars, string(original), true) + + var content map[string]interface{} + switch extension := strings.ToLower(filepath.Ext(filename)); extension { + case ".json": + if err = json.Unmarshal([]byte(encodedString), &content); err != nil { + return nil, fmt.Errorf("error JSON decoding the pipeline file: %s: %w", filename, err) + } + case ".yaml", ".yml": + if err = yaml.Unmarshal([]byte(encodedString), &content); err != nil { + return nil, fmt.Errorf("error YAML decoding the pipeline file: %s: %w", filename, err) + } + newContent, err := fileset.FixYAMLMaps(content) + if err != nil { + return nil, fmt.Errorf("failed to sanitize the YAML pipeline file: %s: %w", filename, err) + } + content = newContent.(map[string]interface{}) + default: + return nil, fmt.Errorf("unsupported extension '%s' for pipeline file: %s", extension, filename) + } + return content, nil +} diff --git a/winlogbeat/winlogbeat.reference.yml b/winlogbeat/winlogbeat.reference.yml index 51ca51897f8f..17f40c8a5f97 100644 --- a/winlogbeat/winlogbeat.reference.yml +++ b/winlogbeat/winlogbeat.reference.yml @@ -20,6 +20,11 @@ # batch of events has been published successfully. The default value is 5s. #winlogbeat.registry_flush: 5s +# By default Ingest pipelines are not updated if a pipeline with the same ID +# already exists. If this option is enabled Winlogbeat overwrites pipelines +# every time a new Elasticsearch connection is established. +#winlogbeat.overwrite_pipelines: false + # event_logs specifies a list of event logs to monitor as well as any # accompanying options. The YAML data type of event_logs is a list of # dictionaries. diff --git a/x-pack/winlogbeat/_meta/config/output-elasticsearch.yml.tmpl b/x-pack/winlogbeat/_meta/config/output-elasticsearch.yml.tmpl new file mode 100644 index 000000000000..ed83c8f61039 --- /dev/null +++ b/x-pack/winlogbeat/_meta/config/output-elasticsearch.yml.tmpl @@ -0,0 +1,15 @@ +{{subheader "Elasticsearch Output"}} +output.elasticsearch: + # Array of hosts to connect to. + hosts: ["localhost:9200"] + + # Protocol - either `http` (default) or `https`. + #protocol: "https" + + # Authentication credentials - either API key or username/password. + #api_key: "id:api_key" + #username: "elastic" + #password: "changeme" + + # Pipeline to route events to security, sysmon, or powershell pipelines. + pipeline: "winlogbeat-%{[agent.version]}-routing" diff --git a/x-pack/winlogbeat/_meta/config/winlogbeat.event_logs.yml.tmpl b/x-pack/winlogbeat/_meta/config/winlogbeat.event_logs.yml.tmpl index bf3d2423a788..5ee2b373dffe 100644 --- a/x-pack/winlogbeat/_meta/config/winlogbeat.event_logs.yml.tmpl +++ b/x-pack/winlogbeat/_meta/config/winlogbeat.event_logs.yml.tmpl @@ -5,55 +5,14 @@ winlogbeat.event_logs: - name: System - name: Security - processors: - - script: - lang: javascript - id: security - file: ${path.home}/module/security/config/winlogbeat-security.js - name: Microsoft-Windows-Sysmon/Operational - processors: - - script: - lang: javascript - id: sysmon - file: ${path.home}/module/sysmon/config/winlogbeat-sysmon.js - name: Windows PowerShell event_id: 400, 403, 600, 800 - processors: - - script: - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - name: Microsoft-Windows-PowerShell/Operational event_id: 4103, 4104, 4105, 4106 - processors: - - script: - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - name: ForwardedEvents tags: [forwarded] - processors: - - script: - when.equals.winlog.channel: Security - lang: javascript - id: security - file: ${path.home}/module/security/config/winlogbeat-security.js - - script: - when.equals.winlog.channel: Microsoft-Windows-Sysmon/Operational - lang: javascript - id: sysmon - file: ${path.home}/module/sysmon/config/winlogbeat-sysmon.js - - script: - when.equals.winlog.channel: Windows PowerShell - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - - script: - when.equals.winlog.channel: Microsoft-Windows-PowerShell/Operational - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js diff --git a/x-pack/winlogbeat/cmd/export.go b/x-pack/winlogbeat/cmd/export.go new file mode 100644 index 000000000000..ce6ecc5f9bf1 --- /dev/null +++ b/x-pack/winlogbeat/cmd/export.go @@ -0,0 +1,60 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package cmd + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" + + "github.com/elastic/beats/v7/libbeat/cmd/instance" + "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/winlogbeat/module" +) + +// GenTemplateConfigCmd is the command used to export the elasticsearch template. +func GenExportPipelineCmd(settings instance.Settings) *cobra.Command { + genExportPipelineCmd := &cobra.Command{ + Use: "pipelines", + Short: "Export pipelines", + Run: func(cmd *cobra.Command, args []string) { + version, _ := cmd.Flags().GetString("es.version") + dir, _ := cmd.Flags().GetString("dir") + + if version == "" { + fatalf("--es.version is required") + } + + ver, err := common.NewVersion(version) + if err != nil { + fatalf("Unable to parse ES version from %s: %+v", version, err) + } + + b, err := instance.NewInitializedBeat(settings) + if err != nil { + fatalf("Failed to initialize 'pipeline' command: %+v", err) + } + + err = module.ExportPipelines(b.Info, *ver, dir) + if err != nil { + fatalf("Failed to export pipelines: %+v", err) + } + + fmt.Fprintf(os.Stdout, "Exported pipelines") + }, + } + + genExportPipelineCmd.Flags().String("es.version", settings.Version, "Elasticsearch version (required)") + genExportPipelineCmd.Flags().String("dir", "", "Specify directory for exporting pipelines. Default is current directory.") + + return genExportPipelineCmd +} + +func fatalf(msg string, vs ...interface{}) { + fmt.Fprintf(os.Stderr, msg, vs...) + fmt.Fprintln(os.Stderr) + os.Exit(1) +} diff --git a/x-pack/winlogbeat/cmd/root.go b/x-pack/winlogbeat/cmd/root.go index ae56c4de83fe..9ac4f71a8910 100644 --- a/x-pack/winlogbeat/cmd/root.go +++ b/x-pack/winlogbeat/cmd/root.go @@ -7,6 +7,7 @@ package cmd import ( "github.com/elastic/beats/v7/libbeat/cmd" winlogbeatCmd "github.com/elastic/beats/v7/winlogbeat/cmd" + "github.com/elastic/beats/v7/x-pack/winlogbeat/module" // Register fields. _ "github.com/elastic/beats/v7/x-pack/libbeat/include" @@ -23,4 +24,6 @@ func init() { settings := winlogbeatCmd.WinlogbeatSettings() settings.ElasticLicensed = true RootCmd = winlogbeatCmd.Initialize(settings) + RootCmd.ExportCmd.AddCommand(GenExportPipelineCmd(settings)) + module.Init() } diff --git a/x-pack/winlogbeat/module/pipeline.go b/x-pack/winlogbeat/module/pipeline.go new file mode 100644 index 000000000000..baa335e4b2a1 --- /dev/null +++ b/x-pack/winlogbeat/module/pipeline.go @@ -0,0 +1,19 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package module + +import ( + "embed" + + "github.com/elastic/beats/v7/winlogbeat/module" +) + +// pipelineFS holds the yml representation of the ingest node pipelines +//go:embed */ingest/*.yml +var pipelinesFS embed.FS + +func Init() { + module.PipelinesFS = &pipelinesFS +} diff --git a/x-pack/winlogbeat/module/powershell/config/winlogbeat-powershell.js b/x-pack/winlogbeat/module/powershell/config/winlogbeat-powershell.js deleted file mode 100644 index 698b12711bf2..000000000000 --- a/x-pack/winlogbeat/module/powershell/config/winlogbeat-powershell.js +++ /dev/null @@ -1,690 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License; -// you may not use this file except in compliance with the Elastic License. - -var powershell = (function () { - var path = require("path"); - var processor = require("processor"); - var windows = require("windows"); - - var normalizeCommonFieldNames = new processor.Convert({ - fields: [ - { - from: "winlog.event_data.Engine Version", - to: "winlog.event_data.EngineVersion", - }, - { - from: "winlog.event_data.Pipeline ID", - to: "winlog.event_data.PipelineId", - }, - { - from: "winlog.event_data.Runspace ID", - to: "winlog.event_data.RunspaceId", - }, - { - from: "winlog.event_data.Host Version", - to: "winlog.event_data.HostVersion", - }, - { - from: "winlog.event_data.Script Name", - to: "winlog.event_data.ScriptName", - }, - { - from: "winlog.event_data.Path", - to: "winlog.event_data.ScriptName", - }, - { - from: "winlog.event_data.Command Path", - to: "winlog.event_data.CommandPath", - }, - { - from: "winlog.event_data.Command Name", - to: "winlog.event_data.CommandName", - }, - { - from: "winlog.event_data.Command Type", - to: "winlog.event_data.CommandType", - }, - { - from: "winlog.event_data.User", - to: "winlog.event_data.UserId", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - - // Builds a dissect tokenizer. - // - // - chunks: number of chunks dissect needs to look for. - // - delimiter: indicates what is the delimiter between chunks, - // in addition to `\n` which is already expected. - // - sep: separator between key value pairs. - // - // example: - // For a string like "Foo=Bar\n\tBar=Baz", chunks: 2, delimiter: '\t', sep: '=' - var buildNewlineSpacedTokenizer = function (chunks, delimiter, sep) { - var tokenizer = ""; - for (var i = 0; i < chunks; i++) { - if (i !== 0) { - tokenizer += "\n%{}"; - } - tokenizer += delimiter+"%{*p"+i+"}"+sep+"%{&p"+i+"}"; - } - return tokenizer; - }; - - var dissectField = function (fromField, targetPrefix, chunks, delimiter, sep) { - return new processor.Dissect({ - field: fromField, - target_prefix: targetPrefix, - tokenizer: buildNewlineSpacedTokenizer(chunks, delimiter, sep), - fail_on_error: false, - }); - }; - - // countChunksDelimitedBy will return the number of chunks contained in a field - // that are delimited by the given delimiter. - var countChunksDelimitedBy = function(evt, fromField, delimiter) { - var str = evt.Get(fromField); - if (!str) { - return 0; - } - return str.split(delimiter).length-1; - }; - - var dissect4xxAnd600 = function (evt) { - var delimiter = "\t"; - var chunks = countChunksDelimitedBy(evt, "winlog.event_data.param3", delimiter); - - dissectField("winlog.event_data.param3", "winlog.event_data", chunks, delimiter, "=").Run(evt); - - // these fields contain redundant information. - evt.Delete("winlog.event_data.param1"); - evt.Delete("winlog.event_data.param2"); - evt.Delete("winlog.event_data.param3"); - }; - - var dissect800Detail = function (evt) { - var delimiter = "\t"; - var chunks = countChunksDelimitedBy(evt, "winlog.event_data.param2", delimiter); - - dissectField("winlog.event_data.param2", "winlog.event_data", chunks, "\t", "=").Run(evt); - - // these fields contain redundant information. - evt.Delete("winlog.event_data.param1"); - evt.Delete("winlog.event_data.param2"); - }; - - var dissect4103 = function (evt) { - var delimiter = " "; - var chunks = countChunksDelimitedBy(evt, "winlog.event_data.ContextInfo", delimiter); - - dissectField("winlog.event_data.ContextInfo", "winlog.event_data", chunks, delimiter, " = ").Run(evt); - - // these fields contain redundant information. - evt.Delete("winlog.event_data.ContextInfo"); - evt.Delete("winlog.event_data.Severity"); - }; - - var addEngineVersion = function (evt) { - var version = evt.Get("winlog.event_data.EngineVersion"); - evt.Delete("winlog.event_data.EngineVersion"); - if (!version) { - return; - } - - evt.Put("powershell.engine.version", version); - }; - - var addPipelineID = function (evt) { - var id = evt.Get("winlog.event_data.PipelineId"); - evt.Delete("winlog.event_data.PipelineId"); - if (!id) { - return; - } - - evt.Put("powershell.pipeline_id", id); - }; - - var addRunspaceID = function (evt) { - var id = evt.Get("winlog.event_data.RunspaceId"); - evt.Delete("winlog.event_data.RunspaceId"); - if (!id) { - return; - } - - evt.Put("powershell.runspace_id", id); - }; - - var addScriptBlockID = function (evt) { - var id = evt.Get("winlog.event_data.ScriptBlockId"); - evt.Delete("winlog.event_data.ScriptBlockId"); - if (!id) { - return; - } - - evt.Put("powershell.file.script_block_id", id); - }; - - var addScriptBlockText = function (evt) { - var text = evt.Get("winlog.event_data.ScriptBlockText"); - evt.Delete("winlog.event_data.ScriptBlockText"); - if (!text) { - return; - } - - evt.Put("powershell.file.script_block_text", text); - }; - - var splitCommandLine = function (evt, source, target) { - var commandLine = evt.Get(source); - if (!commandLine) { - return; - } - evt.Put(target, windows.splitCommandLine(commandLine)); - }; - - var addProcessArgs = function (evt) { - splitCommandLine(evt, "process.command_line", "process.args"); - var args = evt.Get("process.args"); - if (args && args.length > 0) { - evt.Put("process.args_count", args.length); - } - }; - - var addExecutableVersion = function (evt) { - var version = evt.Get("winlog.event_data.HostVersion"); - evt.Delete("winlog.event_data.HostVersion"); - if (!version) { - return; - } - - evt.Put("powershell.process.executable_version", version); - }; - - var addFileInfo = function (evt) { - var scriptName = evt.Get("winlog.event_data.ScriptName"); - evt.Delete("winlog.event_data.ScriptName"); - if (!scriptName) { - return; - } - - evt.Put("file.path", scriptName); - evt.Put("file.name", path.basename(scriptName)); - evt.Put("file.directory", path.dirname(scriptName)); - - // path returns extensions with a preceding ., e.g.: .tmp, .png - // according to ecs the expected format is without it, so we need to remove it. - var ext = path.extname(scriptName); - if (!ext) { - return; - } - - if (ext.charAt(0) === ".") { - ext = ext.substr(1); - } - evt.Put("file.extension", ext); - }; - - var addCommandValue = function (evt) { - var value = evt.Get("winlog.event_data.CommandLine") - evt.Delete("winlog.event_data.CommandLine"); - if (!value) { - return; - } - - evt.Put("powershell.command.value", value.trim()); - }; - - var addCommandPath = function (evt) { - var commandPath = evt.Get("winlog.event_data.CommandPath"); - evt.Delete("winlog.event_data.CommandPath"); - if (!commandPath) { - return; - } - - evt.Put("powershell.command.path", commandPath); - }; - - var addCommandName = function (evt) { - var commandName = evt.Get("winlog.event_data.CommandName"); - evt.Delete("winlog.event_data.CommandName"); - if (!commandName) { - return; - } - - evt.Put("powershell.command.name", commandName); - }; - - var addCommandType = function (evt) { - var commandType = evt.Get("winlog.event_data.CommandType"); - evt.Delete("winlog.event_data.CommandType"); - if (!commandType) { - return; - } - - evt.Put("powershell.command.type", commandType); - }; - - var detailRegex = /^(.+)\((.+)\)\:\s*(.+)?$/; - var parameterBindingRegex = /^.*name\=(.+);\s*value\=(.+)$/ - - // Parses a command invocation detail raw line, and converts it to an object, based on its type. - // - // - for unexpectedly formatted ones: {value: "the raw line as it is"} - // - for all: - // * related_command: describes to what command it is related to - // * value: the value for that detail line - // * type: the type of the detail line, i.e.: CommandInvocation, ParameterBinding, NonTerminatingError - // - additionally, ParameterBinding adds a `name` field with the parameter name being bound. - var parseRawDetail = function (raw) { - var matches = detailRegex.exec(raw); - if (!matches || matches.length !== 4) { - return {value: raw}; - } - - if (matches[1] !== "ParameterBinding") { - return {type: matches[1], related_command: matches[2], value: matches[3]}; - } - - var nameValMatches = parameterBindingRegex.exec(matches[3]); - if (!nameValMatches || nameValMatches.length !== 3) { - return {value: matches[3]}; - } - - return { - type: matches[1], - related_command: matches[2], - name: nameValMatches[1], - value: nameValMatches[2], - }; - }; - - var addCommandInvocationDetails = function (evt, from) { - var rawDetails = evt.Get(from); - if (!rawDetails) { - return; - } - - var details = []; - rawDetails.split("\n").forEach(function (raw) { - details.push(parseRawDetail(raw)); - }); - - if (details.length === 0) { - return; - } - - evt.Delete(from); - evt.Put("powershell.command.invocation_details", details); - }; - - var addCommandInvocationDetailsForEvent800 = function (evt) { - addCommandInvocationDetails(evt, "winlog.event_data.param3"); - }; - - var addCommandInvocationDetailsForEvent4103 = function (evt) { - addCommandInvocationDetails(evt, "winlog.event_data.Payload"); - }; - - var addUser = function (evt) { - var userParts = evt.Get("winlog.event_data.UserId").split("\\"); - evt.Delete("winlog.event_data.UserId"); - if (userParts.length === 2) { - evt.Put("user.domain", userParts[0]); - evt.Put("user.name", userParts[1]); - evt.AppendTo("related.user", userParts[1]); - } - }; - - var addConnectedUser = function (evt) { - var userParts = evt.Get("winlog.event_data.Connected User").split("\\"); - evt.Delete("winlog.event_data.Connected User"); - if (userParts.length === 2) { - evt.Put("powershell.connected_user.domain", userParts[0]); - if (evt.Get("user.domain")) { - evt.Put("destination.user.domain", evt.Get("user.domain")); - } - evt.Put("source.user.domain", userParts[0]); - evt.Put("user.domain", userParts[0]); - - evt.Put("powershell.connected_user.name", userParts[1]); - if (evt.Get("user.name")) { - evt.Put("destination.user.name", evt.Get("user.name")); - } - evt.Put("source.user.name", userParts[1]); - evt.Put("user.name", userParts[1]); - evt.AppendTo("related.user", userParts[1]); - } - }; - - var removeEmptyEventData = function (evt) { - var eventData = evt.Get("winlog.event_data"); - if (eventData && Object.keys(eventData).length === 0) { - evt.Delete("winlog.event_data"); - } - }; - - var event4xxAnd600Common = new processor.Chain() - .Add(dissect4xxAnd600) - .Convert({ - fields: [ - { - from: "winlog.event_data.SequenceNumber", - to: "event.sequence", - type: "long", - }, - { - from: "winlog.event_data.NewEngineState", - to: "powershell.engine.new_state", - }, - { - from: "winlog.event_data.PreviousEngineState", - to: "powershell.engine.previous_state", - }, - { - from: "winlog.event_data.NewProviderState", - to: "powershell.provider.new_state", - }, - { - from: "winlog.event_data.ProviderName", - to: "powershell.provider.name", - }, - { - from: "winlog.event_data.HostId", - to: "process.entity_id", - }, - { - from: "winlog.event_data.HostApplication", - to: "process.command_line", - }, - { - from: "winlog.event_data.HostName", - to: "process.title", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(addEngineVersion) - .Add(addPipelineID) - .Add(addRunspaceID) - .Add(addProcessArgs) - .Add(addExecutableVersion) - .Add(addFileInfo) - .Add(addCommandValue) - .Add(addCommandPath) - .Add(addCommandName) - .Add(addCommandType) - .Add(removeEmptyEventData) - .Build(); - - var event400 = new processor.Chain() - .AddFields({ - fields: { - category: ["process"], - type: ["start"], - }, - target: "event", - }) - .Add(event4xxAnd600Common) - .Build() - - var event403 = new processor.Chain() - .AddFields({ - fields: { - category: ["process"], - type: ["end"], - }, - target: "event", - }) - .Add(event4xxAnd600Common) - .Build() - - var event600 = new processor.Chain() - .AddFields({ - fields: { - category: ["process"], - type: ["info"], - }, - target: "event", - }) - .Add(event4xxAnd600Common) - .Build() - - var event800 = new processor.Chain() - .Add(dissect800Detail) - .AddFields({ - fields: { - category: ["process"], - type: ["info"], - }, - target: "event", - }) - .Convert({ - fields: [ - { - from: "winlog.event_data.SequenceNumber", - to: "event.sequence", - type: "long", - }, - { - from: "winlog.event_data.HostId", - to: "process.entity_id", - }, - { - from: "winlog.event_data.HostApplication", - to: "process.command_line", - }, - { - from: "winlog.event_data.HostName", - to: "process.title", - }, - { - from: "winlog.event_data.DetailTotal", - to: "powershell.total", - type: "long", - }, - { - from: "winlog.event_data.DetailSequence", - to: "powershell.sequence", - type: "long", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(addEngineVersion) - .Add(addPipelineID) - .Add(addRunspaceID) - .Add(addProcessArgs) - .Add(addExecutableVersion) - .Add(addFileInfo) - .Add(addCommandValue) - .Add(addCommandPath) - .Add(addCommandName) - .Add(addCommandType) - .Add(addUser) - .Add(addCommandInvocationDetailsForEvent800) - .Add(removeEmptyEventData) - .Build(); - - var event4103 = new processor.Chain() - .Add(dissect4103) - .AddFields({ - fields: { - category: ["process"], - type: ["info"], - }, - target: "event", - }) - .Convert({ - fields: [ - { - from: "winlog.event_data.Sequence Number", - to: "event.sequence", - type: "long", - }, - { - from: "winlog.event_data.Host ID", - to: "process.entity_id", - }, - { - from: "winlog.event_data.Host Application", - to: "process.command_line", - }, - { - from: "winlog.event_data.Host Name", - to: "process.title", - }, - { - from: "winlog.event_data.Shell ID", - to: "powershell.id", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Convert({ - fields: [ - { - from: "winlog.user.identifier", - to: "user.id", - type: "string", - }, - ], - mode: "copy", - ignore_missing: true, - fail_on_error: false, - }) - .Add(normalizeCommonFieldNames) - .Add(addEngineVersion) - .Add(addPipelineID) - .Add(addRunspaceID) - .Add(addProcessArgs) - .Add(addExecutableVersion) - .Add(addFileInfo) - .Add(addCommandValue) - .Add(addCommandPath) - .Add(addCommandName) - .Add(addCommandType) - .Add(addUser) - .Add(addConnectedUser) - .Add(addCommandInvocationDetailsForEvent4103) - .Add(removeEmptyEventData) - .Build(); - - var event4104 = new processor.Chain() - .AddFields({ - fields: { - category: ["process"], - type: ["info"], - }, - target: "event", - }) - .Convert({ - fields: [ - { - from: "winlog.event_data.MessageNumber", - to: "powershell.sequence", - type: "long", - }, - { - from: "winlog.event_data.MessageTotal", - to: "powershell.total", - type: "long", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Convert({ - fields: [ - { - from: "winlog.user.identifier", - to: "user.id", - type: "string", - }, - ], - mode: "copy", - ignore_missing: true, - fail_on_error: false, - }) - .Add(normalizeCommonFieldNames) - .Add(addFileInfo) - .Add(addScriptBlockID) - .Add(addScriptBlockText) - .Add(removeEmptyEventData) - .Build(); - - var event4105And4106Common = new processor.Chain() - .Add(addRunspaceID) - .Add(addScriptBlockID) - .Add(removeEmptyEventData) - .Convert({ - fields: [ - { - from: "winlog.user.identifier", - to: "user.id", - type: "string", - }, - ], - mode: "copy", - ignore_missing: true, - fail_on_error: false, - }) - .Build(); - - var event4105 = new processor.Chain() - .Add(event4105And4106Common) - .AddFields({ - fields: { - category: ["process"], - type: ["start"], - }, - target: "event", - }) - .Build(); - - var event4106 = new processor.Chain() - .Add(event4105And4106Common) - .AddFields({ - fields: { - category: ["process"], - type: ["end"], - }, - target: "event", - }) - .Build(); - - return { - 400: event400.Run, - 403: event403.Run, - 600: event600.Run, - 800: event800.Run, - 4103: event4103.Run, - 4104: event4104.Run, - 4105: event4105.Run, - 4106: event4106.Run, - - process: function(evt) { - var eventId = evt.Get("winlog.event_id"); - var processor = this[eventId]; - if (processor === undefined) { - return; - } - evt.Put("event.module", "powershell"); - processor(evt); - }, - }; -})(); - -function process(evt) { - return powershell.process(evt); -} diff --git a/x-pack/winlogbeat/module/powershell/ingest/powershell.yml b/x-pack/winlogbeat/module/powershell/ingest/powershell.yml new file mode 100644 index 000000000000..117f7288a94e --- /dev/null +++ b/x-pack/winlogbeat/module/powershell/ingest/powershell.yml @@ -0,0 +1,433 @@ +--- +description: Pipeline for Windows Powershell events +processors: + - kv: + description: Split Event 800 event data fields. + field: winlog.event_data.param2 + target_field: winlog.event_data + field_split: "\n\t" + trim_key: "\n\t" + trim_value: "\n\t" + value_split: "=" + if: ctx?.winlog?.event_id == "800" + - kv: + description: Split Events 4xx and 600 event data fields. + field: winlog.event_data.param3 + target_field: winlog.event_data + field_split: "\n\t" + trim_key: "\n\t" + trim_value: "\n\t" + value_split: "=" + if: ctx?.winlog?.event_id != "800" + + ## ECS and Event fields. + + - set: + field: ecs.version + value: '1.12.0' + - set: + field: log.level + copy_from: winlog.level + ignore_empty_value: true + ignore_failure: true + if: ctx?.winlog?.level != "" + - date: + field: winlog.time_created + formats: + - ISO8601 + ignore_failure: true + if: ctx?.winlog?.time_created != null + + - set: + field: event.ingested + value: '{{_ingest.timestamp}}' + - set: + field: event.kind + value: event + - set: + field: event.code + value: '{{winlog.event_id}}' + - set: + field: event.category + value: process + - set: + field: event.type + value: start + if: ctx?.event.code == "400" + - set: + field: event.type + value: end + if: ctx?.event.code == "403" + - set: + field: event.type + value: info + if: ctx?.event?.type == null + - convert: + field: winlog.event_data.SequenceNumber + target_field: event.sequence + type: long + ignore_failure: true + ignore_missing: true + - convert: + field: winlog.record_id + type: string + ignore_failure: true + ignore_missing: true + + ## Process fields. + + - rename: + field: winlog.event_data.HostId + target_field: process.entity_id + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.HostId != "" + - rename: + field: winlog.event_data.HostApplication + target_field: process.command_line + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.HostApplication != "" + - rename: + field: winlog.event_data.HostName + target_field: process.title + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.HostName != "" + + ## User fields. + + - split: + field: winlog.event_data.UserId + target_field: "_temp.user_parts" + separator: '\\' + if: ctx?.winlog?.event_data?.UserId != null + - set: + field: user.domain + value: "{{_temp.user_parts.0}}" + ignore_failure: true + ignore_empty_value: true + if: ctx?._temp?.user_parts != null && ctx._temp.user_parts.size() == 2 + - set: + field: user.name + value: "{{_temp.user_parts.1}}" + ignore_failure: true + ignore_empty_value: true + if: ctx?._temp?.user_parts != null && ctx._temp.user_parts.size() == 2 + - append: + field: related.user + value: "{{user.name}}" + ignore_failure: true + allow_duplicates: false + if: ctx?.user?.name != null + + ## PowerShell fields. + + - rename: + field: winlog.event_data.NewEngineState + target_field: powershell.engine.new_state + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.NewEngineState != "" + - rename: + field: winlog.event_data.PreviousEngineState + target_field: powershell.engine.previous_state + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.PreviousEngineState != "" + - rename: + field: winlog.event_data.NewProviderState + target_field: powershell.provider.new_state + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.NewProviderState != "" + - rename: + field: winlog.event_data.ProviderName + target_field: powershell.provider.name + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.ProviderName != "" + - convert: + field: winlog.event_data.DetailTotal + target_field: powershell.total + type: long + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.DetailTotal != "" + - convert: + field: winlog.event_data.DetailSequence + target_field: powershell.sequence + type: long + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.DetailSequence != "" + - rename: + field: winlog.event_data.EngineVersion + target_field: powershell.engine.version + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.EngineVersion != "" + - rename: + field: winlog.event_data.PipelineId + target_field: powershell.pipeline_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.PipelineId != "" + - rename: + field: winlog.event_data.RunspaceId + target_field: powershell.runspace_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.RunspaceId != "" + - rename: + field: winlog.event_data.HostVersion + target_field: powershell.process.executable_version + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.HostVersion != "" + - rename: + field: winlog.event_data.CommandLine + target_field: powershell.command.value + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.CommandLine != "" + - rename: + field: winlog.event_data.CommandPath + target_field: powershell.command.path + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.CommandPath != "" + - rename: + field: winlog.event_data.CommandName + target_field: powershell.command.name + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.CommandName != "" + - rename: + field: winlog.event_data.CommandType + target_field: powershell.command.type + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.CommandType != "" + + - split: + description: Split Event 800 command invocation details. + field: winlog.event_data.param3 + separator: "\n" + ignore_failure: true + ignore_missing: true + if: ctx.event.code == "800" + - script: + description: |- + Parses all command invocation detail raw lines, and converts them to an object, based on their type. + - for unexpectedly formatted ones: {value: "the raw line as it is"} + - for all: + * related_command: describes to what command it is related to + * value: the value for that detail line + * type: the type of the detail line, i.e.: CommandInvocation, ParameterBinding, NonTerminatingError + - additionally, ParameterBinding adds a `name` field with the parameter name being bound. + lang: painless + if: ctx.event.code == "800" + params: + field: param3 + source: |- + def parseRawDetail(String raw) { + Pattern detailRegex = /^(.+)\((.+)\)\:\s*(.+)?$/; + Pattern parameterBindingRegex = /name\=(.+);\s*value\=(.+)$/; + + def matcher = detailRegex.matcher(raw); + if (!matcher.matches()) { + return ["value": raw]; + } + def matches = new ArrayList(); + for (def i = 0; i <= matcher.groupCount(); i++) { + matches.add(matcher.group(i)); + } + + if (matches.length != 4) { + return ["value": raw]; + } + + if (matches[1] != "ParameterBinding") { + return [ + "type": matches[1], + "related_command": matches[2], + "value": matches[3] + ]; + } + + matcher = parameterBindingRegex.matcher(matches[3]); + if (!matcher.matches()) { + return ["value": matches[4]]; + } + def nameValMatches = new ArrayList(); + for (def i = 0; i <= matcher.groupCount(); i++) { + nameValMatches.add(matcher.group(i)); + } + if (nameValMatches.length !== 3) { + return ["value": matches[3]]; + } + + return [ + "type": matches[1], + "related_command": matches[2], + "name": nameValMatches[1], + "value": nameValMatches[2] + ]; + } + + if (ctx?._temp == null) { + ctx._temp = new HashMap(); + } + + if (ctx._temp.details == null) { + ctx._temp.details = new ArrayList(); + } + + def values = ctx?.winlog?.event_data[params["field"]]; + if (values != null && values.length > 0) { + for (v in values) { + ctx._temp.details.add(parseRawDetail(v)); + } + } + - rename: + field: _temp.details + target_field: powershell.command.invocation_details + if: ctx?._temp?.details != null && ctx?._temp?.details.length > 0 + + - script: + description: Implements Windows-like SplitCommandLine + lang: painless + if: ctx?.process?.command_line != null && ctx.process.command_line != "" + source: |- + // appendBSBytes appends n '\\' bytes to b and returns the resulting slice. + def appendBSBytes(StringBuilder b, int n) { + for (; n > 0; n--) { + b.append('\\'); + } + return b; + } + + // readNextArg splits command line string cmd into next + // argument and command line remainder. + def readNextArg(String cmd) { + def b = new StringBuilder(); + boolean inquote; + int nslash; + for (; cmd.length() > 0; cmd = cmd.substring(1)) { + def c = cmd.charAt(0); + if (c == (char)' ' || c == (char)0x09) { + if (!inquote) { + return [ + "arg": appendBSBytes(b, nslash).toString(), + "rest": cmd.substring(1) + ]; + } + } else if (c == (char)'"') { + b = appendBSBytes(b, nslash/2); + if (nslash%2 == 0) { + // use "Prior to 2008" rule from + // http://daviddeley.com/autohotkey/parameters/parameters.htm + // section 5.2 to deal with double double quotes + if (inquote && cmd.length() > 1 && cmd.charAt(1) == (char)'"') { + b.append(c); + cmd = cmd.substring(1); + } + inquote = !inquote; + } else { + b.append(c); + } + nslash = 0; + continue; + } else if (c == (char)'\\') { + nslash++; + continue; + } + b = appendBSBytes(b, nslash); + nslash = 0; + b.append(c); + } + return [ + "arg": appendBSBytes(b, nslash).toString(), + "rest": '' + ]; + } + + // commandLineToArgv splits a command line into individual argument + // strings, following the Windows conventions documented + // at http://daviddeley.com/autohotkey/parameters/parameters.htm#WINARGV + // Original implementation found at: https://github.com/golang/go/commit/39c8d2b7faed06b0e91a1ad7906231f53aab45d1 + def commandLineToArgv(String cmd) { + def args = new ArrayList(); + while (cmd.length() > 0) { + if (cmd.charAt(0) == (char)' ' || cmd.charAt(0) == (char)0x09) { + cmd = cmd.substring(1); + continue; + } + def next = readNextArg(cmd); + cmd = next.rest; + args.add(next.arg); + } + return args; + } + + ctx.process.args = commandLineToArgv(ctx.process.command_line); + ctx.process.args_count = ctx.process.args.length; + + - script: + description: Adds file information. + lang: painless + if: ctx?.winlog?.event_data?.ScriptName != null && ctx.winlog.event_data.ScriptName.length() > 1 + source: |- + def path = ctx.winlog.event_data.ScriptName; + def idx = path.lastIndexOf("\\"); + if (idx > -1) { + if (ctx?.file == null) { + ctx.file = new HashMap(); + } + ctx.file.name = path.substring(idx+1); + ctx.file.directory = path.substring(0, idx); + + def extIdx = path.lastIndexOf("."); + if (extIdx > -1) { + ctx.file.extension = path.substring(extIdx+1); + } + } + - rename: + field: winlog.event_data.ScriptName + target_field: file.path + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.ScriptName != "" + + ## Cleanup. + + - remove: + field: + - _temp + - winlog.event_data.param1 + - winlog.event_data.param2 + - winlog.event_data.param3 + - winlog.event_data.SequenceNumber + - winlog.event_data.DetailTotal + - winlog.event_data.DetailSequence + - winlog.event_data.UserId + - winlog.time_created + - winlog.level + ignore_missing: true + ignore_failure: true + - script: + description: Remove all empty values from event_data. + lang: painless + source: ctx?.winlog?.event_data?.entrySet().removeIf(entry -> entry.getValue() == null || entry.getValue().equals("")); + - remove: + description: Remove empty event data. + field: winlog.event_data + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data != null && ctx.winlog.event_data.size() == 0 + +on_failure: + - set: + field: "error.message" + value: "{{ _ingest.on_failure_message }}" diff --git a/x-pack/winlogbeat/module/powershell/ingest/powershell_operational.yml b/x-pack/winlogbeat/module/powershell/ingest/powershell_operational.yml new file mode 100644 index 000000000000..d508f0d73413 --- /dev/null +++ b/x-pack/winlogbeat/module/powershell/ingest/powershell_operational.yml @@ -0,0 +1,492 @@ +--- +description: Pipeline for Windows Powershell/Operational events +processors: + - kv: + description: Split Event 4103 event data fields. + field: winlog.event_data.ContextInfo + target_field: winlog.event_data + field_split: "\n" + trim_key: " \n\t" + trim_value: " \n\t" + value_split: "=" + if: ctx?.winlog?.event_id == "4103" + - script: + description: Remove spaces from all event_data keys. + lang: painless + if: ctx?.winlog?.event_data != null + source: |- + def newEventData = new HashMap(); + for (entry in ctx.winlog.event_data.entrySet()) { + def newKey = /\s/.matcher(entry.getKey().toString()).replaceAll(""); + newEventData.put(newKey, entry.getValue()); + } + ctx.winlog.event_data = newEventData; + + ## ECS and Event fields. + + - set: + field: ecs.version + value: '1.12.0' + - set: + field: log.level + copy_from: winlog.level + ignore_empty_value: true + ignore_failure: true + if: ctx?.winlog?.level != "" + - date: + field: winlog.time_created + formats: + - ISO8601 + ignore_failure: true + if: ctx?.winlog?.time_created != null + + - set: + field: event.ingested + value: '{{_ingest.timestamp}}' + - set: + field: event.kind + value: event + - set: + field: event.code + value: '{{winlog.event_id}}' + - set: + field: event.category + value: process + - set: + field: event.type + value: start + if: ctx?.event.code == "4105" + - set: + field: event.type + value: end + if: ctx?.event.code == "4106" + - set: + field: event.type + value: info + if: ctx?.event?.type == null + - convert: + field: winlog.event_data.SequenceNumber + target_field: event.sequence + type: long + ignore_failure: true + ignore_missing: true + - convert: + field: winlog.record_id + type: string + ignore_failure: true + ignore_missing: true + + ## Process fields. + + - rename: + field: winlog.event_data.HostID + target_field: process.entity_id + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.HostID != "" + - rename: + field: winlog.event_data.HostApplication + target_field: process.command_line + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.HostApplication != "" + - rename: + field: winlog.event_data.HostName + target_field: process.title + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.HostName != "" + + ## User fields. + + - set: + field: user.id + copy_from: winlog.user.identifier + ignore_failure: true + ignore_empty_value: true + - split: + field: winlog.event_data.User + target_field: "_temp.user_parts" + separator: '\\' + if: ctx?.winlog?.event_data?.User != null + - set: + field: user.domain + value: "{{_temp.user_parts.0}}" + ignore_failure: true + ignore_empty_value: true + if: ctx?._temp?.user_parts != null && ctx._temp.user_parts.size() == 2 + - set: + field: user.name + value: "{{_temp.user_parts.1}}" + ignore_failure: true + ignore_empty_value: true + if: ctx?._temp?.user_parts != null && ctx._temp.user_parts.size() == 2 + - append: + field: related.user + value: "{{user.name}}" + ignore_failure: true + allow_duplicates: false + if: ctx?.user?.name != null + - split: + field: winlog.event_data.ConnectedUser + target_field: "_temp.connected_user_parts" + separator: '\\' + if: ctx?.winlog?.event_data?.ConnectedUser != null + - set: + field: source.user.domain + value: "{{_temp.connected_user_parts.0}}" + ignore_failure: true + ignore_empty_value: true + if: ctx?._temp?.connected_user_parts != null && ctx._temp.connected_user_parts.size() == 2 + - set: + field: source.user.name + value: "{{_temp.connected_user_parts.1}}" + ignore_failure: true + ignore_empty_value: true + if: ctx?._temp?.connected_user_parts != null && ctx._temp.connected_user_parts.size() == 2 + - append: + field: related.user + value: "{{source.user.name}}" + ignore_failure: true + allow_duplicates: false + if: ctx?.source?.user?.name != null + - rename: + field: user.domain + target_field: destination.user.domain + ignore_failure: true + ignore_missing: true + if: ctx?.source?.user != null + - rename: + field: user.name + target_field: destination.user.name + ignore_failure: true + ignore_missing: true + if: ctx?.source?.user != null + - set: + field: user.domain + copy_from: source.user.domain + ignore_failure: true + ignore_empty_value: true + if: ctx?.source?.user != null + - set: + field: user.name + copy_from: source.user.name + ignore_failure: true + ignore_empty_value: true + if: ctx?.source?.user != null + + ## PowerShell fields. + + - convert: + field: winlog.event_data.MessageNumber + target_field: powershell.sequence + type: long + ignore_failure: true + ignore_missing: true + - convert: + field: winlog.event_data.MessageTotal + target_field: powershell.total + type: long + ignore_failure: true + ignore_missing: true + - rename: + field: winlog.event_data.ShellID + target_field: powershell.id + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.ShellID != "" + - rename: + field: winlog.event_data.EngineVersion + target_field: powershell.engine.version + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.EngineVersion != "" + - rename: + field: winlog.event_data.PipelineID + target_field: powershell.pipeline_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.PipelineID != "" + - rename: + field: winlog.event_data.RunspaceID + target_field: powershell.runspace_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.RunspaceID != "" + - rename: + field: winlog.event_data.RunspaceId + target_field: powershell.runspace_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.RunspaceId != "" + - rename: + field: winlog.event_data.HostVersion + target_field: powershell.process.executable_version + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.HostVersion != "" + - rename: + field: winlog.event_data.CommandLine + target_field: powershell.command.value + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.CommandLine != "" + - rename: + field: winlog.event_data.CommandPath + target_field: powershell.command.path + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.CommandPath != "" + - rename: + field: winlog.event_data.CommandName + target_field: powershell.command.name + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.CommandName != "" + - rename: + field: winlog.event_data.CommandType + target_field: powershell.command.type + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.CommandType != "" + - rename: + field: winlog.event_data.ScriptBlockId + target_field: powershell.file.script_block_id + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.ScriptBlockId != "" + - rename: + field: winlog.event_data.ScriptBlockText + target_field: powershell.file.script_block_text + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.ScriptBlockText != "" + + - split: + description: Split Event 800 command invocation details. + field: winlog.event_data.Payload + separator: "\n" + ignore_failure: true + ignore_missing: true + if: ctx.event.code == "4103" + - script: + description: |- + Parses all command invocation detail raw lines, and converts them to an object, based on their type. + - for unexpectedly formatted ones: {value: "the raw line as it is"} + - for all: + * related_command: describes to what command it is related to + * value: the value for that detail line + * type: the type of the detail line, i.e.: CommandInvocation, ParameterBinding, NonTerminatingError + - additionally, ParameterBinding adds a `name` field with the parameter name being bound. + lang: painless + if: ctx.event.code == "4103" + params: + field: Payload + source: |- + def parseRawDetail(String raw) { + Pattern detailRegex = /^(.+)\((.+)\)\:\s*(.+)?$/; + Pattern parameterBindingRegex = /name\=(.+);\s*value\=(.+)$/; + + def matcher = detailRegex.matcher(raw); + if (!matcher.matches()) { + return ["value": raw]; + } + def matches = new ArrayList(); + for (def i = 0; i <= matcher.groupCount(); i++) { + matches.add(matcher.group(i)); + } + + if (matches.length != 4) { + return ["value": raw]; + } + + if (matches[1] != "ParameterBinding") { + return [ + "type": matches[1], + "related_command": matches[2], + "value": matches[3] + ]; + } + + matcher = parameterBindingRegex.matcher(matches[3]); + if (!matcher.matches()) { + return ["value": matches[4]]; + } + def nameValMatches = new ArrayList(); + for (def i = 0; i <= matcher.groupCount(); i++) { + nameValMatches.add(matcher.group(i)); + } + if (nameValMatches.length !== 3) { + return ["value": matches[3]]; + } + + return [ + "type": matches[1], + "related_command": matches[2], + "name": nameValMatches[1], + "value": nameValMatches[2] + ]; + } + + if (ctx?._temp == null) { + ctx._temp = new HashMap(); + } + + if (ctx._temp.details == null) { + ctx._temp.details = new ArrayList(); + } + + def values = ctx?.winlog?.event_data[params["field"]]; + if (values != null && values.length > 0) { + for (v in values) { + ctx._temp.details.add(parseRawDetail(v)); + } + } + - rename: + field: _temp.details + target_field: powershell.command.invocation_details + if: ctx?._temp?.details != null && ctx?._temp?.details.length > 0 + + - script: + description: Implements Windows-like SplitCommandLine + lang: painless + if: ctx?.process?.command_line != null && ctx.process.command_line != "" + source: |- + // appendBSBytes appends n '\\' bytes to b and returns the resulting slice. + def appendBSBytes(StringBuilder b, int n) { + for (; n > 0; n--) { + b.append('\\'); + } + return b; + } + + // readNextArg splits command line string cmd into next + // argument and command line remainder. + def readNextArg(String cmd) { + def b = new StringBuilder(); + boolean inquote; + int nslash; + for (; cmd.length() > 0; cmd = cmd.substring(1)) { + def c = cmd.charAt(0); + if (c == (char)' ' || c == (char)0x09) { + if (!inquote) { + return [ + "arg": appendBSBytes(b, nslash).toString(), + "rest": cmd.substring(1) + ]; + } + } else if (c == (char)'"') { + b = appendBSBytes(b, nslash/2); + if (nslash%2 == 0) { + // use "Prior to 2008" rule from + // http://daviddeley.com/autohotkey/parameters/parameters.htm + // section 5.2 to deal with double double quotes + if (inquote && cmd.length() > 1 && cmd.charAt(1) == (char)'"') { + b.append(c); + cmd = cmd.substring(1); + } + inquote = !inquote; + } else { + b.append(c); + } + nslash = 0; + continue; + } else if (c == (char)'\\') { + nslash++; + continue; + } + b = appendBSBytes(b, nslash); + nslash = 0; + b.append(c); + } + return [ + "arg": appendBSBytes(b, nslash).toString(), + "rest": '' + ]; + } + + // commandLineToArgv splits a command line into individual argument + // strings, following the Windows conventions documented + // at http://daviddeley.com/autohotkey/parameters/parameters.htm#WINARGV + // Original implementation found at: https://github.com/golang/go/commit/39c8d2b7faed06b0e91a1ad7906231f53aab45d1 + def commandLineToArgv(String cmd) { + def args = new ArrayList(); + while (cmd.length() > 0) { + if (cmd.charAt(0) == (char)' ' || cmd.charAt(0) == (char)0x09) { + cmd = cmd.substring(1); + continue; + } + def next = readNextArg(cmd); + cmd = next.rest; + args.add(next.arg); + } + return args; + } + + ctx.process.args = commandLineToArgv(ctx.process.command_line); + ctx.process.args_count = ctx.process.args.length; + + - rename: + field: winlog.event_data.Path + target_field: winlog.event_data.ScriptName + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.Path != "" + - script: + description: Adds file information. + lang: painless + if: ctx?.winlog?.event_data?.ScriptName != null && ctx.winlog.event_data.ScriptName.length() > 1 + source: |- + def path = ctx.winlog.event_data.ScriptName; + def idx = path.lastIndexOf("\\"); + if (idx > -1) { + if (ctx?.file == null) { + ctx.file = new HashMap(); + } + ctx.file.name = path.substring(idx+1); + ctx.file.directory = path.substring(0, idx); + + def extIdx = path.lastIndexOf("."); + if (extIdx > -1) { + ctx.file.extension = path.substring(extIdx+1); + } + } + - rename: + field: winlog.event_data.ScriptName + target_field: file.path + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.ScriptName != "" + + ## Cleanup. + + - remove: + field: + - _temp + - winlog.event_data.SequenceNumber + - winlog.event_data.User + - winlog.event_data.ConnectedUser + - winlog.event_data.ContextInfo + - winlog.event_data.Severity + - winlog.event_data.MessageTotal + - winlog.event_data.MessageNumber + - winlog.event_data.Payload + - winlog.time_created + - winlog.level + ignore_missing: true + ignore_failure: true + - script: + description: Remove all empty values from event_data. + lang: painless + source: ctx?.winlog?.event_data?.entrySet().removeIf(entry -> entry.getValue() == null || entry.getValue().equals("")); + - remove: + description: Remove empty event data. + field: winlog.event_data + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data != null && ctx.winlog.event_data.size() == 0 + +on_failure: + - set: + field: "error.message" + value: "{{ _ingest.on_failure_message }}" diff --git a/x-pack/winlogbeat/module/powershell/test/powershell_windows_test.go b/x-pack/winlogbeat/module/powershell/test/powershell_windows_test.go deleted file mode 100644 index 46c4f463f404..000000000000 --- a/x-pack/winlogbeat/module/powershell/test/powershell_windows_test.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License; -// you may not use this file except in compliance with the Elastic License. - -package test - -import ( - "testing" - - "github.com/elastic/beats/v7/x-pack/winlogbeat/module" - - // Register required processors. - _ "github.com/elastic/beats/v7/libbeat/cmd/instance" - _ "github.com/elastic/beats/v7/libbeat/processors/timestamp" -) - -// Ignore these fields because they can be different on different versions -// of windows. -var ignoreFields = []string{ - "message", -} - -func TestPowerShell(t *testing.T) { - module.TestPipeline(t, "testdata/*.evtx", "../config/winlogbeat-powershell.js", - module.WithFieldFilter(ignoreFields)) -} diff --git a/x-pack/winlogbeat/module/routing/ingest/routing.yml b/x-pack/winlogbeat/module/routing/ingest/routing.yml new file mode 100644 index 000000000000..7566be699437 --- /dev/null +++ b/x-pack/winlogbeat/module/routing/ingest/routing.yml @@ -0,0 +1,20 @@ +--- +description: Winlogbeat Routing Pipeline +processors: + - pipeline: + name: '{< IngestPipeline "security" >}' + if: ctx?.winlog?.channel == 'Security' + - pipeline: + name: '{< IngestPipeline "sysmon" >}' + if: ctx?.winlog?.channel == 'Microsoft-Windows-Sysmon/Operational' + - pipeline: + name: '{< IngestPipeline "powershell" >}' + if: ctx?.winlog?.channel == 'Windows Powershell' + - pipeline: + name: '{< IngestPipeline "powershell_operational" >}' + if: ctx?.winlog?.channel == 'Microsoft-Windows-PowerShell/Operational' +on_failure: + - set: + field: error.message + value: |- + Processor "{{ _ingest.on_failure_processor_type }}" with tag "{{ _ingest.on_failure_processor_tag }}" in pipeline "{{ _ingest.on_failure_pipeline }}" failed with message "{{ _ingest.on_failure_message }}" diff --git a/x-pack/winlogbeat/module/security/config/winlogbeat-security.js b/x-pack/winlogbeat/module/security/config/winlogbeat-security.js deleted file mode 100644 index 39739db14796..000000000000 --- a/x-pack/winlogbeat/module/security/config/winlogbeat-security.js +++ /dev/null @@ -1,2828 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License; -// you may not use this file except in compliance with the Elastic License. - -var security = (function () { - var path = require("path"); - var processor = require("processor"); - var windows = require("windows"); - - // Logon Types - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/basic-audit-logon-events - var logonTypes = { - "2": "Interactive", - "3": "Network", - "4": "Batch", - "5": "Service", - "7": "Unlock", - "8": "NetworkCleartext", - "9": "NewCredentials", - "10": "RemoteInteractive", - "11": "CachedInteractive", - }; - - // User Account Control Attributes Table - // https://support.microsoft.com/es-us/help/305144/how-to-use-useraccountcontrol-to-manipulate-user-account-properties - var uacFlags = [ - [0x0001, 'SCRIPT'], - [0x0002, 'ACCOUNTDISABLE'], - [0x0008, 'HOMEDIR_REQUIRED'], - [0x0010, 'LOCKOUT'], - [0x0020, 'PASSWD_NOTREQD'], - [0x0040, 'PASSWD_CANT_CHANGE'], - [0x0080, 'ENCRYPTED_TEXT_PWD_ALLOWED'], - [0x0100, 'TEMP_DUPLICATE_ACCOUNT'], - [0x0200, 'NORMAL_ACCOUNT'], - [0x0800, 'INTERDOMAIN_TRUST_ACCOUNT'], - [0x1000, 'WORKSTATION_TRUST_ACCOUNT'], - [0x2000, 'SERVER_TRUST_ACCOUNT'], - [0x10000, 'DONT_EXPIRE_PASSWORD'], - [0x20000, 'MNS_LOGON_ACCOUNT'], - [0x40000, 'SMARTCARD_REQUIRED'], - [0x80000, 'TRUSTED_FOR_DELEGATION'], - [0x100000, 'NOT_DELEGATED'], - [0x200000, 'USE_DES_KEY_ONLY'], - [0x400000, 'DONT_REQ_PREAUTH'], - [0x800000, 'PASSWORD_EXPIRED'], - [0x1000000, 'TRUSTED_TO_AUTH_FOR_DELEGATION'], - [0x04000000, 'PARTIAL_SECRETS_ACCOUNT'], - ]; - - // Kerberos TGT and TGS Ticket Options - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4769 - var ticketOptions = [ - "Reserved", - "Forwardable", - "Forwarded", - "Proxiable", - "Proxy", - "Allow-postdate", - "Postdated", - "Invalid", - "Renewable", - "Initial", - "Pre-authent", - "Opt-hardware-auth", - "Transited-policy-checked", - "Ok-as-delegate", - "Request-anonymous", - "Name-canonicalize", - "Unused", - "Unused", - "Unused", - "Unused", - "Unused", - "Unused", - "Unused", - "Unused", - "Unused", - "Unused", - "Disable-transited-check", - "Renewable-ok", - "Enc-tkt-in-skey", - "Unused", - "Renew", - "Validate"]; - - // Kerberos Encryption Types - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 - var ticketEncryptionTypes = { - "0x1": "DES-CBC-CRC", - "0x3": "DES-CBC-MD5", - "0x11": "AES128-CTS-HMAC-SHA1-96", - "0x12": "AES256-CTS-HMAC-SHA1-96", - "0x17": "RC4-HMAC", - "0x18": "RC4-HMAC-EXP", - "0xffffffff": "FAIL", - }; - - // Kerberos Result Status Codes - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 - var kerberosTktStatusCodes = { - "0x0": "KDC_ERR_NONE", - "0x1": "KDC_ERR_NAME_EXP", - "0x2": "KDC_ERR_SERVICE_EXP", - "0x3": "KDC_ERR_BAD_PVNO", - "0x4": "KDC_ERR_C_OLD_MAST_KVNO", - "0x5": "KDC_ERR_S_OLD_MAST_KVNO", - "0x6": "KDC_ERR_C_PRINCIPAL_UNKNOWN", - "0x7": "KDC_ERR_S_PRINCIPAL_UNKNOWN", - "0x8": "KDC_ERR_PRINCIPAL_NOT_UNIQUE", - "0x9": "KDC_ERR_NULL_KEY", - "0xA": "KDC_ERR_CANNOT_POSTDATE", - "0xB": "KDC_ERR_NEVER_VALID", - "0xC": "KDC_ERR_POLICY", - "0xD": "KDC_ERR_BADOPTION", - "0xE": "KDC_ERR_ETYPE_NOTSUPP", - "0xF": "KDC_ERR_SUMTYPE_NOSUPP", - "0x10": "KDC_ERR_PADATA_TYPE_NOSUPP", - "0x11": "KDC_ERR_TRTYPE_NO_SUPP", - "0x12": "KDC_ERR_CLIENT_REVOKED", - "0x13": "KDC_ERR_SERVICE_REVOKED", - "0x14": "KDC_ERR_TGT_REVOKED", - "0x15": "KDC_ERR_CLIENT_NOTYET", - "0x16": "KDC_ERR_SERVICE_NOTYET", - "0x17": "KDC_ERR_KEY_EXPIRED", - "0x18": "KDC_ERR_PREAUTH_FAILED", - "0x19": "KDC_ERR_PREAUTH_REQUIRED", - "0x1A": "KDC_ERR_SERVER_NOMATCH", - "0x1B": "KDC_ERR_MUST_USE_USER2USER", - "0x1F": "KRB_AP_ERR_BAD_INTEGRITY", - "0x20": "KRB_AP_ERR_TKT_EXPIRED", - "0x21": "KRB_AP_ERR_TKT_NYV", - "0x22": "KRB_AP_ERR_REPEAT", - "0x23": "KRB_AP_ERR_NOT_US", - "0x24": "KRB_AP_ERR_BADMATCH", - "0x25": "KRB_AP_ERR_SKEW", - "0x26": "KRB_AP_ERR_BADADDR", - "0x27": "KRB_AP_ERR_BADVERSION", - "0x28": "KRB_AP_ERR_MSG_TYPE", - "0x29": "KRB_AP_ERR_MODIFIED", - "0x2A": "KRB_AP_ERR_BADORDER", - "0x2C": "KRB_AP_ERR_BADKEYVER", - "0x2D": "KRB_AP_ERR_NOKEY", - "0x2E": "KRB_AP_ERR_MUT_FAIL", - "0x2F": "KRB_AP_ERR_BADDIRECTION", - "0x30": "KRB_AP_ERR_METHOD", - "0x31": "KRB_AP_ERR_BADSEQ", - "0x32": "KRB_AP_ERR_INAPP_CKSUM", - "0x33": "KRB_AP_PATH_NOT_ACCEPTED", - "0x34": "KRB_ERR_RESPONSE_TOO_BIG", - "0x3C": "KRB_ERR_GENERIC", - "0x3D": "KRB_ERR_FIELD_TOOLONG", - "0x3E": "KDC_ERR_CLIENT_NOT_TRUSTED", - "0x3F": "KDC_ERR_KDC_NOT_TRUSTED", - "0x40": "KDC_ERR_INVALID_SIG", - "0x41": "KDC_ERR_KEY_TOO_WEAK", - "0x42": "KRB_AP_ERR_USER_TO_USER_REQUIRED", - "0x43": "KRB_AP_ERR_NO_TGT", - "0x44": "KDC_ERR_WRONG_REALM", - }; - - // event.category, event.type, event.action - var eventActionTypes = { - "1100": [["process"], ["end"], "logging-service-shutdown"], - "1102": [["iam"], ["admin", "change"], "audit-log-cleared"], // need to recategorize - "1104": [["iam"], ["admin"],"logging-full"], - "1105": [["iam"], ["admin"],"auditlog-archieved"], - "1108": [["iam"], ["admin"],"logging-processing-error"], - "4610": [["configuration"], ["access"], "authentication-package-loaded"], - "4611": [["configuration"], ["change"], "trusted-logon-process-registered"], - "4614": [["configuration"], ["access"], "notification-package-loaded"], - "4616": [["configuration"], ["change"], "system-time-changed"], - "4622": [["configuration"], ["access"], "security-package-loaded"], - "4624": [["authentication"], ["start"], "logged-in"], - "4625": [["authentication"], ["start"], "logon-failed"], - "4634": [["authentication"], ["end"], "logged-out"], - "4647": [["authentication"], ["end"], "logged-out"], - "4648": [["authentication"], ["start"], "logged-in-explicit"], - "4657": [["registry", "configuration"], ["change"], "registry-value-modified"], - "4670": [["iam", "configuration"],["admin", "change"],"permissions-changed"], - "4672": [["iam"], ["admin"], "logged-in-special"], - "4673": [["iam"], ["admin"], "privileged-service-called"], - "4674": [["iam"], ["admin"], "privileged-operation"], - "4688": [["process"], ["start"], "created-process"], - "4689": [["process"], ["end"], "exited-process"], - "4697": [["iam", "configuration"], ["admin", "change"],"service-installed"], // remove iam and admin - "4698": [["iam", "configuration"], ["creation", "admin"], "scheduled-task-created"], // remove iam and admin - "4699": [["iam", "configuration"], ["deletion", "admin"], "scheduled-task-deleted"], // remove iam and admin - "4700": [["iam", "configuration"], ["change", "admin"], "scheduled-task-enabled"], // remove iam and admin - "4701": [["iam", "configuration"], ["change", "admin"], "scheduled-task-disabled"], // remove iam and admin - "4702": [["iam", "configuration"], ["change", "admin"], "scheduled-task-updated"], // remove iam and admin - "4706": [["configuration"], ["creation"], "domain-trust-added"], - "4707": [["configuration"], ["deletion"], "domain-trust-removed"], - "4713": [["configuration"], ["change"], "kerberos-policy-changed"], - "4714": [["configuration"], ["change"], "encrypted-data-recovery-policy-changed"], - "4715": [["configuration"], ["change"], "object-audit-policy-changed"], - "4716": [["configuration"], ["change"], "trusted-domain-information-changed"], - "4717": [["iam", "configuration"],["admin", "change"],"system-security-access-granted"], - "4718": [["iam", "configuration"],["admin", "deletion"],"system-security-access-removed"], - "4719": [["iam", "configuration"], ["admin", "change"], "changed-audit-config"], // remove iam and admin - "4720": [["iam"], ["user", "creation"], "added-user-account"], - "4722": [["iam"], ["user", "change"], "enabled-user-account"], - "4723": [["iam"], ["user", "change"], "changed-password"], - "4724": [["iam"], ["user", "change"], "reset-password"], - "4725": [["iam"], ["user", "deletion"], "disabled-user-account"], - "4726": [["iam"], ["user", "deletion"], "deleted-user-account"], - "4727": [["iam"], ["group", "creation"], "added-group-account"], - "4728": [["iam"], ["group", "change"], "added-member-to-group"], - "4729": [["iam"], ["group", "change"], "removed-member-from-group"], - "4730": [["iam"], ["group", "deletion"], "deleted-group-account"], - "4731": [["iam"], ["group", "creation"], "added-group-account"], - "4732": [["iam"], ["group", "change"], "added-member-to-group"], - "4733": [["iam"], ["group", "change"], "removed-member-from-group"], - "4734": [["iam"], ["group", "deletion"], "deleted-group-account"], - "4735": [["iam"], ["group", "change"], "modified-group-account"], - "4737": [["iam"], ["group", "change"], "modified-group-account"], - "4738": [["iam"], ["user", "change"], "modified-user-account"], - "4739": [["configuration"], ["change"], "domain-policy-changed"], - "4740": [["iam"], ["user", "change"], "locked-out-user-account"], - "4741": [["iam"], ["creation", "admin"], "added-computer-account"], // remove admin - "4742": [["iam"], ["change", "admin"], "changed-computer-account"], // remove admin - "4743": [["iam"], ["deletion", "admin"], "deleted-computer-account"], // remove admin - "4744": [["iam"], ["group", "creation"], "added-distribution-group-account"], - "4745": [["iam"], ["group", "change"], "changed-distribution-group-account"], - "4746": [["iam"], ["group", "change"], "added-member-to-distribution-group"], - "4747": [["iam"], ["group", "change"], "removed-member-from-distribution-group"], - "4748": [["iam"], ["group", "deletion"], "deleted-distribution-group-account"], - "4749": [["iam"], ["group", "creation"], "added-distribution-group-account"], - "4750": [["iam"], ["group", "change"], "changed-distribution-group-account"], - "4751": [["iam"], ["group", "change"], "added-member-to-distribution-group"], - "4752": [["iam"], ["group", "change"], "removed-member-from-distribution-group"], - "4753": [["iam"], ["group", "deletion"], "deleted-distribution-group-account"], - "4754": [["iam"], ["group", "creation"], "added-group-account"], - "4755": [["iam"], ["group", "change"], "modified-group-account"], - "4756": [["iam"], ["group", "change"], "added-member-to-group"], - "4757": [["iam"], ["group", "change"], "removed-member-from-group"], - "4758": [["iam"], ["group", "deletion"], "deleted-group-account"], - "4759": [["iam"], ["group", "creation"], "added-distribution-group-account"], - "4760": [["iam"], ["group", "change"], "changed-distribution-group-account"], - "4761": [["iam"], ["group", "change"], "added-member-to-distribution-group"], - "4762": [["iam"], ["group", "change"], "removed-member-from-distribution-group"], - "4763": [["iam"], ["group", "deletion"], "deleted-distribution-group-account"], - "4764": [["iam"], ["group", "change"], "type-changed-group-account"], - "4767": [["iam"], ["user", "change"], "unlocked-user-account"], - "4768": [["authentication"], ["start"], "kerberos-authentication-ticket-requested"], - "4769": [["authentication"], ["start"], "kerberos-service-ticket-requested"], - "4770": [["authentication"], ["start"], "kerberos-service-ticket-renewed"], - "4771": [["authentication"], ["start"], "kerberos-preauth-failed"], - "4776": [["authentication"], ["start"], "credential-validated"], - "4778": [["authentication", "session"], ["start"], "session-reconnected"], - "4779": [["authentication", "session"], ["end"], "session-disconnected"], - "4781": [["iam"], ["user", "change"], "renamed-user-account"], - "4798": [["iam"], ["user", "info"], "group-membership-enumerated"], // process enumerates the local groups to which the specified user belongs - "4799": [["iam"], ["group", "info"], "user-member-enumerated"], // a process enumerates the members of the specified local group - "4817": [["iam", "configuration"], ["admin", "change"],"object-audit-changed"], - "4902": [["iam", "configuration"], ["admin", "creation"],"user-audit-policy-created"], - "4904": [["iam", "configuration"], ["admin", "change"],"security-event-source-added"], - "4905": [["iam", "configuration"], ["admin", "deletion"], "security-event-source-removed"], - "4906": [["iam", "configuration"], ["admin", "change"], "crash-on-audit-changed"], - "4907": [["iam", "configuration"], ["admin", "change"], "audit-setting-changed"], - "4908": [["iam", "configuration"], ["admin", "change"], "special-group-table-changed"], - "4912": [["iam", "configuration"], ["admin", "change"], "per-user-audit-policy-changed"], - "4950": [["configuration"], ["change"], "windows-firewall-setting-changed"], - "4954": [["configuration"], ["change"], "windows-firewall-group-policy-changed"], - "4964": [["iam"], ["admin", "group"], "logged-in-special"], - "5024": [["process"], ["start"], "windows-firewall-service-started"], - "5025": [["process"], ["end"], "windows-firewall-service-stopped"], - "5033": [["driver"], ["start"], "windows-firewall-driver-started"], - "5034": [["driver"], ["end"], "windows-firewall-driver-stopped"], - "5037": [["driver"], ["end"], "windows-firewall-driver-error"], - }; - - // Services Types - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4697 - var serviceTypes = { - "0x1": "Kernel Driver", - "0x2": "File System Driver", - "0x8": "Recognizer Driver", - "0x10": "Win32 Own Process", - "0x20": "Win32 Share Process", - "0x110": "Interactive Own Process", - "0x120": "Interactive Share Process", - }; - - - // Audit Categories Description - // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-gpac/77878370-0712-47cd-997d-b07053429f6d - var auditDescription = { - "0CCE9210-69AE-11D9-BED3-505054503030":["Security State Change", "System"], - "0CCE9211-69AE-11D9-BED3-505054503030":["Security System Extension", "System"], - "0CCE9212-69AE-11D9-BED3-505054503030":["System Integrity", "System"], - "0CCE9213-69AE-11D9-BED3-505054503030":["IPsec Driver", "System"], - "0CCE9214-69AE-11D9-BED3-505054503030":["Other System Events", "System"], - "0CCE9215-69AE-11D9-BED3-505054503030":["Logon", "Logon/Logoff"], - "0CCE9216-69AE-11D9-BED3-505054503030":["Logoff","Logon/Logoff"], - "0CCE9217-69AE-11D9-BED3-505054503030":["Account Lockout","Logon/Logoff"], - "0CCE9218-69AE-11D9-BED3-505054503030":["IPsec Main Mode","Logon/Logoff"], - "0CCE9219-69AE-11D9-BED3-505054503030":["IPsec Quick Mode","Logon/Logoff"], - "0CCE921A-69AE-11D9-BED3-505054503030":["IPsec Extended Mode","Logon/Logoff"], - "0CCE921B-69AE-11D9-BED3-505054503030":["Special Logon","Logon/Logoff"], - "0CCE921C-69AE-11D9-BED3-505054503030":["Other Logon/Logoff Events","Logon/Logoff"], - "0CCE9243-69AE-11D9-BED3-505054503030":["Network Policy Server","Logon/Logoff"], - "0CCE9247-69AE-11D9-BED3-505054503030":["User / Device Claims","Logon/Logoff"], - "0CCE921D-69AE-11D9-BED3-505054503030":["File System","Object Access"], - "0CCE921E-69AE-11D9-BED3-505054503030":["Registry","Object Access"], - "0CCE921F-69AE-11D9-BED3-505054503030":["Kernel Object","Object Access"], - "0CCE9220-69AE-11D9-BED3-505054503030":["SAM","Object Access"], - "0CCE9221-69AE-11D9-BED3-505054503030":["Certification Services","Object Access"], - "0CCE9222-69AE-11D9-BED3-505054503030":["Application Generated","Object Access"], - "0CCE9223-69AE-11D9-BED3-505054503030":["Handle Manipulation","Object Access"], - "0CCE9224-69AE-11D9-BED3-505054503030":["File Share","Object Access"], - "0CCE9225-69AE-11D9-BED3-505054503030":["Filtering Platform Packet Drop","Object Access"], - "0CCE9226-69AE-11D9-BED3-505054503030":["Filtering Platform Connection ","Object Access"], - "0CCE9227-69AE-11D9-BED3-505054503030":["Other Object Access Events","Object Access"], - "0CCE9244-69AE-11D9-BED3-505054503030":["Detailed File Share","Object Access"], - "0CCE9245-69AE-11D9-BED3-505054503030":["Removable Storage","Object Access"], - "0CCE9246-69AE-11D9-BED3-505054503030":["Central Policy Staging","Object Access"], - "0CCE9228-69AE-11D9-BED3-505054503030":["Sensitive Privilege Use","Privilege Use"], - "0CCE9229-69AE-11D9-BED3-505054503030":["Non Sensitive Privilege Use","Privilege Use"], - "0CCE922A-69AE-11D9-BED3-505054503030":["Other Privilege Use Events","Privilege Use"], - "0CCE922B-69AE-11D9-BED3-505054503030":["Process Creation","Detailed Tracking"], - "0CCE922C-69AE-11D9-BED3-505054503030":["Process Termination","Detailed Tracking"], - "0CCE922D-69AE-11D9-BED3-505054503030":["DPAPI Activity","Detailed Tracking"], - "0CCE922E-69AE-11D9-BED3-505054503030":["RPC Events","Detailed Tracking"], - "0CCE9248-69AE-11D9-BED3-505054503030":["Plug and Play Events","Detailed Tracking"], - "0CCE922F-69AE-11D9-BED3-505054503030":["Audit Policy Change","Policy Change"], - "0CCE9230-69AE-11D9-BED3-505054503030":["Authentication Policy Change","Policy Change"], - "0CCE9231-69AE-11D9-BED3-505054503030":["Authorization Policy Change","Policy Change"], - "0CCE9232-69AE-11D9-BED3-505054503030":["MPSSVC Rule-Level Policy Change","Policy Change"], - "0CCE9233-69AE-11D9-BED3-505054503030":["Filtering Platform Policy Change","Policy Change"], - "0CCE9234-69AE-11D9-BED3-505054503030":["Other Policy Change Events","Policy Change"], - "0CCE9235-69AE-11D9-BED3-505054503030":["User Account Management","Account Management"], - "0CCE9236-69AE-11D9-BED3-505054503030":["Computer Account Management","Account Management"], - "0CCE9237-69AE-11D9-BED3-505054503030":["Security Group Management","Account Management"], - "0CCE9238-69AE-11D9-BED3-505054503030":["Distribution Group Management","Account Management"], - "0CCE9239-69AE-11D9-BED3-505054503030":["Application Group Management","Account Management"], - "0CCE923A-69AE-11D9-BED3-505054503030":["Other Account Management Events","Account Management"], - "0CCE923B-69AE-11D9-BED3-505054503030":["Directory Service Access","Account Management"], - "0CCE923C-69AE-11D9-BED3-505054503030":["Directory Service Changes","Account Management"], - "0CCE923D-69AE-11D9-BED3-505054503030":["Directory Service Replication","Account Management"], - "0CCE923E-69AE-11D9-BED3-505054503030":["Detailed Directory Service Replication","Account Management"], - "0CCE923F-69AE-11D9-BED3-505054503030":["Credential Validation","Account Logon"], - "0CCE9240-69AE-11D9-BED3-505054503030":["Kerberos Service Ticket Operations","Account Logon"], - "0CCE9241-69AE-11D9-BED3-505054503030":["Other Account Logon Events","Account Logon"], - "0CCE9242-69AE-11D9-BED3-505054503030":["Kerberos Authentication Service","Account Logon"], - }; - - - // Descriptions of failure status codes. - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4625 - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4776 - var logonFailureStatus = { - "0xc000005e": "There are currently no logon servers available to service the logon request.", - "0xc0000064": "User logon with misspelled or bad user account", - "0xc000006a": "User logon with misspelled or bad password", - "0xc000006d": "This is either due to a bad username or authentication information", - "0xc000006e": "Unknown user name or bad password.", - "0xc000006f": "User logon outside authorized hours", - "0xc0000070": "User logon from unauthorized workstation", - "0xc0000071": "User logon with expired password", - "0xc0000072": "User logon to account disabled by administrator", - "0xc00000dc": "Indicates the Sam Server was in the wrong state to perform the desired operation.", - "0xc0000133": "Clocks between DC and other computer too far out of sync", - "0xc000015b": "The user has not been granted the requested logon type (aka logon right) at this machine", - "0xc000018c": "The logon request failed because the trust relationship between the primary domain and the trusted domain failed.", - "0xc0000192": "An attempt was made to logon, but the Netlogon service was not started.", - "0xc0000193": "User logon with expired account", - "0xc0000224": "User is required to change password at next logon", - "0xc0000225": "Evidently a bug in Windows and not a risk", - "0xc0000234": "User logon with account locked", - "0xc00002ee": "Failure Reason: An Error occurred during Logon", - "0xc0000413": "Logon Failure: The machine you are logging onto is protected by an authentication firewall. The specified account is not allowed to authenticate to the machine.", - "0xc0000371": "The local account store does not contain secret material for the specified account", - "0x0": "Status OK.", - }; - - // Message table extracted from msobjs.dll on Windows 2019. - // https://gist.github.com/andrewkroh/665dca0682bd0e4daf194ab291694012 - var msobjsMessageTable = { - "279": "Undefined Access (no effect) Bit 7", - "1536": "Unused message ID", - "1537": "DELETE", - "1538": "READ_CONTROL", - "1539": "WRITE_DAC", - "1540": "WRITE_OWNER", - "1541": "SYNCHRONIZE", - "1542": "ACCESS_SYS_SEC", - "1543": "MAX_ALLOWED", - "1552": "Unknown specific access (bit 0)", - "1553": "Unknown specific access (bit 1)", - "1554": "Unknown specific access (bit 2)", - "1555": "Unknown specific access (bit 3)", - "1556": "Unknown specific access (bit 4)", - "1557": "Unknown specific access (bit 5)", - "1558": "Unknown specific access (bit 6)", - "1559": "Unknown specific access (bit 7)", - "1560": "Unknown specific access (bit 8)", - "1561": "Unknown specific access (bit 9)", - "1562": "Unknown specific access (bit 10)", - "1563": "Unknown specific access (bit 11)", - "1564": "Unknown specific access (bit 12)", - "1565": "Unknown specific access (bit 13)", - "1566": "Unknown specific access (bit 14)", - "1567": "Unknown specific access (bit 15)", - "1601": "Not used", - "1603": "Assign Primary Token Privilege", - "1604": "Lock Memory Privilege", - "1605": "Increase Memory Quota Privilege", - "1606": "Unsolicited Input Privilege", - "1607": "Trusted Computer Base Privilege", - "1608": "Security Privilege", - "1609": "Take Ownership Privilege", - "1610": "Load/Unload Driver Privilege", - "1611": "Profile System Privilege", - "1612": "Set System Time Privilege", - "1613": "Profile Single Process Privilege", - "1614": "Increment Base Priority Privilege", - "1615": "Create Pagefile Privilege", - "1616": "Create Permanent Object Privilege", - "1617": "Backup Privilege", - "1618": "Restore From Backup Privilege", - "1619": "Shutdown System Privilege", - "1620": "Debug Privilege", - "1621": "View or Change Audit Log Privilege", - "1622": "Change Hardware Environment Privilege", - "1623": "Change Notify (and Traverse) Privilege", - "1624": "Remotely Shut System Down Privilege", - "1792": "", - "1794": "", - "1795": "Enabled", - "1796": "Disabled", - "1797": "All", - "1798": "None", - "1799": "Audit Policy query/set API Operation", - "1800": "", - "1801": "Granted by", - "1802": "Denied by", - "1803": "Denied by Integrity Policy check", - "1804": "Granted by Ownership", - "1805": "Not granted", - "1806": "Granted by NULL DACL", - "1807": "Denied by Empty DACL", - "1808": "Granted by NULL Security Descriptor", - "1809": "Unknown or unchecked", - "1810": "Not granted due to missing", - "1811": "Granted by ACE on parent folder", - "1812": "Denied by ACE on parent folder", - "1813": "Granted by Central Access Rule", - "1814": "NOT Granted by Central Access Rule", - "1815": "Granted by parent folder's Central Access Rule", - "1816": "NOT Granted by parent folder's Central Access Rule", - "1817": "Unknown Type", - "1818": "String", - "1819": "Unsigned 64-bit Integer", - "1820": "64-bit Integer", - "1821": "FQBN", - "1822": "Blob", - "1823": "Sid", - "1824": "Boolean", - "1825": "TRUE", - "1826": "FALSE", - "1827": "Invalid", - "1828": "an ACE too long to display", - "1829": "a Security Descriptor too long to display", - "1830": "Not granted to AppContainers", - "1831": "...", - "1832": "Identification", - "1833": "Impersonation", - "1840": "Delegation", - "1841": "Denied by Process Trust Label ACE", - "1842": "Yes", - "1843": "No", - "1844": "System", - "1845": "Not Available", - "1846": "Default", - "1847": "DisallowMmConfig", - "1848": "Off", - "1849": "Auto", - "1872": "REG_NONE", - "1873": "REG_SZ", - "1874": "REG_EXPAND_SZ", - "1875": "REG_BINARY", - "1876": "REG_DWORD", - "1877": "REG_DWORD_BIG_ENDIAN", - "1878": "REG_LINK", - "1879": "REG_MULTI_SZ (New lines are replaced with *. A * is replaced with **)", - "1880": "REG_RESOURCE_LIST", - "1881": "REG_FULL_RESOURCE_DESCRIPTOR", - "1882": "REG_RESOURCE_REQUIREMENTS_LIST", - "1883": "REG_QWORD", - "1904": "New registry value created", - "1905": "Existing registry value modified", - "1906": "Registry value deleted", - "1920": "Sunday", - "1921": "Monday", - "1922": "Tuesday", - "1923": "Wednesday", - "1924": "Thursday", - "1925": "Friday", - "1926": "Saturday", - "1936": "TokenElevationTypeDefault (1)", - "1937": "TokenElevationTypeFull (2)", - "1938": "TokenElevationTypeLimited (3)", - "2048": "Account Enabled", - "2049": "Home Directory Required' - Disabled", - "2050": "Password Not Required' - Disabled", - "2051": "Temp Duplicate Account' - Disabled", - "2052": "Normal Account' - Disabled", - "2053": "MNS Logon Account' - Disabled", - "2054": "Interdomain Trust Account' - Disabled", - "2055": "Workstation Trust Account' - Disabled", - "2056": "Server Trust Account' - Disabled", - "2057": "Don't Expire Password' - Disabled", - "2058": "Account Unlocked", - "2059": "Encrypted Text Password Allowed' - Disabled", - "2060": "Smartcard Required' - Disabled", - "2061": "Trusted For Delegation' - Disabled", - "2062": "Not Delegated' - Disabled", - "2063": "Use DES Key Only' - Disabled", - "2064": "Don't Require Preauth' - Disabled", - "2065": "Password Expired' - Disabled", - "2066": "Trusted To Authenticate For Delegation' - Disabled", - "2067": "Exclude Authorization Information' - Disabled", - "2068": "Undefined UserAccountControl Bit 20' - Disabled", - "2069": "Protect Kerberos Service Tickets with AES Keys' - Disabled", - "2070": "Undefined UserAccountControl Bit 22' - Disabled", - "2071": "Undefined UserAccountControl Bit 23' - Disabled", - "2072": "Undefined UserAccountControl Bit 24' - Disabled", - "2073": "Undefined UserAccountControl Bit 25' - Disabled", - "2074": "Undefined UserAccountControl Bit 26' - Disabled", - "2075": "Undefined UserAccountControl Bit 27' - Disabled", - "2076": "Undefined UserAccountControl Bit 28' - Disabled", - "2077": "Undefined UserAccountControl Bit 29' - Disabled", - "2078": "Undefined UserAccountControl Bit 30' - Disabled", - "2079": "Undefined UserAccountControl Bit 31' - Disabled", - "2080": "Account Disabled", - "2081": "Home Directory Required' - Enabled", - "2082": "Password Not Required' - Enabled", - "2083": "Temp Duplicate Account' - Enabled", - "2084": "Normal Account' - Enabled", - "2085": "MNS Logon Account' - Enabled", - "2086": "Interdomain Trust Account' - Enabled", - "2087": "Workstation Trust Account' - Enabled", - "2088": "Server Trust Account' - Enabled", - "2089": "Don't Expire Password' - Enabled", - "2090": "Account Locked", - "2091": "Encrypted Text Password Allowed' - Enabled", - "2092": "Smartcard Required' - Enabled", - "2093": "Trusted For Delegation' - Enabled", - "2094": "Not Delegated' - Enabled", - "2095": "Use DES Key Only' - Enabled", - "2096": "Don't Require Preauth' - Enabled", - "2097": "Password Expired' - Enabled", - "2098": "Trusted To Authenticate For Delegation' - Enabled", - "2099": "Exclude Authorization Information' - Enabled", - "2100": "Undefined UserAccountControl Bit 20' - Enabled", - "2101": "Protect Kerberos Service Tickets with AES Keys' - Enabled", - "2102": "Undefined UserAccountControl Bit 22' - Enabled", - "2103": "Undefined UserAccountControl Bit 23' - Enabled", - "2104": "Undefined UserAccountControl Bit 24' - Enabled", - "2105": "Undefined UserAccountControl Bit 25' - Enabled", - "2106": "Undefined UserAccountControl Bit 26' - Enabled", - "2107": "Undefined UserAccountControl Bit 27' - Enabled", - "2108": "Undefined UserAccountControl Bit 28' - Enabled", - "2109": "Undefined UserAccountControl Bit 29' - Enabled", - "2110": "Undefined UserAccountControl Bit 30' - Enabled", - "2111": "Undefined UserAccountControl Bit 31' - Enabled", - "2304": "An Error occured during Logon.", - "2305": "The specified user account has expired.", - "2306": "The NetLogon component is not active.", - "2307": "Account locked out.", - "2308": "The user has not been granted the requested logon type at this machine.", - "2309": "The specified account's password has expired.", - "2310": "Account currently disabled.", - "2311": "Account logon time restriction violation.", - "2312": "User not allowed to logon at this computer.", - "2313": "Unknown user name or bad password.", - "2314": "Domain sid inconsistent.", - "2315": "Smartcard logon is required and was not used.", - "2432": "Not Available.", - "2436": "Random number generator failure.", - "2437": "Random number generation failed FIPS-140 pre-hash check.", - "2438": "Failed to zero secret data.", - "2439": "Key failed pair wise consistency check.", - "2448": "Failed to unprotect persistent cryptographic key.", - "2449": "Key export checks failed.", - "2450": "Validation of public key failed.", - "2451": "Signature verification failed.", - "2456": "Open key file.", - "2457": "Delete key file.", - "2458": "Read persisted key from file.", - "2459": "Write persisted key to file.", - "2464": "Export of persistent cryptographic key.", - "2465": "Import of persistent cryptographic key.", - "2480": "Open Key.", - "2481": "Create Key.", - "2482": "Delete Key.", - "2483": "Encrypt.", - "2484": "Decrypt.", - "2485": "Sign hash.", - "2486": "Secret agreement.", - "2487": "Domain settings", - "2488": "Local settings", - "2489": "Add provider.", - "2490": "Remove provider.", - "2491": "Add context.", - "2492": "Remove context.", - "2493": "Add function.", - "2494": "Remove function.", - "2495": "Add function provider.", - "2496": "Remove function provider.", - "2497": "Add function property.", - "2498": "Remove function property.", - "2499": "Machine key.", - "2500": "User key.", - "2501": "Key Derivation.", - "4352": "Device Access Bit 0", - "4353": "Device Access Bit 1", - "4354": "Device Access Bit 2", - "4355": "Device Access Bit 3", - "4356": "Device Access Bit 4", - "4357": "Device Access Bit 5", - "4358": "Device Access Bit 6", - "4359": "Device Access Bit 7", - "4360": "Device Access Bit 8", - "4361": "Undefined Access (no effect) Bit 9", - "4362": "Undefined Access (no effect) Bit 10", - "4363": "Undefined Access (no effect) Bit 11", - "4364": "Undefined Access (no effect) Bit 12", - "4365": "Undefined Access (no effect) Bit 13", - "4366": "Undefined Access (no effect) Bit 14", - "4367": "Undefined Access (no effect) Bit 15", - "4368": "Query directory", - "4369": "Traverse", - "4370": "Create object in directory", - "4371": "Create sub-directory", - "4372": "Undefined Access (no effect) Bit 4", - "4373": "Undefined Access (no effect) Bit 5", - "4374": "Undefined Access (no effect) Bit 6", - "4375": "Undefined Access (no effect) Bit 7", - "4376": "Undefined Access (no effect) Bit 8", - "4377": "Undefined Access (no effect) Bit 9", - "4378": "Undefined Access (no effect) Bit 10", - "4379": "Undefined Access (no effect) Bit 11", - "4380": "Undefined Access (no effect) Bit 12", - "4381": "Undefined Access (no effect) Bit 13", - "4382": "Undefined Access (no effect) Bit 14", - "4383": "Undefined Access (no effect) Bit 15", - "4384": "Query event state", - "4385": "Modify event state", - "4386": "Undefined Access (no effect) Bit 2", - "4387": "Undefined Access (no effect) Bit 3", - "4388": "Undefined Access (no effect) Bit 4", - "4389": "Undefined Access (no effect) Bit 5", - "4390": "Undefined Access (no effect) Bit 6", - "4391": "Undefined Access (no effect) Bit 7", - "4392": "Undefined Access (no effect) Bit 8", - "4393": "Undefined Access (no effect) Bit 9", - "4394": "Undefined Access (no effect) Bit 10", - "4395": "Undefined Access (no effect) Bit 11", - "4396": "Undefined Access (no effect) Bit 12", - "4397": "Undefined Access (no effect) Bit 13", - "4398": "Undefined Access (no effect) Bit 14", - "4399": "Undefined Access (no effect) Bit 15", - "4416": "ReadData (or ListDirectory)", - "4417": "WriteData (or AddFile)", - "4418": "AppendData (or AddSubdirectory or CreatePipeInstance)", - "4419": "ReadEA", - "4420": "WriteEA", - "4421": "Execute/Traverse", - "4422": "DeleteChild", - "4423": "ReadAttributes", - "4424": "WriteAttributes", - "4425": "Undefined Access (no effect) Bit 9", - "4426": "Undefined Access (no effect) Bit 10", - "4427": "Undefined Access (no effect) Bit 11", - "4428": "Undefined Access (no effect) Bit 12", - "4429": "Undefined Access (no effect) Bit 13", - "4430": "Undefined Access (no effect) Bit 14", - "4431": "Undefined Access (no effect) Bit 15", - "4432": "Query key value", - "4433": "Set key value", - "4434": "Create sub-key", - "4435": "Enumerate sub-keys", - "4436": "Notify about changes to keys", - "4437": "Create Link", - "4438": "Undefined Access (no effect) Bit 6", - "4439": "Undefined Access (no effect) Bit 7", - "4440": "Enable 64(or 32) bit application to open 64 bit key", - "4441": "Enable 64(or 32) bit application to open 32 bit key", - "4442": "Undefined Access (no effect) Bit 10", - "4443": "Undefined Access (no effect) Bit 11", - "4444": "Undefined Access (no effect) Bit 12", - "4445": "Undefined Access (no effect) Bit 13", - "4446": "Undefined Access (no effect) Bit 14", - "4447": "Undefined Access (no effect) Bit 15", - "4448": "Query mutant state", - "4449": "Undefined Access (no effect) Bit 1", - "4450": "Undefined Access (no effect) Bit 2", - "4451": "Undefined Access (no effect) Bit 3", - "4452": "Undefined Access (no effect) Bit 4", - "4453": "Undefined Access (no effect) Bit 5", - "4454": "Undefined Access (no effect) Bit 6", - "4455": "Undefined Access (no effect) Bit 7", - "4456": "Undefined Access (no effect) Bit 8", - "4457": "Undefined Access (no effect) Bit 9", - "4458": "Undefined Access (no effect) Bit 10", - "4459": "Undefined Access (no effect) Bit 11", - "4460": "Undefined Access (no effect) Bit 12", - "4461": "Undefined Access (no effect) Bit 13", - "4462": "Undefined Access (no effect) Bit 14", - "4463": "Undefined Access (no effect) Bit 15", - "4464": "Communicate using port", - "4465": "Undefined Access (no effect) Bit 1", - "4466": "Undefined Access (no effect) Bit 2", - "4467": "Undefined Access (no effect) Bit 3", - "4468": "Undefined Access (no effect) Bit 4", - "4469": "Undefined Access (no effect) Bit 5", - "4470": "Undefined Access (no effect) Bit 6", - "4471": "Undefined Access (no effect) Bit 7", - "4472": "Undefined Access (no effect) Bit 8", - "4473": "Undefined Access (no effect) Bit 9", - "4474": "Undefined Access (no effect) Bit 10", - "4475": "Undefined Access (no effect) Bit 11", - "4476": "Undefined Access (no effect) Bit 12", - "4477": "Undefined Access (no effect) Bit 13", - "4478": "Undefined Access (no effect) Bit 14", - "4479": "Undefined Access (no effect) Bit 15", - "4480": "Force process termination", - "4481": "Create new thread in process", - "4482": "Set process session ID", - "4483": "Perform virtual memory operation", - "4484": "Read from process memory", - "4485": "Write to process memory", - "4486": "Duplicate handle into or out of process", - "4487": "Create a subprocess of process", - "4488": "Set process quotas", - "4489": "Set process information", - "4490": "Query process information", - "4491": "Set process termination port", - "4492": "Undefined Access (no effect) Bit 12", - "4493": "Undefined Access (no effect) Bit 13", - "4494": "Undefined Access (no effect) Bit 14", - "4495": "Undefined Access (no effect) Bit 15", - "4496": "Control profile", - "4497": "Undefined Access (no effect) Bit 1", - "4498": "Undefined Access (no effect) Bit 2", - "4499": "Undefined Access (no effect) Bit 3", - "4500": "Undefined Access (no effect) Bit 4", - "4501": "Undefined Access (no effect) Bit 5", - "4502": "Undefined Access (no effect) Bit 6", - "4503": "Undefined Access (no effect) Bit 7", - "4504": "Undefined Access (no effect) Bit 8", - "4505": "Undefined Access (no effect) Bit 9", - "4506": "Undefined Access (no effect) Bit 10", - "4507": "Undefined Access (no effect) Bit 11", - "4508": "Undefined Access (no effect) Bit 12", - "4509": "Undefined Access (no effect) Bit 13", - "4510": "Undefined Access (no effect) Bit 14", - "4511": "Undefined Access (no effect) Bit 15", - "4512": "Query section state", - "4513": "Map section for write", - "4514": "Map section for read", - "4515": "Map section for execute", - "4516": "Extend size", - "4517": "Undefined Access (no effect) Bit 5", - "4518": "Undefined Access (no effect) Bit 6", - "4519": "Undefined Access (no effect) Bit 7", - "4520": "Undefined Access (no effect) Bit 8", - "4521": "Undefined Access (no effect) Bit 9", - "4522": "Undefined Access (no effect) Bit 10", - "4523": "Undefined Access (no effect) Bit 11", - "4524": "Undefined Access (no effect) Bit 12", - "4525": "Undefined Access (no effect) Bit 13", - "4526": "Undefined Access (no effect) Bit 14", - "4527": "Undefined Access (no effect) Bit 15", - "4528": "Query semaphore state", - "4529": "Modify semaphore state", - "4530": "Undefined Access (no effect) Bit 2", - "4531": "Undefined Access (no effect) Bit 3", - "4532": "Undefined Access (no effect) Bit 4", - "4533": "Undefined Access (no effect) Bit 5", - "4534": "Undefined Access (no effect) Bit 6", - "4535": "Undefined Access (no effect) Bit 7", - "4536": "Undefined Access (no effect) Bit 8", - "4537": "Undefined Access (no effect) Bit 9", - "4538": "Undefined Access (no effect) Bit 10", - "4539": "Undefined Access (no effect) Bit 11", - "4540": "Undefined Access (no effect) Bit 12", - "4541": "Undefined Access (no effect) Bit 13", - "4542": "Undefined Access (no effect) Bit 14", - "4543": "Undefined Access (no effect) Bit 15", - "4544": "Use symbolic link", - "4545": "Undefined Access (no effect) Bit 1", - "4546": "Undefined Access (no effect) Bit 2", - "4547": "Undefined Access (no effect) Bit 3", - "4548": "Undefined Access (no effect) Bit 4", - "4549": "Undefined Access (no effect) Bit 5", - "4550": "Undefined Access (no effect) Bit 6", - "4551": "Undefined Access (no effect) Bit 7", - "4552": "Undefined Access (no effect) Bit 8", - "4553": "Undefined Access (no effect) Bit 9", - "4554": "Undefined Access (no effect) Bit 10", - "4555": "Undefined Access (no effect) Bit 11", - "4556": "Undefined Access (no effect) Bit 12", - "4557": "Undefined Access (no effect) Bit 13", - "4558": "Undefined Access (no effect) Bit 14", - "4559": "Undefined Access (no effect) Bit 15", - "4560": "Force thread termination", - "4561": "Suspend or resume thread", - "4562": "Send an alert to thread", - "4563": "Get thread context", - "4564": "Set thread context", - "4565": "Set thread information", - "4566": "Query thread information", - "4567": "Assign a token to the thread", - "4568": "Cause thread to directly impersonate another thread", - "4569": "Directly impersonate this thread", - "4570": "Undefined Access (no effect) Bit 10", - "4571": "Undefined Access (no effect) Bit 11", - "4572": "Undefined Access (no effect) Bit 12", - "4573": "Undefined Access (no effect) Bit 13", - "4574": "Undefined Access (no effect) Bit 14", - "4575": "Undefined Access (no effect) Bit 15", - "4576": "Query timer state", - "4577": "Modify timer state", - "4578": "Undefined Access (no effect) Bit 2", - "4579": "Undefined Access (no effect) Bit 3", - "4580": "Undefined Access (no effect) Bit 4", - "4581": "Undefined Access (no effect) Bit 5", - "4582": "Undefined Access (no effect) Bit 6", - "4584": "Undefined Access (no effect) Bit 8", - "4585": "Undefined Access (no effect) Bit 9", - "4586": "Undefined Access (no effect) Bit 10", - "4587": "Undefined Access (no effect) Bit 11", - "4588": "Undefined Access (no effect) Bit 12", - "4589": "Undefined Access (no effect) Bit 13", - "4590": "Undefined Access (no effect) Bit 14", - "4591": "Undefined Access (no effect) Bit 15", - "4592": "AssignAsPrimary", - "4593": "Duplicate", - "4594": "Impersonate", - "4595": "Query", - "4596": "QuerySource", - "4597": "AdjustPrivileges", - "4598": "AdjustGroups", - "4599": "AdjustDefaultDacl", - "4600": "AdjustSessionID", - "4601": "Undefined Access (no effect) Bit 9", - "4602": "Undefined Access (no effect) Bit 10", - "4603": "Undefined Access (no effect) Bit 11", - "4604": "Undefined Access (no effect) Bit 12", - "4605": "Undefined Access (no effect) Bit 13", - "4606": "Undefined Access (no effect) Bit 14", - "4607": "Undefined Access (no effect) Bit 15", - "4608": "Create instance of object type", - "4609": "Undefined Access (no effect) Bit 1", - "4610": "Undefined Access (no effect) Bit 2", - "4611": "Undefined Access (no effect) Bit 3", - "4612": "Undefined Access (no effect) Bit 4", - "4613": "Undefined Access (no effect) Bit 5", - "4614": "Undefined Access (no effect) Bit 6", - "4615": "Undefined Access (no effect) Bit 7", - "4616": "Undefined Access (no effect) Bit 8", - "4617": "Undefined Access (no effect) Bit 9", - "4618": "Undefined Access (no effect) Bit 10", - "4619": "Undefined Access (no effect) Bit 11", - "4620": "Undefined Access (no effect) Bit 12", - "4621": "Undefined Access (no effect) Bit 13", - "4622": "Undefined Access (no effect) Bit 14", - "4623": "Undefined Access (no effect) Bit 15", - "4864": "Query State", - "4865": "Modify State", - "5120": "Channel read message", - "5121": "Channel write message", - "5122": "Channel query information", - "5123": "Channel set information", - "5124": "Undefined Access (no effect) Bit 4", - "5125": "Undefined Access (no effect) Bit 5", - "5126": "Undefined Access (no effect) Bit 6", - "5127": "Undefined Access (no effect) Bit 7", - "5128": "Undefined Access (no effect) Bit 8", - "5129": "Undefined Access (no effect) Bit 9", - "5130": "Undefined Access (no effect) Bit 10", - "5131": "Undefined Access (no effect) Bit 11", - "5132": "Undefined Access (no effect) Bit 12", - "5133": "Undefined Access (no effect) Bit 13", - "5134": "Undefined Access (no effect) Bit 14", - "5135": "Undefined Access (no effect) Bit 15", - "5136": "Assign process", - "5137": "Set Attributes", - "5138": "Query Attributes", - "5139": "Terminate Job", - "5140": "Set Security Attributes", - "5141": "Undefined Access (no effect) Bit 5", - "5142": "Undefined Access (no effect) Bit 6", - "5143": "Undefined Access (no effect) Bit 7", - "5144": "Undefined Access (no effect) Bit 8", - "5145": "Undefined Access (no effect) Bit 9", - "5146": "Undefined Access (no effect) Bit 10", - "5147": "Undefined Access (no effect) Bit 11", - "5148": "Undefined Access (no effect) Bit 12", - "5149": "Undefined Access (no effect) Bit 13", - "5150": "Undefined Access (no effect) Bit 14", - "5151": "Undefined Access (no effect) Bit 15", - "5376": "ConnectToServer", - "5377": "ShutdownServer", - "5378": "InitializeServer", - "5379": "CreateDomain", - "5380": "EnumerateDomains", - "5381": "LookupDomain", - "5382": "Undefined Access (no effect) Bit 6", - "5383": "Undefined Access (no effect) Bit 7", - "5384": "Undefined Access (no effect) Bit 8", - "5385": "Undefined Access (no effect) Bit 9", - "5386": "Undefined Access (no effect) Bit 10", - "5387": "Undefined Access (no effect) Bit 11", - "5388": "Undefined Access (no effect) Bit 12", - "5389": "Undefined Access (no effect) Bit 13", - "5390": "Undefined Access (no effect) Bit 14", - "5391": "Undefined Access (no effect) Bit 15", - "5392": "ReadPasswordParameters", - "5393": "WritePasswordParameters", - "5394": "ReadOtherParameters", - "5395": "WriteOtherParameters", - "5396": "CreateUser", - "5397": "CreateGlobalGroup", - "5398": "CreateLocalGroup", - "5399": "GetLocalGroupMembership", - "5400": "ListAccounts", - "5401": "LookupIDs", - "5402": "AdministerServer", - "5403": "Undefined Access (no effect) Bit 11", - "5404": "Undefined Access (no effect) Bit 12", - "5405": "Undefined Access (no effect) Bit 13", - "5406": "Undefined Access (no effect) Bit 14", - "5407": "Undefined Access (no effect) Bit 15", - "5408": "ReadInformation", - "5409": "WriteAccount", - "5410": "AddMember", - "5411": "RemoveMember", - "5412": "ListMembers", - "5413": "Undefined Access (no effect) Bit 5", - "5414": "Undefined Access (no effect) Bit 6", - "5415": "Undefined Access (no effect) Bit 7", - "5416": "Undefined Access (no effect) Bit 8", - "5417": "Undefined Access (no effect) Bit 9", - "5418": "Undefined Access (no effect) Bit 10", - "5419": "Undefined Access (no effect) Bit 11", - "5420": "Undefined Access (no effect) Bit 12", - "5421": "Undefined Access (no effect) Bit 13", - "5422": "Undefined Access (no effect) Bit 14", - "5423": "Undefined Access (no effect) Bit 15", - "5424": "AddMember", - "5425": "RemoveMember", - "5426": "ListMembers", - "5427": "ReadInformation", - "5428": "WriteAccount", - "5429": "Undefined Access (no effect) Bit 5", - "5430": "Undefined Access (no effect) Bit 6", - "5431": "Undefined Access (no effect) Bit 7", - "5432": "Undefined Access (no effect) Bit 8", - "5433": "Undefined Access (no effect) Bit 9", - "5434": "Undefined Access (no effect) Bit 10", - "5435": "Undefined Access (no effect) Bit 11", - "5436": "Undefined Access (no effect) Bit 12", - "5437": "Undefined Access (no effect) Bit 13", - "5438": "Undefined Access (no effect) Bit 14", - "5439": "Undefined Access (no effect) Bit 15", - "5440": "ReadGeneralInformation", - "5441": "ReadPreferences", - "5442": "WritePreferences", - "5443": "ReadLogon", - "5444": "ReadAccount", - "5445": "WriteAccount", - "5446": "ChangePassword (with knowledge of old password)", - "5447": "SetPassword (without knowledge of old password)", - "5448": "ListGroups", - "5449": "ReadGroupMembership", - "5450": "ChangeGroupMembership", - "5451": "Undefined Access (no effect) Bit 11", - "5452": "Undefined Access (no effect) Bit 12", - "5453": "Undefined Access (no effect) Bit 13", - "5454": "Undefined Access (no effect) Bit 14", - "5455": "Undefined Access (no effect) Bit 15", - "5632": "View non-sensitive policy information", - "5633": "View system audit requirements", - "5634": "Get sensitive policy information", - "5635": "Modify domain trust relationships", - "5636": "Create special accounts (for assignment of user rights)", - "5637": "Create a secret object", - "5638": "Create a privilege", - "5639": "Set default quota limits", - "5640": "Change system audit requirements", - "5641": "Administer audit log attributes", - "5642": "Enable/Disable LSA", - "5643": "Lookup Names/SIDs", - "5648": "Change secret value", - "5649": "Query secret value", - "5650": "Undefined Access (no effect) Bit 2", - "5651": "Undefined Access (no effect) Bit 3", - "5652": "Undefined Access (no effect) Bit 4", - "5653": "Undefined Access (no effect) Bit 5", - "5654": "Undefined Access (no effect) Bit 6", - "5655": "Undefined Access (no effect) Bit 7", - "5656": "Undefined Access (no effect) Bit 8", - "5657": "Undefined Access (no effect) Bit 9", - "5658": "Undefined Access (no effect) Bit 10", - "5659": "Undefined Access (no effect) Bit 11", - "5660": "Undefined Access (no effect) Bit 12", - "5661": "Undefined Access (no effect) Bit 13", - "5662": "Undefined Access (no effect) Bit 14", - "5663": "Undefined Access (no effect) Bit 15", - "5664": "Query trusted domain name/SID", - "5665": "Retrieve the controllers in the trusted domain", - "5666": "Change the controllers in the trusted domain", - "5667": "Query the Posix ID offset assigned to the trusted domain", - "5668": "Change the Posix ID offset assigned to the trusted domain", - "5669": "Undefined Access (no effect) Bit 5", - "5670": "Undefined Access (no effect) Bit 6", - "5671": "Undefined Access (no effect) Bit 7", - "5672": "Undefined Access (no effect) Bit 8", - "5673": "Undefined Access (no effect) Bit 9", - "5674": "Undefined Access (no effect) Bit 10", - "5675": "Undefined Access (no effect) Bit 11", - "5676": "Undefined Access (no effect) Bit 12", - "5677": "Undefined Access (no effect) Bit 13", - "5678": "Undefined Access (no effect) Bit 14", - "5679": "Undefined Access (no effect) Bit 15", - "5680": "Query account information", - "5681": "Change privileges assigned to account", - "5682": "Change quotas assigned to account", - "5683": "Change logon capabilities assigned to account", - "5684": "Change the Posix ID offset assigned to the accounted domain", - "5685": "Undefined Access (no effect) Bit 5", - "5686": "Undefined Access (no effect) Bit 6", - "5687": "Undefined Access (no effect) Bit 7", - "5688": "Undefined Access (no effect) Bit 8", - "5689": "Undefined Access (no effect) Bit 9", - "5690": "Undefined Access (no effect) Bit 10", - "5691": "Undefined Access (no effect) Bit 11", - "5692": "Undefined Access (no effect) Bit 12", - "5693": "Undefined Access (no effect) Bit 13", - "5694": "Undefined Access (no effect) Bit 14", - "5695": "Undefined Access (no effect) Bit 15", - "5696": "KeyedEvent Wait", - "5697": "KeyedEvent Wake", - "5698": "Undefined Access (no effect) Bit 2", - "5699": "Undefined Access (no effect) Bit 3", - "5700": "Undefined Access (no effect) Bit 4", - "5701": "Undefined Access (no effect) Bit 5", - "5702": "Undefined Access (no effect) Bit 6", - "5703": "Undefined Access (no effect) Bit 7", - "5704": "Undefined Access (no effect) Bit 8", - "5705": "Undefined Access (no effect) Bit 9", - "5706": "Undefined Access (no effect) Bit 10", - "5707": "Undefined Access (no effect) Bit 11", - "5708": "Undefined Access (no effect) Bit 12", - "5709": "Undefined Access (no effect) Bit 13", - "5710": "Undefined Access (no effect) Bit 14", - "5711": "Undefined Access (no effect) Bit 15", - "6656": "Enumerate desktops", - "6657": "Read attributes", - "6658": "Access Clipboard", - "6659": "Create desktop", - "6660": "Write attributes", - "6661": "Access global atoms", - "6662": "Exit windows", - "6663": "Unused Access Flag", - "6664": "Include this windowstation in enumerations", - "6665": "Read screen", - "6672": "Read Objects", - "6673": "Create window", - "6674": "Create menu", - "6675": "Hook control", - "6676": "Journal (record)", - "6677": "Journal (playback)", - "6678": "Include this desktop in enumerations", - "6679": "Write objects", - "6680": "Switch to this desktop", - "6912": "Administer print server", - "6913": "Enumerate printers", - "6930": "Full Control", - "6931": "Print", - "6948": "Administer Document", - "7168": "Connect to service controller", - "7169": "Create a new service", - "7170": "Enumerate services", - "7171": "Lock service database for exclusive access", - "7172": "Query service database lock state", - "7173": "Set last-known-good state of service database", - "7184": "Query service configuration information", - "7185": "Set service configuration information", - "7186": "Query status of service", - "7187": "Enumerate dependencies of service", - "7188": "Start the service", - "7189": "Stop the service", - "7190": "Pause or continue the service", - "7191": "Query information from service", - "7192": "Issue service-specific control commands", - "7424": "DDE Share Read", - "7425": "DDE Share Write", - "7426": "DDE Share Initiate Static", - "7427": "DDE Share Initiate Link", - "7428": "DDE Share Request", - "7429": "DDE Share Advise", - "7430": "DDE Share Poke", - "7431": "DDE Share Execute", - "7432": "DDE Share Add Items", - "7433": "DDE Share List Items", - "7680": "Create Child", - "7681": "Delete Child", - "7682": "List Contents", - "7683": "Write Self", - "7684": "Read Property", - "7685": "Write Property", - "7686": "Delete Tree", - "7687": "List Object", - "7688": "Control Access", - "7689": "Undefined Access (no effect) Bit 9", - "7690": "Undefined Access (no effect) Bit 10", - "7691": "Undefined Access (no effect) Bit 11", - "7692": "Undefined Access (no effect) Bit 12", - "7693": "Undefined Access (no effect) Bit 13", - "7694": "Undefined Access (no effect) Bit 14", - "7695": "Undefined Access (no effect) Bit 15", - "7936": "Audit Set System Policy", - "7937": "Audit Query System Policy", - "7938": "Audit Set Per User Policy", - "7939": "Audit Query Per User Policy", - "7940": "Audit Enumerate Users", - "7941": "Audit Set Options", - "7942": "Audit Query Options", - "8064": "Port sharing (read)", - "8065": "Port sharing (write)", - "8096": "Default credentials", - "8097": "Credentials manager", - "8098": "Fresh credentials", - "8192": "Kerberos", - "8193": "Preshared key", - "8194": "Unknown authentication", - "8195": "DES", - "8196": "3DES", - "8197": "MD5", - "8198": "SHA1", - "8199": "Local computer", - "8200": "Remote computer", - "8201": "No state", - "8202": "Sent first (SA) payload", - "8203": "Sent second (KE) payload", - "8204": "Sent third (ID) payload", - "8205": "Initiator", - "8206": "Responder", - "8207": "No state", - "8208": "Sent first (SA) payload", - "8209": "Sent final payload", - "8210": "Complete", - "8211": "Unknown", - "8212": "Transport", - "8213": "Tunnel", - "8214": "IKE/AuthIP DoS prevention mode started", - "8215": "IKE/AuthIP DoS prevention mode stopped", - "8216": "Enabled", - "8217": "Not enabled", - "8218": "No state", - "8219": "Sent first (EM attributes) payload", - "8220": "Sent second (SSPI) payload", - "8221": "Sent third (hash) payload", - "8222": "IKEv1", - "8223": "AuthIP", - "8224": "Anonymous", - "8225": "NTLM V2", - "8226": "CGA", - "8227": "Certificate", - "8228": "SSL", - "8229": "None", - "8230": "DH group 1", - "8231": "DH group 2", - "8232": "DH group 14", - "8233": "DH group ECP 256", - "8234": "DH group ECP 384", - "8235": "AES-128", - "8236": "AES-192", - "8237": "AES-256", - "8238": "Certificate ECDSA P256", - "8239": "Certificate ECDSA P384", - "8240": "SSL ECDSA P256", - "8241": "SSL ECDSA P384", - "8242": "SHA 256", - "8243": "SHA 384", - "8244": "IKEv2", - "8245": "EAP payload sent", - "8246": "Authentication payload sent", - "8247": "EAP", - "8248": "DH group 24", - "8272": "System", - "8273": "Logon/Logoff", - "8274": "Object Access", - "8275": "Privilege Use", - "8276": "Detailed Tracking", - "8277": "Policy Change", - "8278": "Account Management", - "8279": "DS Access", - "8280": "Account Logon", - "8448": "Success removed", - "8449": "Success Added", - "8450": "Failure removed", - "8451": "Failure Added", - "8452": "Success include removed", - "8453": "Success include added", - "8454": "Success exclude removed", - "8455": "Success exclude added", - "8456": "Failure include removed", - "8457": "Failure include added", - "8458": "Failure exclude removed", - "8459": "Failure exclude added", - "12288": "Security State Change", - "12289": "Security System Extension", - "12290": "System Integrity", - "12291": "IPsec Driver", - "12292": "Other System Events", - "12544": "Logon", - "12545": "Logoff", - "12546": "Account Lockout", - "12547": "IPsec Main Mode", - "12548": "Special Logon", - "12549": "IPsec Quick Mode", - "12550": "IPsec Extended Mode", - "12551": "Other Logon/Logoff Events", - "12552": "Network Policy Server", - "12553": "User / Device Claims", - "12554": "Group Membership", - "12800": "File System", - "12801": "Registry", - "12802": "Kernel Object", - "12803": "SAM", - "12804": "Other Object Access Events", - "12805": "Certification Services", - "12806": "Application Generated", - "12807": "Handle Manipulation", - "12808": "File Share", - "12809": "Filtering Platform Packet Drop", - "12810": "Filtering Platform Connection", - "12811": "Detailed File Share", - "12812": "Removable Storage", - "12813": "Central Policy Staging", - "13056": "Sensitive Privilege Use", - "13057": "Non Sensitive Privilege Use", - "13058": "Other Privilege Use Events", - "13312": "Process Creation", - "13313": "Process Termination", - "13314": "DPAPI Activity", - "13315": "RPC Events", - "13316": "Plug and Play Events", - "13317": "Token Right Adjusted Events", - "13568": "Audit Policy Change", - "13569": "Authentication Policy Change", - "13570": "Authorization Policy Change", - "13571": "MPSSVC Rule-Level Policy Change", - "13572": "Filtering Platform Policy Change", - "13573": "Other Policy Change Events", - "13824": "User Account Management", - "13825": "Computer Account Management", - "13826": "Security Group Management", - "13827": "Distribution Group Management", - "13828": "Application Group Management", - "13829": "Other Account Management Events", - "14080": "Directory Service Access", - "14081": "Directory Service Changes", - "14082": "Directory Service Replication", - "14083": "Detailed Directory Service Replication", - "14336": "Credential Validation", - "14337": "Kerberos Service Ticket Operations", - "14338": "Other Account Logon Events", - "14339": "Kerberos Authentication Service", - "14592": "Inbound", - "14593": "Outbound", - "14594": "Forward", - "14595": "Bidirectional", - "14596": "IP Packet", - "14597": "Transport", - "14598": "Forward", - "14599": "Stream", - "14600": "Datagram Data", - "14601": "ICMP Error", - "14602": "MAC 802.3", - "14603": "MAC Native", - "14604": "vSwitch", - "14608": "Resource Assignment", - "14609": "Listen", - "14610": "Receive/Accept", - "14611": "Connect", - "14612": "Flow Established", - "14614": "Resource Release", - "14615": "Endpoint Closure", - "14616": "Connect Redirect", - "14617": "Bind Redirect", - "14624": "Stream Packet", - "14640": "ICMP Echo-Request", - "14641": "vSwitch Ingress", - "14642": "vSwitch Egress", - "14672": "", - "14673": "[NULL]", - "14674": "Value Added", - "14675": "Value Deleted", - "14676": "Active Directory Domain Services", - "14677": "Active Directory Lightweight Directory Services", - "14678": "Yes", - "14679": "No", - "14680": "Value Added With Expiration Time", - "14681": "Value Deleted With Expiration Time", - "14688": "Value Auto Deleted With Expiration Time", - "16384": "Add", - "16385": "Delete", - "16386": "Boot-time", - "16387": "Persistent", - "16388": "Not persistent", - "16389": "Block", - "16390": "Permit", - "16391": "Callout", - "16392": "MD5", - "16393": "SHA-1", - "16394": "SHA-256", - "16395": "AES-GCM 128", - "16396": "AES-GCM 192", - "16397": "AES-GCM 256", - "16398": "DES", - "16399": "3DES", - "16400": "AES-128", - "16401": "AES-192", - "16402": "AES-256", - "16403": "Transport", - "16404": "Tunnel", - "16405": "Responder", - "16406": "Initiator", - "16407": "AES-GMAC 128", - "16408": "AES-GMAC 192", - "16409": "AES-GMAC 256", - "16416": "AuthNoEncap Transport", - "16896": "Enable WMI Account", - "16897": "Execute Method", - "16898": "Full Write", - "16899": "Partial Write", - "16900": "Provider Write", - "16901": "Remote Access", - "16902": "Subscribe", - "16903": "Publish", - }; - - // Trust Types - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4706 - var trustTypes = { - "1": "TRUST_TYPE_DOWNLEVEL", - "2": "TRUST_TYPE_UPLEVEL", - "3": "TRUST_TYPE_MIT", - "4": "TRUST_TYPE_DCE" - } - - // Trust Direction - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4706 - var trustDirection = { - "0": "TRUST_DIRECTION_DISABLED", - "1": "TRUST_DIRECTION_INBOUND", - "2": "TRUST_DIRECTION_OUTBOUND", - "3": "TRUST_DIRECTION_BIDIRECTIONAL" - } - - // Trust Attributes - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4706 - var trustAttributes = { - "0": "UNDEFINED", - "1": "TRUST_ATTRIBUTE_NON_TRANSITIVE", - "2": "TRUST_ATTRIBUTE_UPLEVEL_ONLY", - "4": "TRUST_ATTRIBUTE_QUARANTINED_DOMAIN", - "8": "TRUST_ATTRIBUTE_FOREST_TRANSITIVE", - "16": "TRUST_ATTRIBUTE_CROSS_ORGANIZATION", - "32": "TRUST_ATTRIBUTE_WITHIN_FOREST", - "64": "TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL", - "128": "TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION", - "512": "TRUST_ATTRIBUTE_CROSS_ORGANIZATION_NO_TGT_DELEGATION", - "1024": "TRUST_ATTRIBUTE_PIM_TRUST" - } - - // SDDL Ace Types - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4715 - // https://docs.microsoft.com/en-us/windows/win32/secauthz/ace-strings - // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/f4296d69-1c0f-491f-9587-a960b292d070 - var aceTypes = { - "A": "Access Allowed", - "D": "Access Denied", - "OA": "Object Access Allowed", - "OD": "Object Access Denied", - "AU": "System Audit", - "AL": "System Alarm", - "OU": "System Object Audit", - "OL": "System Object Alarm", - "ML": "System Mandatory Label", - "SP": "Central Policy ID" - } - - // SDDL Permissions - // https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4715 - // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/f4296d69-1c0f-491f-9587-a960b292d070 - var permissionDescription = { - "GA": "Generic All", - "GR": "Generic Read", - "GW": "Generic Write", - "GX": "Generic Execute", - "RC": "Read Permissions", - "SD": "Delete", - "WD": "Modify Permissions", - "WO": "Modify Owner", - "RP": "Read All Properties", - "WP": "Write All Properties", - "CC": "Create All Child Objects", - "DC": "Delete All Child Objects", - "LC": "List Contents", - "SW": "All Validated", - "LO": "List Object", - "DT": "Delete Subtree", - "CR": "All Extended Rights", - "FA": "File All Access", - "FR": "File Generic Read", - "FX": "FILE GENERIC EXECUTE", - "FW": "FILE GENERIC WRITE", - "KA": "KEY ALL ACCESS", - "KR": "KEY READ", - "KW": "KEY WRITE", - "KX": "KEY EXECUTE" - } - - // Known SIDs - // https://support.microsoft.com/en-au/help/243330/well-known-security-identifier"S-in-window"S-operating-systems - // https://docs.microsoft.com/en-us/windows/win32/secauthz/sid-strings - var accountSIDDescription = { - "AO": "Account operators", - "RU": "Alias to allow previous Windows 2000", - "AN": "Anonymous logon", - "AU": "Authenticated users", - "BA": "Built-in administrators", - "BG": "Built-in guests", - "BO": "Backup operators", - "BU": "Built-in users", - "CA": "Certificate server administrators", - "CG": "Creator group", - "CO": "Creator owner", - "DA": "Domain administrators", - "DC": "Domain computers", - "DD": "Domain controllers", - "DG": "Domain guests", - "DU": "Domain users", - "EA": "Enterprise administrators", - "ED": "Enterprise domain controllers", - "WD": "Everyone", - "PA": "Group Policy administrators", - "IU": "Interactively logged-on user", - "LA": "Local administrator", - "LG": "Local guest", - "LS": "Local service account", - "SY": "Local system", - "NU": "Network logon user", - "NO": "Network configuration operators", - "NS": "Network service account", - "PO": "Printer operators", - "PS": "Personal self", - "PU": "Power users", - "RS": "RAS servers group", - "RD": "Terminal server users", - "RE": "Replicator", - "RC": "Restricted code", - "SA": "Schema administrators", - "SO": "Server operators", - "SU": "Service logon user", - "S-1-0": "Null Authority", - "S-1-0-0": "Nobody", - "S-1-1": "World Authority", - "S-1-1-0": "Everyone", - "S-1-16-0": "Untrusted Mandatory Level", - "S-1-16-12288": "High Mandatory Level", - "S-1-16-16384": "System Mandatory Level", - "S-1-16-20480": "Protected Process Mandatory Level", - "S-1-16-28672": "Secure Process Mandatory Level", - "S-1-16-4096": "Low Mandatory Level", - "S-1-16-8192": "Medium Mandatory Level", - "S-1-16-8448": "Medium Plus Mandatory Level", - "S-1-2": "Local Authority", - "S-1-2-0": "Local", - "S-1-2-1": "Console Logon", - "S-1-3": "Creator Authority", - "S-1-3-0": "Creator Owner", - "S-1-3-1": "Creator Group", - "S-1-3-2": "Creator Owner Server", - "S-1-3-3": "Creator Group Server", - "S-1-3-4": "Owner Rights", - "S-1-4": "Non-unique Authority", - "S-1-5": "NT Authority", - "S-1-5-1": "Dialup", - "S-1-5-10": "Principal Self", - "S-1-5-11": "Authenticated Users", - "S-1-5-12": "Restricted Code", - "S-1-5-13": "Terminal Server Users", - "S-1-5-14": "Remote Interactive Logon", - "S-1-5-15": "This Organization", - "S-1-5-17": "This Organization", - "S-1-5-18": "Local System", - "S-1-5-19": "NT Authority", - "S-1-5-2": "Network", - "S-1-5-20": "NT Authority", - "S-1-5-3": "Batch", - "S-1-5-32-544": "Administrators", - "S-1-5-32-545": "Users", - "S-1-5-32-546": "Guests", - "S-1-5-32-547": "Power Users", - "S-1-5-32-548": "Account Operators", - "S-1-5-32-549": "Server Operators", - "S-1-5-32-550": "Print Operators", - "S-1-5-32-551": "Backup Operators", - "S-1-5-32-552": "Replicators", - "S-1-5-32-554": "Builtin\Pre-Windows 2000 Compatible Access", - "S-1-5-32-555": "Builtin\Remote Desktop Users", - "S-1-5-32-556": "Builtin\Network Configuration Operators", - "S-1-5-32-557": "Builtin\Incoming Forest Trust Builders", - "S-1-5-32-558": "Builtin\Performance Monitor Users", - "S-1-5-32-559": "Builtin\Performance Log Users", - "S-1-5-32-560": "Builtin\Windows Authorization Access Group", - "S-1-5-32-561": "Builtin\Terminal Server License Servers", - "S-1-5-32-562": "Builtin\Distributed COM Users", - "S-1-5-32-569": "Builtin\Cryptographic Operators", - "S-1-5-32-573": "Builtin\Event Log Readers", - "S-1-5-32-574": "Builtin\Certificate Service DCOM Access", - "S-1-5-32-575": "Builtin\RDS Remote Access Servers", - "S-1-5-32-576": "Builtin\RDS Endpoint Servers", - "S-1-5-32-577": "Builtin\RDS Management Servers", - "S-1-5-32-578": "Builtin\Hyper-V Administrators", - "S-1-5-32-579": "Builtin\Access Control Assistance Operators", - "S-1-5-32-580": "Builtin\Remote Management Users", - "S-1-5-32-582": "Storage Replica Administrators", - "S-1-5-4": "Interactive", - "S-1-5-5-X-Y": "Logon Session", - "S-1-5-6": "Service", - "S-1-5-64-10": "NTLM Authentication", - "S-1-5-64-14": "SChannel Authentication", - "S-1-5-64-21": "Digest Authentication", - "S-1-5-7": "Anonymous", - "S-1-5-8": "Proxy", - "S-1-5-80": "NT Service", - "S-1-5-80-0": "All Services", - "S-1-5-83-0": "NT Virtual Machine\Virtual Machines", - "S-1-5-9": "Enterprise Domain Controllers", - "S-1-5-90-0": "Windows Manager\Windows Manager Group" - } - - // Domain-specific SIDs - // https://support.microsoft.com/en-au/help/243330/well-known-security-identifiers-in-windows-operating-systems - var domainSpecificSID = { - "498": "Enterprise Read-only Domain Controllers", - "500": "Administrator", - "501": "Guest", - "502": "KRBTGT", - "512": "Domain Admins", - "513": "Domain Users", - "514": "Domain Guests", - "515": "Domain Computers", - "516": "Domain Controllers", - "517": "Cert Publishers", - "518": "Schema Admins", - "519": "Enterprise Admins", - "520": "Group Policy Creator Owners", - "521": "Read-only Domain Controllers", - "522": "Cloneable Domain Controllers", - "526": "Key Admins", - "527": "Enterprise Key Admins", - "553": "RAS and IAS Servers", - "571": "Allowed RODC Password Replication Group", - "572": "Denied RODC Password Replication Group" - } - - // Object Permission Flags - // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/7a53f60e-e730-4dfe-bbe9-b21b62eb790b - var permsFlags = [ - [0x80000000, 'Generic Read'], - [0x4000000, 'Generic Write'], - [0x20000000, 'Generic Execute'], - [0x10000000, 'Generic All'], - [0x02000000, 'Maximun Allowed'], - [0x01000000, 'Access System Security'], - [0x00100000, 'Syncronize'], - [0x00080000, 'Write Owner'], - [0x00040000, 'Write DACL'], - [0x00020000, 'Read Control'], - [0x00010000, 'Delete'] - ]; - - // https://docs.microsoft.com/en-us/windows/win32/secauthz/access-rights-and-access-masks - var accessMaskDescriptions = [ - [0x00000001, 'Create Child'], - [0x00000002, 'Delete Child'], - [0x00000004, 'List Contents'], - [0x00000008, 'SELF'], - [0x00000010, 'Read Property'], - [0x00000020, 'Write Property'], - [0x00000040, 'Delete Treee'], - [0x00000080, 'List Object'], - [0x00000100, 'Control Access'], - [0x00010000, 'DELETE'], - [0x00020000, 'READ_CONTROL'], - [0x00040000, 'WRITE_DAC'], - [0x00080000, 'WRITE_OWNER'], - [0x00100000, 'SYNCHRONIZE'], - [0x00F00000, 'STANDARD_RIGHTS_REQUIRED'], - [0x001F0000, 'STANDARD_RIGHTS_ALL'], - [0x0000FFFF, 'SPECIFIC_RIGHTS_ALL'], - [0x01000000, 'ADS_RIGHT_ACCESS_SYSTEM_SECURITY'], - [0x10000000, 'ADS_RIGHT_GENERIC_ALL'], - [0x20000000, 'ADS_RIGHT_GENERIC_EXECUTE'], - [0x40000000, 'ADS_RIGHT_GENERIC_WRITE'], - [0x80000000, 'ADS_RIGHT_GENERIC_READ'] - ]; - - // lookupMessageCode returns the string associated with the code. key should - // be the name of the field in evt containing the code (e.g. %%2313). - var lookupMessageCode = function (evt, key) { - var code = evt.Get(key); - if (!code) { - return; - } - code = code.replace("%%", ""); - return msobjsMessageTable[code]; - }; - - var addEventFields = function(evt){ - var code = evt.Get("event.code"); - if (!code) { - return; - } - var eventActionDescription = eventActionTypes[code][2]; - if (eventActionDescription) { - evt.Put("event.category", eventActionTypes[code][0]); - evt.Put("event.type", eventActionTypes[code][1]); - evt.Put("event.action", eventActionTypes[code][2]); - } - }; - - var addLogonType = function(evt) { - var code = evt.Get("winlog.event_data.LogonType"); - if (!code) { - return; - } - var descriptiveLogonType = logonTypes[code]; - if (descriptiveLogonType === undefined) { - return; - } - evt.Put("winlog.logon.type", descriptiveLogonType); - }; - - var addFailureCode = function(evt) { - var msg = lookupMessageCode(evt, "winlog.event_data.FailureReason"); - if (!msg) { - return; - } - evt.Put("winlog.logon.failure.reason", msg); - }; - - var addFailureStatus = function(evt) { - var code = evt.Get("winlog.event_data.Status"); - if (!code) { - return; - } - var descriptiveFailureStatus = logonFailureStatus[code]; - if (descriptiveFailureStatus === undefined) { - return; - } - evt.Put("winlog.logon.failure.status", descriptiveFailureStatus); - }; - - var addFailureSubStatus = function(evt) { - var code = evt.Get("winlog.event_data.SubStatus"); - if (!code) { - return; - } - var descriptiveFailureStatus = logonFailureStatus[code]; - if (descriptiveFailureStatus === undefined) { - return; - } - evt.Put("winlog.logon.failure.sub_status", descriptiveFailureStatus); - }; - - var addUACDescription = function(evt) { - var code = evt.Get("winlog.event_data.NewUacValue"); - if (!code) { - return; - } - var uacCode = parseInt(code); - var uacResult = []; - for (var i = 0; i < uacFlags.length; i++) { - if ((uacCode | uacFlags[i][0]) === uacCode) { - uacResult.push(uacFlags[i][1]); - } - } - if (uacResult) { - evt.Put("winlog.event_data.NewUACList", uacResult); - } - var uacList = evt.Get("winlog.event_data.UserAccountControl").replace(/\s/g, '').split("%%").filter(String); - if (!uacList) { - return; - } - evt.Put("winlog.event_data.UserAccountControl", uacList); - }; - - var addAuditInfo = function(evt) { - var subcategoryGuid = evt.Get("winlog.event_data.SubcategoryGuid").replace("{", '').replace("}", '').toUpperCase(); - if (!subcategoryGuid) { - return; - } - if (!auditDescription[subcategoryGuid]) { - return; - } - evt.Put("winlog.event_data.Category", auditDescription[subcategoryGuid][1]); - evt.Put("winlog.event_data.SubCategory", auditDescription[subcategoryGuid][0]); - var codedActions = evt.Get("winlog.event_data.AuditPolicyChanges").split(","); - var actionResults = []; - for (var j = 0; j < codedActions.length; j++) { - var actionCode = codedActions[j].replace("%%", '').replace(' ', ''); - actionResults.push(msobjsMessageTable[actionCode]); - } - evt.Put("winlog.event_data.AuditPolicyChangesDescription", actionResults); - }; - - var addTicketOptionsDescription = function(evt) { - var code = evt.Get("winlog.event_data.TicketOptions"); - if (!code) { - return; - } - var tktCode = parseInt(code, 16).toString(2); - var tktResult = []; - var tktCodeLen = tktCode.length; - for (var i = tktCodeLen; i >= 0; i--) { - if (tktCode[i] == 1) { - tktResult.push(ticketOptions[(32-tktCodeLen)+i]); - } - } - if (tktResult) { - evt.Put("winlog.event_data.TicketOptionsDescription", tktResult); - } - }; - - var addTicketEncryptionType = function(evt) { - var code = evt.Get("winlog.event_data.TicketEncryptionType"); - if (!code) { - return; - } - var encTypeCode = code.toLowerCase(); - evt.Put("winlog.event_data.TicketEncryptionTypeDescription", ticketEncryptionTypes[encTypeCode]); - }; - - var addTicketStatus = function(evt) { - var code = evt.Get("winlog.event_data.Status"); - if (!code) { - return; - } - evt.Put("winlog.event_data.StatusDescription", kerberosTktStatusCodes[code]); - }; - - var translateSID = function(sid){ - var translatedSID = accountSIDDescription[sid]; - if (translatedSID == undefined) { - if (/^S\-1\-5\-21/.test(sid)) { - var uid = sid.match(/[0-9]{1,5}$/g); - if (uid) { - translatedSID = domainSpecificSID[uid]; - } - } - } - if (translatedSID == undefined) { - translatedSID = sid; - } - return translatedSID; - } - - var translatePermissionMask = function(mask) { - if (!mask) { - return; - } - var permCode = parseInt(mask); - var permResult = []; - for (var i = 0; i < permsFlags.length; i++) { - if ((permCode | permsFlags[i][0]) === permCode) { - permResult.push(permsFlags[i][1]); - } - } - if (permResult) { - return permResult; - } else { - return mask; - } - }; - - var translateACL = function(dacl) { - var aceArray = dacl.split(";"); - var aceResult = []; - var aceType = aceArray[0]; - var acePerm = aceArray[2]; - var aceTrustedSid = aceArray[5]; - if (aceTrustedSid) { - aceResult['grantee'] = translateSID(aceTrustedSid); - } - if (aceType) { - aceResult['type'] = aceTypes[aceType]; - } - if (acePerm) { - if (/^0x/.test(acePerm)) { - var perms = translatePermissionMask(acePerm); - } - else { - var perms = [] - var permPairs = acePerm.match(/.{1,2}/g); - for ( var i = 0; i < permPairs.length; i ++) { - perms.push(permissionDescription[permPairs[i]]) - } - } - aceResult['perms'] = perms; - } - return aceResult; - }; - - var enrichSDDL = function(evt, sddl) { - var sddlStr = evt.Get(sddl); - if (!sddlStr) { - return; - } - var sdOwner = sddlStr.match(/^O\:[A-Z]{2}/g); - var sdGroup = sddlStr.match(/^G\:[A-Z]{2}/g); - var sdDacl = sddlStr.match(/(D:([A-Z]*(\(.*\))*))/g); - var sdSacl = sddlStr.match(/(S:([A-Z]*(\(.*\))*))?$/g); - if (sdOwner) { - evt.Put(sddl+"Owner", translateSID(sdOwner)); - } - if (sdGroup) { - evt.Put(sddl+"Group", translateSID(sdGroup)); - } - if (sdDacl) { - // Split each entry of the DACL - var daclList = (sdDacl[0]).match(/\([^*\)]*\)/g); - if (daclList) { - for (var i = 0; i < daclList.length; i++) { - var newDacl = translateACL(daclList[i].replace("(", '').replace(")", '')); - evt.Put(sddl+"Dacl"+i, newDacl['grantee']+" :"+newDacl['type']+" ("+newDacl['perms']+")"); - if ( newDacl['grantee'] === "Administrator" || newDacl['grantee'] === "Guest" || newDacl['grantee'] === "KRBTGT" ) { - evt.AppendTo('related.user', newDacl['grantee']); - } - } - } - } - if (sdSacl) { - // Split each entry of the SACL - var saclList = (sdSacl[0]).match(/\([^*\)]*\)/g); - if (saclList) { - for (var i = 0; i < saclList.length; i++) { - var newSacl = translateACL(saclList[i].replace("(", '').replace(")", '')); - evt.Put(sddl+"Sacl"+i, newSacl['grantee']+" :"+newSacl['type']+" ("+newSacl['perms']+")"); - if ( newSacl['grantee'] === "Administrator" || newSacl['grantee'] === "Guest" || newSacl['grantee'] === "KRBTGT" ) { - evt.AppendTo('related.user', newSacl['grantee']); - } - } - } - } - }; - - var translateAccessMask = function(mask) { - if (!mask) { - return; - } - var accessCode = parseInt(mask); - var accessResult = []; - for (var i = 0; i < accessMaskDescriptions.length; i++) { - if ((accessCode | accessMaskDescriptions[i][0]) === accessCode) { - accessResult.push(accessMaskDescriptions[i][1]); - } - } - if (accessResult) { - return accessResult; - } - }; - - var addSessionData = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.AccountName", to: "user.name"}, - {from: "winlog.event_data.AccountDomain", to: "user.domain"}, - {from: "winlog.event_data.ClientAddress", to: "source.ip", type: "ip"}, - {from: "winlog.event_data.ClientName", to: "source.domain"}, - {from: "winlog.event_data.LogonID", to: "winlog.logon.id"}, - ], - ignore_missing: true, - fail_on_error: false, - }) - .Add(function(evt) { - var user = evt.Get("winlog.event_data.AccountName"); - evt.AppendTo('related.user', user); - }) - .Add(function(evt) { - var ip = evt.Get("source.ip"); - if (ip) { - evt.Put('related.ip', ip); - } - }) - .Build(); - - var addServiceFields = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.ServiceName", to: "service.name"}, - ], - ignore_missing: true, - }) - .Add(function(evt) { - var code = evt.Get("winlog.event_data.ServiceType"); - if (!code) { - return; - } - evt.Put("service.type", serviceTypes[code]); - }) - .Build(); - - var addTrustInformation = new processor.Chain() - .Add(function(evt) { - var code = evt.Get("winlog.event_data.TdoType"); - if (!code) { - return; - } - evt.Put("winlog.trustType", trustTypes[code]); - code = evt.Get("winlog.event_data.TdoDirection"); - if (!code) { - return; - } - evt.Put("winlog.trustDirection", trustDirection[code]); - code = evt.Get("winlog.event_data.TdoAttributes"); - if (!code) { - return; - } - evt.Put("winlog.trustAttribute", trustAttributes[code]); - - }) - .Build(); - - var copyTargetUser = function(evt) { - var targetUserId = evt.Get("winlog.event_data.TargetUserSid"); - if (!targetUserId) targetUserId = evt.Get("winlog.event_data.TargetSid"); - if (targetUserId) { - if (evt.Get("user.id")) evt.Put("user.target.id", targetUserId); - else evt.Put("user.id", targetUserId); - } - var targetUserName = evt.Get("winlog.event_data.TargetUserName"); - if (targetUserName) { - if (targetUserName.indexOf('@')>0) { - targetUserName = targetUserName.split('@')[0]; - } - - evt.AppendTo("related.user", targetUserName); - if (evt.Get("user.name")) evt.Put("user.target.name", targetUserName); - else evt.Put("user.name", targetUserName); - } - - var targetUserDomain = evt.Get("winlog.event_data.TargetDomainName"); - if (targetUserDomain) { - if (evt.Get("user.domain")) evt.Put("user.target.domain", targetUserDomain); - else evt.Put("user.domain", targetUserDomain); - } - } - - var removeIfEmptyOrHyphen = function(evt, key) { - var val = evt.Get(key); - if (!val || val === "-") { - evt.Delete(key); - return true; - } - return false; - } - - var copyTargetUserToEffective = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.TargetUserSid", to: "user.effective.id"}, - {from: "winlog.event_data.TargetUserName", to: "user.effective.name"}, - {from: "winlog.event_data.TargetDomainName", to: "user.effective.domain"}, - ], - ignore_missing: true, - }) - .Add(function(evt) { - var user = evt.Get("winlog.event_data.TargetUserName"); - if (user) { - if (user.indexOf('@')>0) { - user = user.split('@')[0]; - evt.Put('user.effective.name', user); - } - } - }) - .Add(function(evt) { - if (!removeIfEmptyOrHyphen(evt, "user.effective.name")) { - evt.AppendTo("related.user", evt.Get("user.effective.name")); - } - removeIfEmptyOrHyphen(evt, "user.effective.domain"); - removeIfEmptyOrHyphen(evt, "user.effective.id"); - }) - .Build(); - - var copyTargetUserToTarget = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.TargetSid", to: "user.target.id"}, - {from: "winlog.event_data.TargetUserName", to: "user.target.name"}, - {from: "winlog.event_data.TargetDomainName", to: "user.target.domain"}, - ], - ignore_missing: true, - }) - .Add(function(evt) { - var user = evt.Get("winlog.event_data.TargetUserName"); - if (user) { - if (user.indexOf('@')>0) { - user = user.split('@')[0]; - evt.Put('user.target.name', user); - } - evt.AppendTo('related.user', user); - } - }) - .Add(function(evt) { - if (!removeIfEmptyOrHyphen(evt, "user.target.name")) { - evt.AppendTo("related.user", evt.Get("user.target.name")); - } - removeIfEmptyOrHyphen(evt, "user.target.domain"); - removeIfEmptyOrHyphen(evt, "user.target.id"); - }) - .Build(); - - - var copyMemberToUser = function(evt) { - var member = evt.Get("winlog.event_data.MemberName"); - if (!member) { - return; - } - - var userName = member.split(',')[0].replace('CN=', '').replace('cn=', ''); - - evt.AppendTo("related.user", userName); - evt.Put("user.target.name", userName); - - var domainName = member.split(',')[3]; - if (domainName) { - evt.Put("user.target.domain", domainName.replace('DC=', '').replace('dc=', '')); - } - } - - var copyTargetUserToGroup = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.TargetUserSid", to: "group.id"}, - {from: "winlog.event_data.TargetSid", to: "group.id"}, - {from: "winlog.event_data.TargetUserName", to: "group.name"}, - {from: "winlog.event_data.TargetDomainName", to: "group.domain"}, - ], - ignore_missing: true, - }).Add(function(evt) { - if (!evt.Get("user.target")) return; - evt.Put("user.target.group.id", evt.Get("group.id")); - evt.Put("user.target.group.name", evt.Get("group.name")); - evt.Put("user.target.group.domain", evt.Get("group.domain")); - }) - .Build(); - - var copyTargetUserToComputerObject = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.TargetSid", to: "winlog.computerObject.id"}, - {from: "winlog.event_data.TargetUserName", to: "winlog.computerObject.name"}, - {from: "winlog.event_data.TargetDomainName", to: "winlog.computerObject.domain"}, - ], - ignore_missing: true, - }) - .Build(); - - var copyTargetUserLogonId = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.TargetLogonId", to: "winlog.logon.id"}, - ], - ignore_missing: true, - }) - .Build(); - - var copySubjectUser = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.SubjectUserSid", to: "user.id"}, - {from: "winlog.event_data.SubjectUserName", to: "user.name"}, - {from: "winlog.event_data.SubjectDomainName", to: "user.domain"}, - ], - ignore_missing: true, - }) - .Add(function(evt) { - var user = evt.Get("winlog.event_data.SubjectUserName"); - evt.AppendTo('related.user', user); - }) - .Build(); - - var copySubjectUserFromUserData = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.user_data.SubjectUserSid", to: "user.id"}, - {from: "winlog.user_data.SubjectUserName", to: "user.name"}, - {from: "winlog.user_data.SubjectDomainName", to: "user.domain"}, - ], - ignore_missing: true, - }) - .Add(function(evt) { - var user = evt.Get("winlog.user_data.SubjectUserName"); - evt.AppendTo('related.user', user); - }) - .Build(); - - var copySubjectUserLogonId = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.SubjectLogonId", to: "winlog.logon.id"}, - ], - ignore_missing: true, - }) - .Build(); - - var copySubjectUserLogonIdFromUserData = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.user_data.SubjectLogonId", to: "winlog.logon.id"}, - ], - ignore_missing: true, - }) - .Build(); - - var renameCommonAuthFields = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.ProcessId", to: "process.pid", type: "long"}, - {from: "winlog.event_data.ProcessName", to: "process.executable"}, - {from: "winlog.event_data.IpAddress", to: "source.ip", type: "ip"}, - {from: "winlog.event_data.IpPort", to: "source.port", type: "long"}, - {from: "winlog.event_data.WorkstationName", to: "source.domain"}, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(function(evt) { - var name = evt.Get("process.name"); - if (name) { - return; - } - var exe = evt.Get("process.executable"); - if (!exe) { - return; - } - evt.Put("process.name", path.basename(exe)); - }) - .Add(function(evt) { - var ip = evt.Get("source.ip"); - if (ip) { - evt.Put('related.ip', ip); - } - }) - .Build(); - - var renameNewProcessFields = new processor.Chain() - .Convert({ - fields: [ - {from: "winlog.event_data.NewProcessId", to: "process.pid", type: "long"}, - {from: "winlog.event_data.NewProcessName", to: "process.executable"}, - {from: "winlog.event_data.ParentProcessName", to: "process.parent.executable"} - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(function(evt) { - var name = evt.Get("process.name"); - if (name) { - return; - } - var exe = evt.Get("process.executable"); - if (!exe) { - return; - } - evt.Put("process.name", path.basename(exe)); - }) - .Add(function(evt) { - var name = evt.Get("process.parent.name"); - if (name) { - return; - } - var exe = evt.Get("process.parent.executable"); - if (!exe) { - return; - } - evt.Put("process.parent.name", path.basename(exe)); - }) - .Add(function(evt) { - var cl = evt.Get("winlog.event_data.CommandLine"); - if (!cl) { - return; - } - evt.Put("process.args", windows.splitCommandLine(cl)); - evt.Put("process.command_line", cl); - }) - .Build(); - - // Handles 4634 and 4647. - var logoff = new processor.Chain() - .Add(copyTargetUser) - .Add(copyTargetUserLogonId) - .Add(addLogonType) - .Add(addEventFields) - .Build(); - - // Handles both 4624 - var logonSuccess = new processor.Chain() - .Add(copyTargetUser) - .Add(copyTargetUserLogonId) - .Add(addLogonType) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Add(function(evt) { - var user = evt.Get("winlog.event_data.SubjectUserName"); - if (user) { - var res = /^-$/.test(user); - if (!res) { - evt.AppendTo('related.user', user); - } - } - }) - .Build(); - - // Handles both 4648 - var event4648 = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Add(copyTargetUserToEffective) - .Add(function(evt) { - var user = evt.Get("winlog.event_data.SubjectUserName"); - if (user) { - var res = /^-$/.test(user); - if (!res) { - evt.AppendTo('related.user', user); - } - } - }) - .Build(); - - var event4625 = new processor.Chain() - .Add(copyTargetUser) - .Add(copySubjectUserLogonId) - .Add(addLogonType) - .Add(addFailureCode) - .Add(addFailureStatus) - .Add(addFailureSubStatus) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Build(); - - var event4672 = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(function(evt) { - var privs = evt.Get("winlog.event_data.PrivilegeList"); - if (!privs) { - return; - } - evt.Put("winlog.event_data.PrivilegeList", privs.split(/\s+/)); - }) - .Add(addEventFields) - .Build(); - - var event4688 = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameNewProcessFields) - .Add(copyTargetUserToEffective) - .Add(addEventFields) - .Build(); - - var event4689 = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Build(); - - var event4697 = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameCommonAuthFields) - .Add(addServiceFields) - .Add(addEventFields) - .Build(); - - var userMgmtEvts = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameCommonAuthFields) - .Add(addUACDescription) - .Add(addEventFields) - .Add(copyTargetUserToTarget) - .Build(); - - var userRenamed = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(addEventFields) - .Add(function(evt) { - var userNew = evt.Get("winlog.event_data.NewTargetUserName"); - evt.AppendTo('related.user', userNew); - var userOld = evt.Get("winlog.event_data.OldTargetUserName"); - evt.AppendTo('related.user', userOld); - if (userOld) { - evt.Put('user.target.name', userOld); - } - if (userNew) { - evt.Put('user.changes.name', userNew); - } - }) - .Build(); - - var groupMgmtEvts = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(copyMemberToUser) - .Add(copyTargetUserToGroup) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Build(); - - var auditLogCleared = new processor.Chain() - .Add(copySubjectUserFromUserData) - .Add(copySubjectUserLogonIdFromUserData) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Build(); - - var auditChanged = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameCommonAuthFields) - .Add(addAuditInfo) - .Add(addEventFields) - .Build(); - - var auditLogMgmt = new processor.Chain() - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Build(); - - var computerMgmtEvts = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(copyTargetUserToComputerObject) - .Add(renameCommonAuthFields) - .Add(addUACDescription) - .Add(addEventFields) - .Add(function(evt) { - var privs = evt.Get("winlog.event_data.PrivilegeList"); - if (!privs) { - return; - } - evt.Put("winlog.event_data.PrivilegeList", privs.split(/\s+/)); - }) - .Build(); - - var sessionEvts = new processor.Chain() - .Add(addSessionData) - .Add(addEventFields) - .Build(); - - var event4964 = new processor.Chain() - .Add(copyTargetUser) - .Add(copyTargetUserLogonId) - .Add(addEventFields) - .Build(); - - var kerberosTktEvts = new processor.Chain() - .Add(copyTargetUser) - .Add(renameCommonAuthFields) - .Add(addTicketOptionsDescription) - .Add(addTicketEncryptionType) - .Add(addTicketStatus) - .Add(addEventFields) - .Add(function(evt) { - var ip = evt.Get("source.ip"); - if (ip) { - if (/::ffff:/.test(ip)) { - evt.Put("source.ip", ip.replace("::ffff:", "")); - evt.Put("related.ip", ip.replace("::ffff:", "")); - } - } - }) - .Build(); - - var event4776 = new processor.Chain() - .Add(copyTargetUser) - .Add(addFailureStatus) - .Add(addEventFields) - .Build(); - - var scheduledTask = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(addEventFields) - .Build(); - - var sensitivePrivilege = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Add(function(evt) { - var privs = evt.Get("winlog.event_data.PrivilegeList"); - if (!privs) { - return; - } - evt.Put("winlog.event_data.PrivilegeList", privs.split(/\s+/)); - }) - .Add(function(evt){ - var accessMask = evt.Get("winlog.event_data.AccessMask"); - if (!accessMask) { - return; - } - var accessDescriptions = translateAccessMask(accessMask); - if (!accessDescriptions) { - return; - } - if (accessDescriptions.length > 0) { - evt.Put("winlog.event_data.AccessMaskDescription", accessDescriptions); - } - }) - .Add(function(evt){ - var listNames = ["AccessList", "AccessMask"] - for (var i = 0; i < listNames.length; i++) { - var listContents = evt.Get("winlog.event_data." + listNames[i]) - if (!listContents) { - continue; - } - var listDescription = evt.Get("winlog.event_data." + listNames[i] + "Description") - if (listDescription) { - continue; - } - - var items = listContents.replace(/\s+/g, '').split("%%").filter(String); - evt.Put("winlog.event_data." + listNames[i], items) - var results = []; - for (var j = 0; j < items.length; j++) { - var description = msobjsMessageTable[items[j]]; - if (description === undefined) { - continue; - } - results.push(description); - } - evt.Put("winlog.event_data." + listNames[i] + "Description", results); - } - }) - - .Build(); - - var trustDomainMgmtEvts = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(addEventFields) - .Add(addTrustInformation) - .Build(); - - var policyChange = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(addEventFields) - .Build(); - - var objectPolicyChange = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Add(copyTargetUserToTarget) - .Add(function(evt) { - var oldSd = evt.Get("winlog.event_data.OldSd"); - var newSd = evt.Get("winlog.event_data.NewSd"); - if (oldSd) { - enrichSDDL(evt, "winlog.event_data.OldSd"); - } - if (newSd) { - enrichSDDL(evt, "winlog.event_data.NewSd"); - } - }) - .Build(); - - var genericAuditChange = new processor.Chain() - .Add(addEventFields) - .Build(); - - var event4908 = new processor.Chain() - .Add(addEventFields) - .Add(function(evt) { - var sids = evt.Get("winlog.event_data.SidList"); - if (!sids) { - return; - } - var sidList = sids.split(/\s+/); - evt.Put("winlog.event_data.SidList", sids.split(/\s+/)); - var sidListDesc = []; - for (var i = 0; i < sidList.length; i++) { - var sidTemp = sidList[i].replace("%", "").replace("{", "").replace("}", "").replace(" ",""); - if (sidTemp) { - sidListDesc.push(translateSID(sidTemp)); - } - } - evt.Put("winlog.event_data.SidListDesc", sidListDesc); - }) - .Build(); - - var securityEventSource = new processor.Chain() - .Add(copySubjectUser) - .Add(copySubjectUserLogonId) - .Add(renameCommonAuthFields) - .Add(addEventFields) - .Build(); - - return { - - // 1100 - The event logging service has shut down. - 1100: auditLogMgmt.Run, - - // 1102 - The audit log was cleared. - 1102: auditLogCleared.Run, - - // 1104 - The security log is now full. - 1104: auditLogMgmt.Run, - - // 1105 - Event log automatic backup. - 1105: auditLogMgmt.Run, - - // 1108 - The event logging service encountered an error while processing an incoming event published from %1 - 1108: auditLogMgmt.Run, - - // 4624 - An account was successfully logged on. - 4624: logonSuccess.Run, - - // 4625 - An account failed to log on. - 4625: event4625.Run, - - // 4634 - An account was logged off. - 4634: logoff.Run, - - // 4647 - User initiated logoff. - 4647: logoff.Run, - - // 4648 - A logon was attempted using explicit credentials. - 4648: event4648.Run, - - // 4670 - Permissions on an object were changed. - 4670: objectPolicyChange.Run, - - // 4672 - Special privileges assigned to new logon. - 4672: event4672.Run, - - // 4673 - A privileged service was called. - 4673: sensitivePrivilege.Run, - - // 4674 - An operation was attempted on a privileged object. - 4674: sensitivePrivilege.Run, - - // 4688 - A new process has been created. - 4688: event4688.Run, - - // 4689 - A process has exited. - 4689: event4689.Run, - - // 4697 - A service was installed in the system. - 4697: event4697.Run, - - // 4698 - A scheduled task was created. - 4698: scheduledTask.Run, - - // 4699 - A scheduled task was deleted. - 4699: scheduledTask.Run, - - // 4700 - A scheduled task was enabled. - 4700: scheduledTask.Run, - - // 4701 - A scheduled task was disabled. - 4701: scheduledTask.Run, - - // 4702 - A scheduled task was updated. - 4702: scheduledTask.Run, - - // 4706 - A new trust was created to a domain. - 4706: trustDomainMgmtEvts.Run, - - // 4707 - A trust to a domain was removed. - 4707: trustDomainMgmtEvts.Run, - - // 4713 - Kerberos policy was changed. - 4713: policyChange.Run, - - // 4716 - Trusted domain information was modified. - 4716: trustDomainMgmtEvts.Run, - - // 4717 - System security access was granted to an account. - 4717: policyChange.Run, - - // 4718 - System security access was removed from an account. - 4718: policyChange.Run, - - // 4719 - System audit policy was changed. - 4719: auditChanged.Run, - - // 4720 - A user account was created - 4720: userMgmtEvts.Run, - - // 4722 - A user account was enabled - 4722: userMgmtEvts.Run, - - // 4723 - An attempt was made to change an account's password - 4723: userMgmtEvts.Run, - - // 4724 - An attempt was made to reset an account's password - 4724: userMgmtEvts.Run, - - // 4725 - A user account was disabled. - 4725: userMgmtEvts.Run, - - // 4726 - An user account was deleted. - 4726: userMgmtEvts.Run, - - // 4727 - A security-enabled global group was created. - 4727: groupMgmtEvts.Run, - - // 4728 - A member was added to a security-enabled global group. - 4728: groupMgmtEvts.Run, - - // 4729 - A member was removed from a security-enabled global group. - 4729: groupMgmtEvts.Run, - - // 4730 - A security-enabled global group was deleted. - 4730: groupMgmtEvts.Run, - - // 4731 - A security-enabled local group was created. - 4731: groupMgmtEvts.Run, - - // 4732 - A member was added to a security-enabled local group. - 4732: groupMgmtEvts.Run, - - // 4733 - A member was removed from a security-enabled local group. - 4733: groupMgmtEvts.Run, - - // 4734 - A security-enabled local group was deleted. - 4734: groupMgmtEvts.Run, - - // 4735 - A security-enabled local group was changed. - 4735: groupMgmtEvts.Run, - - // 4737 - A security-enabled global group was changed. - 4737: groupMgmtEvts.Run, - - // 4739 - A security-enabled global group was changed. - 4739: policyChange.Run, - - // 4738 - An user account was changed. - 4738: userMgmtEvts.Run, - - // 4740 - An account was locked out - 4740: userMgmtEvts.Run, - - // 4741 - A computer account was created. - 4741: computerMgmtEvts.Run, - - // 4742 - A computer account was changed. - 4742: computerMgmtEvts.Run, - - // 4743 - A computer account was deleted. - 4743: computerMgmtEvts.Run, - - // 4744 - A security-disabled local group was created. - 4744: groupMgmtEvts.Run, - - // 4745 - A security-disabled local group was changed. - 4745: groupMgmtEvts.Run, - - // 4746 - A member was added to a security-disabled local group. - 4746: groupMgmtEvts.Run, - - // 4747 - A member was removed from a security-disabled local group. - 4747: groupMgmtEvts.Run, - - // 4748 - A security-disabled local group was deleted. - 4748: groupMgmtEvts.Run, - - // 4749 - A security-disabled global group was created. - 4749: groupMgmtEvts.Run, - - // 4750 - A security-disabled global group was changed. - 4750: groupMgmtEvts.Run, - - // 4751 - A member was added to a security-disabled global group. - 4751: groupMgmtEvts.Run, - - // 4752 - A member was removed from a security-disabled global group. - 4752: groupMgmtEvts.Run, - - // 4753 - A security-disabled global group was deleted. - 4753: groupMgmtEvts.Run, - - // 4754 - A security-enabled universal group was created. - 4754: groupMgmtEvts.Run, - - // 4755 - A security-enabled universal group was changed. - 4755: groupMgmtEvts.Run, - - // 4756 - A member was added to a security-enabled universal group. - 4756: groupMgmtEvts.Run, - - // 4757 - A member was removed from a security-enabled universal group. - 4757: groupMgmtEvts.Run, - - // 4758 - A security-enabled universal group was deleted. - 4758: groupMgmtEvts.Run, - - // 4759 - A security-disabled universal group was created. - 4759: groupMgmtEvts.Run, - - // 4760 - A security-disabled universal group was changed. - 4760: groupMgmtEvts.Run, - - // 4761 - A member was added to a security-disabled universal group. - 4761: groupMgmtEvts.Run, - - // 4762 - A member was removed from a security-disabled universal group. - 4762: groupMgmtEvts.Run, - - // 4763 - A security-disabled global group was deleted. - 4763: groupMgmtEvts.Run, - - // 4764 - A group\'s type was changed. - 4764: groupMgmtEvts.Run, - - // 4767 - A user account was unlocked. - 4767: userMgmtEvts.Run, - - // 4768 - A Kerberos authentication ticket TGT was requested. - 4768: kerberosTktEvts.Run, - - // 4769 - A Kerberos service ticket was requested. - 4769: kerberosTktEvts.Run, - - // 4770 - A Kerberos service ticket was renewed. - 4770: kerberosTktEvts.Run, - - // 4771 - Kerberos pre-authentication failed. - 4771: kerberosTktEvts.Run, - - // 4776 - The computer attempted to validate the credentials for an account. - 4776: event4776.Run, - - // 4778 - A session was reconnected to a Window Station. - 4778: sessionEvts.Run, - - // 4779 - A session was disconnected from a Window Station. - 4779: sessionEvts.Run, - - // 4781 - The name of an account was changed. - 4781: userRenamed.Run, - - // 4798 - A user's local group membership was enumerated. - 4798: userMgmtEvts.Run, - - // 4799 - A security-enabled local group membership was enumerated. - 4799: groupMgmtEvts.Run, - - // 4817 - Auditing settings on object were changed. - 4817: objectPolicyChange.Run, - - // 4902 - The Per-user audit policy table was created. - 4902: genericAuditChange.Run, - - // 4904 - An attempt was made to register a security event source. - 4904: securityEventSource.Run, - - // 4905 - An attempt was made to unregister a security event source. - 4905: securityEventSource.Run, - - // 4906 - The CrashOnAuditFail value has changed. - 4906: genericAuditChange.Run, - - // 4907 - Auditing settings on object were changed. - 4907: objectPolicyChange.Run, - - // 4908 - Special Groups Logon table modified. - 4908: event4908.Run, - - // 4912 - Per User Audit Policy was changed. - 4912: auditChanged.Run, - - // 4964 - Special groups have been assigned to a new logon. - 4964: event4964.Run, - - process: function(evt) { - var eventId = evt.Get("winlog.event_id"); - var processor = this[eventId]; - if (processor === undefined) { - return; - } - evt.Put("event.module", "security"); - processor(evt); - }, - }; -})(); - -function process(evt) { - return security.process(evt); -} diff --git a/x-pack/winlogbeat/module/security/ingest/security.yml b/x-pack/winlogbeat/module/security/ingest/security.yml new file mode 100644 index 000000000000..7681693f253c --- /dev/null +++ b/x-pack/winlogbeat/module/security/ingest/security.yml @@ -0,0 +1,3364 @@ +--- +description: Pipeline for Windows Security events +processors: + - set: + field: event.ingested + value: '{{_ingest.timestamp}}' + - convert: + field: event.code + type: string + ignore_missing: true + - script: + lang: painless + ignore_failure: false + tag: Set ECS categorization fields + description: Set ECS categorization fields + params: + "1100": + category: + - process + type: + - end + action: logging-service-shutdown + "1102": + category: + - iam + type: + - admin + - change + action: audit-log-cleared + "1104": + category: + - iam + type: + - admin + action: logging-full + "1105": + category: + - iam + type: + - admin + action: auditlog-archieved + "1108": + category: + - iam + type: + - admin + action: logging-processing-error + "4610": + category: + - configuration + type: + - access + action: authentication-package-loaded + "4611": + category: + - configuration + type: + - change + action: trusted-logon-process-registered + "4614": + category: + - configuration + type: + - access + action: notification-package-loaded + "4616": + category: + - configuration + type: + - change + action: system-time-changed + "4622": + category: + - configuration + type: + - access + action: security-package-loaded + "4624": + category: + - authentication + type: + - start + action: logged-in + "4625": + category: + - authentication + type: + - start + action: logon-failed + "4634": + category: + - authentication + type: + - end + action: logged-out + "4647": + category: + - authentication + type: + - end + action: logged-out + "4648": + category: + - authentication + type: + - start + action: logged-in-explicit + "4657": + category: + - registry + - configuration + type: + - change + action: registry-value-modified + "4670": + category: + - iam + - configuration + type: + - admin + - change + action: permissions-changed + "4672": + category: + - iam + type: + - admin + action: logged-in-special + "4673": + category: + - iam + type: + - admin + action: privileged-service-called + "4674": + category: + - iam + type: + - admin + action: privileged-operation + "4688": + category: + - process + type: + - start + action: created-process + "4689": + category: + - process + type: + - end + action: exited-process + "4697": + category: + - iam + - configuration + type: + - admin + - change + action: service-installed + "4698": + category: + - iam + - configuration + type: + - creation + - admin + action: scheduled-task-created + "4699": + category: + - iam + - configuration + type: + - deletion + - admin + action: scheduled-task-deleted + "4700": + category: + - iam + - configuration + type: + - change + - admin + action: scheduled-task-enabled + "4701": + category: + - iam + - configuration + type: + - change + - admin + action: scheduled-task-disabled + "4702": + category: + - iam + - configuration + type: + - change + - admin + action: scheduled-task-updated + "4706": + category: + - configuration + type: + - creation + action: domain-trust-added + "4707": + category: + - configuration + type: + - deletion + action: domain-trust-removed + "4713": + category: + - configuration + type: + - change + action: kerberos-policy-changed + "4714": + category: + - configuration + type: + - change + action: encrypted-data-recovery-policy-changed + "4715": + category: + - configuration + type: + - change + action: object-audit-policy-changed + "4716": + category: + - configuration + type: + - change + action: trusted-domain-information-changed + "4717": + category: + - iam + - configuration + type: + - admin + - change + action: system-security-access-granted + "4718": + category: + - iam + - configuration + type: + - admin + - deletion + action: system-security-access-removed + "4719": + category: + - iam + - configuration + type: + - admin + - change + action: changed-audit-config + "4720": + category: + - iam + type: + - user + - creation + action: added-user-account + "4722": + category: + - iam + type: + - user + - change + action: enabled-user-account + "4723": + category: + - iam + type: + - user + - change + action: changed-password + "4724": + category: + - iam + type: + - user + - change + action: reset-password + "4725": + category: + - iam + type: + - user + - deletion + action: disabled-user-account + "4726": + category: + - iam + type: + - user + - deletion + action: deleted-user-account + "4727": + category: + - iam + type: + - group + - creation + action: added-group-account + "4728": + category: + - iam + type: + - group + - change + action: added-member-to-group + "4729": + category: + - iam + type: + - group + - change + action: removed-member-from-group + "4730": + category: + - iam + type: + - group + - deletion + action: deleted-group-account + "4731": + category: + - iam + type: + - group + - creation + action: added-group-account + "4732": + category: + - iam + type: + - group + - change + action: added-member-to-group + "4733": + category: + - iam + type: + - group + - change + action: removed-member-from-group + "4734": + category: + - iam + type: + - group + - deletion + action: deleted-group-account + "4735": + category: + - iam + type: + - group + - change + action: modified-group-account + "4737": + category: + - iam + type: + - group + - change + action: modified-group-account + "4738": + category: + - iam + type: + - user + - change + action: modified-user-account + "4739": + category: + - configuration + type: + - change + action: domain-policy-changed + "4740": + category: + - iam + type: + - user + - change + action: locked-out-user-account + "4741": + category: + - iam + type: + - creation + - admin + action: added-computer-account + "4742": + category: + - iam + type: + - change + - admin + action: changed-computer-account + "4743": + category: + - iam + type: + - deletion + - admin + action: deleted-computer-account + "4744": + category: + - iam + type: + - group + - creation + action: added-distribution-group-account + "4745": + category: + - iam + type: + - group + - change + action: changed-distribution-group-account + "4746": + category: + - iam + type: + - group + - change + action: added-member-to-distribution-group + "4747": + category: + - iam + type: + - group + - change + action: removed-member-from-distribution-group + "4748": + category: + - iam + type: + - group + - deletion + action: deleted-distribution-group-account + "4749": + category: + - iam + type: + - group + - creation + action: added-distribution-group-account + "4750": + category: + - iam + type: + - group + - change + action: changed-distribution-group-account + "4751": + category: + - iam + type: + - group + - change + action: added-member-to-distribution-group + "4752": + category: + - iam + type: + - group + - change + action: removed-member-from-distribution-group + "4753": + category: + - iam + type: + - group + - deletion + action: deleted-distribution-group-account + "4754": + category: + - iam + type: + - group + - creation + action: added-group-account + "4755": + category: + - iam + type: + - group + - change + action: modified-group-account + "4756": + category: + - iam + type: + - group + - change + action: added-member-to-group + "4757": + category: + - iam + type: + - group + - change + action: removed-member-from-group + "4758": + category: + - iam + type: + - group + - deletion + action: deleted-group-account + "4759": + category: + - iam + type: + - group + - creation + action: added-distribution-group-account + "4760": + category: + - iam + type: + - group + - change + action: changed-distribution-group-account + "4761": + category: + - iam + type: + - group + - change + action: added-member-to-distribution-group + "4762": + category: + - iam + type: + - group + - change + action: removed-member-from-distribution-group + "4763": + category: + - iam + type: + - group + - deletion + action: deleted-distribution-group-account + "4764": + category: + - iam + type: + - group + - change + action: type-changed-group-account + "4767": + category: + - iam + type: + - user + - change + action: unlocked-user-account + "4768": + category: + - authentication + type: + - start + action: kerberos-authentication-ticket-requested + "4769": + category: + - authentication + type: + - start + action: kerberos-service-ticket-requested + "4770": + category: + - authentication + type: + - start + action: kerberos-service-ticket-renewed + "4771": + category: + - authentication + type: + - start + action: kerberos-preauth-failed + "4776": + category: + - authentication + type: + - start + action: credential-validated + "4778": + category: + - authentication + - session + type: + - start + action: session-reconnected + "4779": + category: + - authentication + - session + type: + - end + action: session-disconnected + "4781": + category: + - iam + type: + - user + - change + action: renamed-user-account + "4798": + category: + - iam + type: + - user + - info + action: group-membership-enumerated + "4799": + category: + - iam + type: + - group + - info + action: user-member-enumerated + "4817": + category: + - iam + - configuration + type: + - admin + - change + action: object-audit-changed + "4902": + category: + - iam + - configuration + type: + - admin + - creation + action: user-audit-policy-created + "4904": + category: + - iam + - configuration + type: + - admin + - change + action: security-event-source-added + "4905": + category: + - iam + - configuration + type: + - admin + - deletion + action: security-event-source-removed + "4906": + category: + - iam + - configuration + type: + - admin + - change + action: crash-on-audit-changed + "4907": + category: + - iam + - configuration + type: + - admin + - change + action: audit-setting-changed + "4908": + category: + - iam + - configuration + type: + - admin + - change + action: special-group-table-changed + "4912": + category: + - iam + - configuration + type: + - admin + - change + action: per-user-audit-policy-changed + "4950": + category: + - configuration + type: + - change + action: windows-firewall-setting-changed + "4954": + category: + - configuration + type: + - change + action: windows-firewall-group-policy-changed + "4964": + category: + - iam + type: + - admin + - group + action: logged-in-special + "5024": + category: + - process + type: + - start + action: windows-firewall-service-started + "5025": + category: + - process + type: + - end + action: windows-firewall-service-stopped + "5033": + category: + - driver + type: + - start + action: windows-firewall-driver-started + "5034": + category: + - driver + type: + - end + action: windows-firewall-driver-stopped + "5037": + category: + - driver + type: + - end + action: windows-firewall-driver-error + source: |- + if (ctx?.event?.code == null || params.get(ctx.event.code) == null) { + return; + } + def hm = new HashMap(params.get(ctx.event.code)); + hm.forEach((k, v) -> ctx.event[k] = v); + - script: + lang: painless + ignore_failure: false + tag: Set Logon Type + description: Set Logon Type + # Logon Types + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/basic-audit-logon-events + params: + "2": Interactive + "3": Network + "4": Batch + "5": Service + "7": Unlock + "8": NetworkCleartext + "9": NewCredentials + "10": RemoteInteractive + "11": CachedInteractive + source: |- + if (ctx?.winlog?.event_data?.LogonType == null) { + return; + } + def t = params.get(ctx.winlog.event_data.LogonType); + if (t == null) { + return; + } + if (ctx?.winlog?.logon == null ) { + Map map = new HashMap(); + ctx.winlog.put("logon", map); + } + ctx.winlog.logon.put("type", t) + - script: + lang: painless + ignore_failure: false + tag: Set User Account Control + description: Set User Account Control + # User Account Control Attributes Table + # https://support.microsoft.com/es-us/help/305144/how-to-use-useraccountcontrol-to-manipulate-user-account-properties + params: + "0x00000001": SCRIPT + "0x00000002": ACCOUNTDISABLE + "0x00000008": HOMEDIR_REQUIRED + "0x00000010": LOCKOUT + "0x00000020": PASSWD_NOTREQD + "0x00000040": PASSWD_CANT_CHANGE + "0x00000080": ENCRYPTED_TEXT_PWD_ALLOWED + "0x00000100": TEMP_DUPLICATE_ACCOUNT + "0x00000200": NORMAL_ACCOUNT + "0x00000800": INTERDOMAIN_TRUST_ACCOUNT + "0x00001000": WORKSTATION_TRUST_ACCOUNT + "0x00002000": SERVER_TRUST_ACCOUNT + "0x00010000": DONT_EXPIRE_PASSWORD + "0x00020000": MNS_LOGON_ACCOUNT + "0x00040000": SMARTCARD_REQUIRED + "0x00080000": TRUSTED_FOR_DELEGATION + "0x00100000": NOT_DELEGATED + "0x00200000": USE_DES_KEY_ONLY + "0x00400000": DONT_REQ_PREAUTH + "0x00800000": PASSWORD_EXPIRED + "0x01000000": TRUSTED_TO_AUTH_FOR_DELEGATION + "0x04000000": PARTIAL_SECRETS_ACCOUNT + source: |- + if (ctx?.winlog?.event_data?.NewUacValue == null) { + return; + } + Long newUacValue = Long.decode(ctx.winlog.event_data.NewUacValue); + ArrayList uacResult = new ArrayList(); + for (entry in params.entrySet()) { + Long flag = Long.decode(entry.getKey()); + if ((newUacValue.longValue() & flag.longValue()) == flag.longValue()) { + uacResult.add(entry.getValue()); + } + } + if (uacResult.length == 0) { + return; + } + ctx.winlog.event_data.put("NewUACList", uacResult); + if (ctx?.winlog?.event_data?.UserAccountControl == null) { + return; + } + ArrayList uac_array = new ArrayList(); + for (elem in ctx.winlog.event_data.UserAccountControl.splitOnToken("%%")) { + if (elem.trim().length() > 0) { + uac_array.add(elem.trim()); + } + } + ctx.winlog.event_data.UserAccountControl = uac_array; + - script: + lang: painless + ignore_failure: false + tag: Set Kerberos Ticket Options + description: Set Kerberos Ticket Options + # Kerberos TGT and TGS Ticket Options + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4769 + params: + "0x40000000": Forwardable + "0x20000000": Forwarded + "0x10000000": Proxiable + "0x08000000": Proxy + "0x04000000": Allow-postdate + "0x02000000": Postdated + "0x01000000": Invalid + "0x00800000": Renewable + "0x00400000": Initial + "0x00200000": Pre-authent + "0x00100000": Opt-hardware-auth + "0x00080000": Transited-policy-checked + "0x00040000": Ok-as-delegate + "0x00020000": Request-anonymous + "0x00010000": Name-canonicalize + "0x00000020": Disable-transited-check + "0x00000010": Renewable-ok + "0x00000008": Enc-tkt-in-skey + "0x00000002": Renew + "0x00000001": Validate + source: |- + if (ctx?.winlog?.event_data?.TicketOptions == null) { + return; + } + Long tOpts = Long.decode(ctx.winlog.event_data.TicketOptions); + ArrayList tDescs = new ArrayList(); + for (entry in params.entrySet()) { + Long flag = Long.decode(entry.getKey()); + if ((tOpts.longValue() & flag.longValue()) == flag.longValue()) { + tDescs.add(entry.getValue()); + } + } + if (tDescs.length == 0) { + return; + } + ctx.winlog.event_data.put("TicketOptionsDescription", tDescs); + - script: + lang: painless + ignore_failure: false + tag: Set Kerberos Encryption Types + description: Set Kerberos Encryption Types + # Kerberos Encryption Types + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 + params: + "0x1": DES-CBC-CRC + "0x3": DES-CBC-MD5 + "0x11": AES128-CTS-HMAC-SHA1-96 + "0x12": AES256-CTS-HMAC-SHA1-96 + "0x17": RC4-HMAC + "0x18": RC4-HMAC-EXP + "0xffffffff": FAIL + source: |- + if (ctx?.winlog?.event_data?.TicketEncryptionType == null) { + return; + } + ctx.winlog.event_data.put("TicketEncryptionTypeDescription", + params[ctx.winlog.event_data.TicketEncryptionType.toLowerCase()]) + - script: + lang: painless + ignore_failure: false + tag: Set Kerberos Ticket Status Codes + # Kerberos Result Status Codes + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4768 + description: Set Kerberos Ticket Status Codes + params: + "0x0": KDC_ERR_NONE + "0x1": KDC_ERR_NAME_EXP + "0x2": KDC_ERR_SERVICE_EXP + "0x3": KDC_ERR_BAD_PVNO + "0x4": KDC_ERR_C_OLD_MAST_KVNO + "0x5": KDC_ERR_S_OLD_MAST_KVNO + "0x6": KDC_ERR_C_PRINCIPAL_UNKNOWN + "0x7": KDC_ERR_S_PRINCIPAL_UNKNOWN + "0x8": KDC_ERR_PRINCIPAL_NOT_UNIQUE + "0x9": KDC_ERR_NULL_KEY + "0xA": KDC_ERR_CANNOT_POSTDATE + "0xB": KDC_ERR_NEVER_VALID + "0xC": KDC_ERR_POLICY + "0xD": KDC_ERR_BADOPTION + "0xE": KDC_ERR_ETYPE_NOTSUPP + "0xF": KDC_ERR_SUMTYPE_NOSUPP + "0x10": KDC_ERR_PADATA_TYPE_NOSUPP + "0x11": KDC_ERR_TRTYPE_NO_SUPP + "0x12": KDC_ERR_CLIENT_REVOKED + "0x13": KDC_ERR_SERVICE_REVOKED + "0x14": KDC_ERR_TGT_REVOKED + "0x15": KDC_ERR_CLIENT_NOTYET + "0x16": KDC_ERR_SERVICE_NOTYET + "0x17": KDC_ERR_KEY_EXPIRED + "0x18": KDC_ERR_PREAUTH_FAILED + "0x19": KDC_ERR_PREAUTH_REQUIRED + "0x1A": KDC_ERR_SERVER_NOMATCH + "0x1B": KDC_ERR_MUST_USE_USER2USER + "0x1F": KRB_AP_ERR_BAD_INTEGRITY + "0x20": KRB_AP_ERR_TKT_EXPIRED + "0x21": KRB_AP_ERR_TKT_NYV + "0x22": KRB_AP_ERR_REPEAT + "0x23": KRB_AP_ERR_NOT_US + "0x24": KRB_AP_ERR_BADMATCH + "0x25": KRB_AP_ERR_SKEW + "0x26": KRB_AP_ERR_BADADDR + "0x27": KRB_AP_ERR_BADVERSION + "0x28": KRB_AP_ERR_MSG_TYPE + "0x29": KRB_AP_ERR_MODIFIED + "0x2A": KRB_AP_ERR_BADORDER + "0x2C": KRB_AP_ERR_BADKEYVER + "0x2D": KRB_AP_ERR_NOKEY + "0x2E": KRB_AP_ERR_MUT_FAIL + "0x2F": KRB_AP_ERR_BADDIRECTION + "0x30": KRB_AP_ERR_METHOD + "0x31": KRB_AP_ERR_BADSEQ + "0x32": KRB_AP_ERR_INAPP_CKSUM + "0x33": KRB_AP_PATH_NOT_ACCEPTED + "0x34": KRB_ERR_RESPONSE_TOO_BIG + "0x3C": KRB_ERR_GENERIC + "0x3D": KRB_ERR_FIELD_TOOLONG + "0x3E": KDC_ERR_CLIENT_NOT_TRUSTED + "0x3F": KDC_ERR_KDC_NOT_TRUSTED + "0x40": KDC_ERR_INVALID_SIG + "0x41": KDC_ERR_KEY_TOO_WEAK + "0x42": KRB_AP_ERR_USER_TO_USER_REQUIRED + "0x43": KRB_AP_ERR_NO_TGT + "0x44": KDC_ERR_WRONG_REALM + source: |- + if (ctx?.winlog?.event_data?.Status == null || + ctx?.event?.code == null || + !["4768", "4769", "4770", "4771"].contains(ctx.event.code)) { + return; + } + ctx.winlog.event_data.put("StatusDescription", params[ctx.winlog.event_data.Status]); + - script: + lang: painless + ignore_failure: false + tag: Set Service Type and Name + description: Set Service Type and Name + # Services Types + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4697 + params: + "0x1": Kernel Driver + "0x2": File System Driver + "0x8": Recognizer Driver + "0x10": Win32 Own Process + "0x20": Win32 Share Process + "0x110": Interactive Own Process + "0x120": Interactive Share Process + source: |- + if (ctx?.winlog?.event_data?.ServiceName != null) { + if (ctx?.service == null) { + HashMap hm = new HashMap(); + ctx.put("service", hm); + } + ctx.service.put("name", ctx.winlog.event_data.ServiceName); + } + if (ctx?.winlog.event_data?.ServiceType != null) { + if (ctx?.service == null) { + HashMap hm = new HashMap(); + ctx.put("service", hm); + } + ctx.service.put("type", params[ctx.winlog.event_data.ServiceType]); + } + - script: + lang: painless + ignore_failure: false + tag: Set Audit Information + description: Set Audit Information + # Audit Categories Description + # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-gpac/77878370-0712-47cd-997d-b07053429f6d + params: + "0CCE9210-69AE-11D9-BED3-505054503030": ["Security State Change", "System"] + "0CCE9211-69AE-11D9-BED3-505054503030": ["Security System Extension", "System"] + "0CCE9212-69AE-11D9-BED3-505054503030": ["System Integrity", "System"] + "0CCE9213-69AE-11D9-BED3-505054503030": ["IPsec Driver", "System"] + "0CCE9214-69AE-11D9-BED3-505054503030": ["Other System Events", "System"] + "0CCE9215-69AE-11D9-BED3-505054503030": ["Logon", "Logon/Logoff"] + "0CCE9216-69AE-11D9-BED3-505054503030": ["Logoff", "Logon/Logoff"] + "0CCE9217-69AE-11D9-BED3-505054503030": ["Account Lockout", "Logon/Logoff"] + "0CCE9218-69AE-11D9-BED3-505054503030": ["IPsec Main Mode", "Logon/Logoff"] + "0CCE9219-69AE-11D9-BED3-505054503030": ["IPsec Quick Mode", "Logon/Logoff"] + "0CCE921A-69AE-11D9-BED3-505054503030": ["IPsec Extended Mode", "Logon/Logoff"] + "0CCE921B-69AE-11D9-BED3-505054503030": ["Special Logon", "Logon/Logoff"] + "0CCE921C-69AE-11D9-BED3-505054503030": ["Other Logon/Logoff Events", "Logon/Logoff"] + "0CCE9243-69AE-11D9-BED3-505054503030": ["Network Policy Server", "Logon/Logoff"] + "0CCE9247-69AE-11D9-BED3-505054503030": ["User / Device Claims", "Logon/Logoff"] + "0CCE921D-69AE-11D9-BED3-505054503030": ["File System", "Object Access"] + "0CCE921E-69AE-11D9-BED3-505054503030": ["Registry", "Object Access"] + "0CCE921F-69AE-11D9-BED3-505054503030": ["Kernel Object", "Object Access"] + "0CCE9220-69AE-11D9-BED3-505054503030": ["SAM", "Object Access"] + "0CCE9221-69AE-11D9-BED3-505054503030": ["Certification Services", "Object Access"] + "0CCE9222-69AE-11D9-BED3-505054503030": ["Application Generated", "Object Access"] + "0CCE9223-69AE-11D9-BED3-505054503030": ["Handle Manipulation", "Object Access"] + "0CCE9224-69AE-11D9-BED3-505054503030": ["File Share", "Object Access"] + "0CCE9225-69AE-11D9-BED3-505054503030": ["Filtering Platform Packet Drop", "Object Access"] + "0CCE9226-69AE-11D9-BED3-505054503030": ["Filtering Platform Connection ", "Object Access"] + "0CCE9227-69AE-11D9-BED3-505054503030": ["Other Object Access Events", "Object Access"] + "0CCE9244-69AE-11D9-BED3-505054503030": ["Detailed File Share", "Object Access"] + "0CCE9245-69AE-11D9-BED3-505054503030": ["Removable Storage", "Object Access"] + "0CCE9246-69AE-11D9-BED3-505054503030": ["Central Policy Staging", "Object Access"] + "0CCE9228-69AE-11D9-BED3-505054503030": ["Sensitive Privilege Use", "Privilege Use"] + "0CCE9229-69AE-11D9-BED3-505054503030": ["Non Sensitive Privilege Use", "Privilege Use"] + "0CCE922A-69AE-11D9-BED3-505054503030": ["Other Privilege Use Events", "Privilege Use"] + "0CCE922B-69AE-11D9-BED3-505054503030": ["Process Creation", "Detailed Tracking"] + "0CCE922C-69AE-11D9-BED3-505054503030": ["Process Termination", "Detailed Tracking"] + "0CCE922D-69AE-11D9-BED3-505054503030": ["DPAPI Activity", "Detailed Tracking"] + "0CCE922E-69AE-11D9-BED3-505054503030": ["RPC Events", "Detailed Tracking"] + "0CCE9248-69AE-11D9-BED3-505054503030": ["Plug and Play Events", "Detailed Tracking"] + "0CCE922F-69AE-11D9-BED3-505054503030": ["Audit Policy Change", "Policy Change"] + "0CCE9230-69AE-11D9-BED3-505054503030": ["Authentication Policy Change", "Policy Change"] + "0CCE9231-69AE-11D9-BED3-505054503030": ["Authorization Policy Change", "Policy Change"] + "0CCE9232-69AE-11D9-BED3-505054503030": ["MPSSVC Rule-Level Policy Change", "Policy Change"] + "0CCE9233-69AE-11D9-BED3-505054503030": ["Filtering Platform Policy Change", "Policy Change"] + "0CCE9234-69AE-11D9-BED3-505054503030": ["Other Policy Change Events", "Policy Change"] + "0CCE9235-69AE-11D9-BED3-505054503030": ["User Account Management", "Account Management"] + "0CCE9236-69AE-11D9-BED3-505054503030": ["Computer Account Management", "Account Management"] + "0CCE9237-69AE-11D9-BED3-505054503030": ["Security Group Management", "Account Management"] + "0CCE9238-69AE-11D9-BED3-505054503030": ["Distribution Group Management", "Account Management"] + "0CCE9239-69AE-11D9-BED3-505054503030": ["Application Group Management", "Account Management"] + "0CCE923A-69AE-11D9-BED3-505054503030": ["Other Account Management Events", "Account Management"] + "0CCE923B-69AE-11D9-BED3-505054503030": ["Directory Service Access", "Account Management"] + "0CCE923C-69AE-11D9-BED3-505054503030": ["Directory Service Changes", "Account Management"] + "0CCE923D-69AE-11D9-BED3-505054503030": ["Directory Service Replication", "Account Management"] + "0CCE923E-69AE-11D9-BED3-505054503030": ["Detailed Directory Service Replication", "Account Management"] + "0CCE923F-69AE-11D9-BED3-505054503030": ["Credential Validation", "Account Logon"] + "0CCE9240-69AE-11D9-BED3-505054503030": ["Kerberos Service Ticket Operations", "Account Logon"] + "0CCE9241-69AE-11D9-BED3-505054503030": ["Other Account Logon Events", "Account Logon"] + "0CCE9242-69AE-11D9-BED3-505054503030": ["Kerberos Authentication Service", "Account Logon"] + source: |- + if (ctx?.winlog?.event_data?.SubcategoryGuid == null) { + return; + } + def subCatGuid = ctx.winlog.event_data.SubcategoryGuid.replace("{","").replace("}","").toUpperCase(); + if (!params.containsKey(subCatGuid)) { + return; + } + ctx.winlog.event_data.put("Category", params[subCatGuid][1]); + ctx.winlog.event_data.put("SubCategory", params[subCatGuid][0]); + - script: + lang: painless + ignore_failure: false + tag: Decode message table + description: Decode message table + # Message table extracted from msobjs.dll on Windows 2019. + # https://gist.github.com/andrewkroh/665dca0682bd0e4daf194ab291694012 + # https://docs.microsoft.com/en-us/windows/win32/secauthz/access-rights-and-access-masks + # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/7a53f60e-e730-4dfe-bbe9-b21b62eb790b + params: + descriptions: + "279": "Undefined Access (no effect) Bit 7" + "1536": "Unused message ID" + "1537": "DELETE" + "1538": "READ_CONTROL" + "1539": "WRITE_DAC" + "1540": "WRITE_OWNER" + "1541": "SYNCHRONIZE" + "1542": "ACCESS_SYS_SEC" + "1543": "MAX_ALLOWED" + "1552": "Unknown specific access (bit 0)" + "1553": "Unknown specific access (bit 1)" + "1554": "Unknown specific access (bit 2)" + "1555": "Unknown specific access (bit 3)" + "1556": "Unknown specific access (bit 4)" + "1557": "Unknown specific access (bit 5)" + "1558": "Unknown specific access (bit 6)" + "1559": "Unknown specific access (bit 7)" + "1560": "Unknown specific access (bit 8)" + "1561": "Unknown specific access (bit 9)" + "1562": "Unknown specific access (bit 10)" + "1563": "Unknown specific access (bit 11)" + "1564": "Unknown specific access (bit 12)" + "1565": "Unknown specific access (bit 13)" + "1566": "Unknown specific access (bit 14)" + "1567": "Unknown specific access (bit 15)" + "1601": "Not used" + "1603": "Assign Primary Token Privilege" + "1604": "Lock Memory Privilege" + "1605": "Increase Memory Quota Privilege" + "1606": "Unsolicited Input Privilege" + "1607": "Trusted Computer Base Privilege" + "1608": "Security Privilege" + "1609": "Take Ownership Privilege" + "1610": "Load/Unload Driver Privilege" + "1611": "Profile System Privilege" + "1612": "Set System Time Privilege" + "1613": "Profile Single Process Privilege" + "1614": "Increment Base Priority Privilege" + "1615": "Create Pagefile Privilege" + "1616": "Create Permanent Object Privilege" + "1617": "Backup Privilege" + "1618": "Restore From Backup Privilege" + "1619": "Shutdown System Privilege" + "1620": "Debug Privilege" + "1621": "View or Change Audit Log Privilege" + "1622": "Change Hardware Environment Privilege" + "1623": "Change Notify (and Traverse) Privilege" + "1624": "Remotely Shut System Down Privilege" + "1792": "" + "1794": "" + "1795": "Enabled" + "1796": "Disabled" + "1797": "All" + "1798": "None" + "1799": "Audit Policy query/set API Operation" + "1800": "" + "1801": "Granted by" + "1802": "Denied by" + "1803": "Denied by Integrity Policy check" + "1804": "Granted by Ownership" + "1805": "Not granted" + "1806": "Granted by NULL DACL" + "1807": "Denied by Empty DACL" + "1808": "Granted by NULL Security Descriptor" + "1809": "Unknown or unchecked" + "1810": "Not granted due to missing" + "1811": "Granted by ACE on parent folder" + "1812": "Denied by ACE on parent folder" + "1813": "Granted by Central Access Rule" + "1814": "NOT Granted by Central Access Rule" + "1815": "Granted by parent folder's Central Access Rule" + "1816": "NOT Granted by parent folder's Central Access Rule" + "1817": "Unknown Type" + "1818": "String" + "1819": "Unsigned 64-bit Integer" + "1820": "64-bit Integer" + "1821": "FQBN" + "1822": "Blob" + "1823": "Sid" + "1824": "Boolean" + "1825": "TRUE" + "1826": "FALSE" + "1827": "Invalid" + "1828": "an ACE too long to display" + "1829": "a Security Descriptor too long to display" + "1830": "Not granted to AppContainers" + "1831": "..." + "1832": "Identification" + "1833": "Impersonation" + "1840": "Delegation" + "1841": "Denied by Process Trust Label ACE" + "1842": "Yes" + "1843": "No" + "1844": "System" + "1845": "Not Available" + "1846": "Default" + "1847": "DisallowMmConfig" + "1848": "Off" + "1849": "Auto" + "1872": "REG_NONE" + "1873": "REG_SZ" + "1874": "REG_EXPAND_SZ" + "1875": "REG_BINARY" + "1876": "REG_DWORD" + "1877": "REG_DWORD_BIG_ENDIAN" + "1878": "REG_LINK" + "1879": "REG_MULTI_SZ (New lines are replaced with *. A * is replaced with **)" + "1880": "REG_RESOURCE_LIST" + "1881": "REG_FULL_RESOURCE_DESCRIPTOR" + "1882": "REG_RESOURCE_REQUIREMENTS_LIST" + "1883": "REG_QWORD" + "1904": "New registry value created" + "1905": "Existing registry value modified" + "1906": "Registry value deleted" + "1920": "Sunday" + "1921": "Monday" + "1922": "Tuesday" + "1923": "Wednesday" + "1924": "Thursday" + "1925": "Friday" + "1926": "Saturday" + "1936": "TokenElevationTypeDefault (1)" + "1937": "TokenElevationTypeFull (2)" + "1938": "TokenElevationTypeLimited (3)" + "2048": "Account Enabled" + "2049": "Home Directory Required' - Disabled" + "2050": "Password Not Required' - Disabled" + "2051": "Temp Duplicate Account' - Disabled" + "2052": "Normal Account' - Disabled" + "2053": "MNS Logon Account' - Disabled" + "2054": "Interdomain Trust Account' - Disabled" + "2055": "Workstation Trust Account' - Disabled" + "2056": "Server Trust Account' - Disabled" + "2057": "Don't Expire Password' - Disabled" + "2058": "Account Unlocked" + "2059": "Encrypted Text Password Allowed' - Disabled" + "2060": "Smartcard Required' - Disabled" + "2061": "Trusted For Delegation' - Disabled" + "2062": "Not Delegated' - Disabled" + "2063": "Use DES Key Only' - Disabled" + "2064": "Don't Require Preauth' - Disabled" + "2065": "Password Expired' - Disabled" + "2066": "Trusted To Authenticate For Delegation' - Disabled" + "2067": "Exclude Authorization Information' - Disabled" + "2068": "Undefined UserAccountControl Bit 20' - Disabled" + "2069": "Protect Kerberos Service Tickets with AES Keys' - Disabled" + "2070": "Undefined UserAccountControl Bit 22' - Disabled" + "2071": "Undefined UserAccountControl Bit 23' - Disabled" + "2072": "Undefined UserAccountControl Bit 24' - Disabled" + "2073": "Undefined UserAccountControl Bit 25' - Disabled" + "2074": "Undefined UserAccountControl Bit 26' - Disabled" + "2075": "Undefined UserAccountControl Bit 27' - Disabled" + "2076": "Undefined UserAccountControl Bit 28' - Disabled" + "2077": "Undefined UserAccountControl Bit 29' - Disabled" + "2078": "Undefined UserAccountControl Bit 30' - Disabled" + "2079": "Undefined UserAccountControl Bit 31' - Disabled" + "2080": "Account Disabled" + "2081": "Home Directory Required' - Enabled" + "2082": "Password Not Required' - Enabled" + "2083": "Temp Duplicate Account' - Enabled" + "2084": "Normal Account' - Enabled" + "2085": "MNS Logon Account' - Enabled" + "2086": "Interdomain Trust Account' - Enabled" + "2087": "Workstation Trust Account' - Enabled" + "2088": "Server Trust Account' - Enabled" + "2089": "Don't Expire Password' - Enabled" + "2090": "Account Locked" + "2091": "Encrypted Text Password Allowed' - Enabled" + "2092": "Smartcard Required' - Enabled" + "2093": "Trusted For Delegation' - Enabled" + "2094": "Not Delegated' - Enabled" + "2095": "Use DES Key Only' - Enabled" + "2096": "Don't Require Preauth' - Enabled" + "2097": "Password Expired' - Enabled" + "2098": "Trusted To Authenticate For Delegation' - Enabled" + "2099": "Exclude Authorization Information' - Enabled" + "2100": "Undefined UserAccountControl Bit 20' - Enabled" + "2101": "Protect Kerberos Service Tickets with AES Keys' - Enabled" + "2102": "Undefined UserAccountControl Bit 22' - Enabled" + "2103": "Undefined UserAccountControl Bit 23' - Enabled" + "2104": "Undefined UserAccountControl Bit 24' - Enabled" + "2105": "Undefined UserAccountControl Bit 25' - Enabled" + "2106": "Undefined UserAccountControl Bit 26' - Enabled" + "2107": "Undefined UserAccountControl Bit 27' - Enabled" + "2108": "Undefined UserAccountControl Bit 28' - Enabled" + "2109": "Undefined UserAccountControl Bit 29' - Enabled" + "2110": "Undefined UserAccountControl Bit 30' - Enabled" + "2111": "Undefined UserAccountControl Bit 31' - Enabled" + "2304": "An Error occured during Logon." + "2305": "The specified user account has expired." + "2306": "The NetLogon component is not active." + "2307": "Account locked out." + "2308": "The user has not been granted the requested logon type at this machine." + "2309": "The specified account's password has expired." + "2310": "Account currently disabled." + "2311": "Account logon time restriction violation." + "2312": "User not allowed to logon at this computer." + "2313": "Unknown user name or bad password." + "2314": "Domain sid inconsistent." + "2315": "Smartcard logon is required and was not used." + "2432": "Not Available." + "2436": "Random number generator failure." + "2437": "Random number generation failed FIPS-140 pre-hash check." + "2438": "Failed to zero secret data." + "2439": "Key failed pair wise consistency check." + "2448": "Failed to unprotect persistent cryptographic key." + "2449": "Key export checks failed." + "2450": "Validation of public key failed." + "2451": "Signature verification failed." + "2456": "Open key file." + "2457": "Delete key file." + "2458": "Read persisted key from file." + "2459": "Write persisted key to file." + "2464": "Export of persistent cryptographic key." + "2465": "Import of persistent cryptographic key." + "2480": "Open Key." + "2481": "Create Key." + "2482": "Delete Key." + "2483": "Encrypt." + "2484": "Decrypt." + "2485": "Sign hash." + "2486": "Secret agreement." + "2487": "Domain settings" + "2488": "Local settings" + "2489": "Add provider." + "2490": "Remove provider." + "2491": "Add context." + "2492": "Remove context." + "2493": "Add function." + "2494": "Remove function." + "2495": "Add function provider." + "2496": "Remove function provider." + "2497": "Add function property." + "2498": "Remove function property." + "2499": "Machine key." + "2500": "User key." + "2501": "Key Derivation." + "4352": "Device Access Bit 0" + "4353": "Device Access Bit 1" + "4354": "Device Access Bit 2" + "4355": "Device Access Bit 3" + "4356": "Device Access Bit 4" + "4357": "Device Access Bit 5" + "4358": "Device Access Bit 6" + "4359": "Device Access Bit 7" + "4360": "Device Access Bit 8" + "4361": "Undefined Access (no effect) Bit 9" + "4362": "Undefined Access (no effect) Bit 10" + "4363": "Undefined Access (no effect) Bit 11" + "4364": "Undefined Access (no effect) Bit 12" + "4365": "Undefined Access (no effect) Bit 13" + "4366": "Undefined Access (no effect) Bit 14" + "4367": "Undefined Access (no effect) Bit 15" + "4368": "Query directory" + "4369": "Traverse" + "4370": "Create object in directory" + "4371": "Create sub-directory" + "4372": "Undefined Access (no effect) Bit 4" + "4373": "Undefined Access (no effect) Bit 5" + "4374": "Undefined Access (no effect) Bit 6" + "4375": "Undefined Access (no effect) Bit 7" + "4376": "Undefined Access (no effect) Bit 8" + "4377": "Undefined Access (no effect) Bit 9" + "4378": "Undefined Access (no effect) Bit 10" + "4379": "Undefined Access (no effect) Bit 11" + "4380": "Undefined Access (no effect) Bit 12" + "4381": "Undefined Access (no effect) Bit 13" + "4382": "Undefined Access (no effect) Bit 14" + "4383": "Undefined Access (no effect) Bit 15" + "4384": "Query event state" + "4385": "Modify event state" + "4386": "Undefined Access (no effect) Bit 2" + "4387": "Undefined Access (no effect) Bit 3" + "4388": "Undefined Access (no effect) Bit 4" + "4389": "Undefined Access (no effect) Bit 5" + "4390": "Undefined Access (no effect) Bit 6" + "4391": "Undefined Access (no effect) Bit 7" + "4392": "Undefined Access (no effect) Bit 8" + "4393": "Undefined Access (no effect) Bit 9" + "4394": "Undefined Access (no effect) Bit 10" + "4395": "Undefined Access (no effect) Bit 11" + "4396": "Undefined Access (no effect) Bit 12" + "4397": "Undefined Access (no effect) Bit 13" + "4398": "Undefined Access (no effect) Bit 14" + "4399": "Undefined Access (no effect) Bit 15" + "4416": "ReadData (or ListDirectory)" + "4417": "WriteData (or AddFile)" + "4418": "AppendData (or AddSubdirectory or CreatePipeInstance)" + "4419": "ReadEA" + "4420": "WriteEA" + "4421": "Execute/Traverse" + "4422": "DeleteChild" + "4423": "ReadAttributes" + "4424": "WriteAttributes" + "4425": "Undefined Access (no effect) Bit 9" + "4426": "Undefined Access (no effect) Bit 10" + "4427": "Undefined Access (no effect) Bit 11" + "4428": "Undefined Access (no effect) Bit 12" + "4429": "Undefined Access (no effect) Bit 13" + "4430": "Undefined Access (no effect) Bit 14" + "4431": "Undefined Access (no effect) Bit 15" + "4432": "Query key value" + "4433": "Set key value" + "4434": "Create sub-key" + "4435": "Enumerate sub-keys" + "4436": "Notify about changes to keys" + "4437": "Create Link" + "4438": "Undefined Access (no effect) Bit 6" + "4439": "Undefined Access (no effect) Bit 7" + "4440": "Enable 64(or 32) bit application to open 64 bit key" + "4441": "Enable 64(or 32) bit application to open 32 bit key" + "4442": "Undefined Access (no effect) Bit 10" + "4443": "Undefined Access (no effect) Bit 11" + "4444": "Undefined Access (no effect) Bit 12" + "4445": "Undefined Access (no effect) Bit 13" + "4446": "Undefined Access (no effect) Bit 14" + "4447": "Undefined Access (no effect) Bit 15" + "4448": "Query mutant state" + "4449": "Undefined Access (no effect) Bit 1" + "4450": "Undefined Access (no effect) Bit 2" + "4451": "Undefined Access (no effect) Bit 3" + "4452": "Undefined Access (no effect) Bit 4" + "4453": "Undefined Access (no effect) Bit 5" + "4454": "Undefined Access (no effect) Bit 6" + "4455": "Undefined Access (no effect) Bit 7" + "4456": "Undefined Access (no effect) Bit 8" + "4457": "Undefined Access (no effect) Bit 9" + "4458": "Undefined Access (no effect) Bit 10" + "4459": "Undefined Access (no effect) Bit 11" + "4460": "Undefined Access (no effect) Bit 12" + "4461": "Undefined Access (no effect) Bit 13" + "4462": "Undefined Access (no effect) Bit 14" + "4463": "Undefined Access (no effect) Bit 15" + "4464": "Communicate using port" + "4465": "Undefined Access (no effect) Bit 1" + "4466": "Undefined Access (no effect) Bit 2" + "4467": "Undefined Access (no effect) Bit 3" + "4468": "Undefined Access (no effect) Bit 4" + "4469": "Undefined Access (no effect) Bit 5" + "4470": "Undefined Access (no effect) Bit 6" + "4471": "Undefined Access (no effect) Bit 7" + "4472": "Undefined Access (no effect) Bit 8" + "4473": "Undefined Access (no effect) Bit 9" + "4474": "Undefined Access (no effect) Bit 10" + "4475": "Undefined Access (no effect) Bit 11" + "4476": "Undefined Access (no effect) Bit 12" + "4477": "Undefined Access (no effect) Bit 13" + "4478": "Undefined Access (no effect) Bit 14" + "4479": "Undefined Access (no effect) Bit 15" + "4480": "Force process termination" + "4481": "Create new thread in process" + "4482": "Set process session ID" + "4483": "Perform virtual memory operation" + "4484": "Read from process memory" + "4485": "Write to process memory" + "4486": "Duplicate handle into or out of process" + "4487": "Create a subprocess of process" + "4488": "Set process quotas" + "4489": "Set process information" + "4490": "Query process information" + "4491": "Set process termination port" + "4492": "Undefined Access (no effect) Bit 12" + "4493": "Undefined Access (no effect) Bit 13" + "4494": "Undefined Access (no effect) Bit 14" + "4495": "Undefined Access (no effect) Bit 15" + "4496": "Control profile" + "4497": "Undefined Access (no effect) Bit 1" + "4498": "Undefined Access (no effect) Bit 2" + "4499": "Undefined Access (no effect) Bit 3" + "4500": "Undefined Access (no effect) Bit 4" + "4501": "Undefined Access (no effect) Bit 5" + "4502": "Undefined Access (no effect) Bit 6" + "4503": "Undefined Access (no effect) Bit 7" + "4504": "Undefined Access (no effect) Bit 8" + "4505": "Undefined Access (no effect) Bit 9" + "4506": "Undefined Access (no effect) Bit 10" + "4507": "Undefined Access (no effect) Bit 11" + "4508": "Undefined Access (no effect) Bit 12" + "4509": "Undefined Access (no effect) Bit 13" + "4510": "Undefined Access (no effect) Bit 14" + "4511": "Undefined Access (no effect) Bit 15" + "4512": "Query section state" + "4513": "Map section for write" + "4514": "Map section for read" + "4515": "Map section for execute" + "4516": "Extend size" + "4517": "Undefined Access (no effect) Bit 5" + "4518": "Undefined Access (no effect) Bit 6" + "4519": "Undefined Access (no effect) Bit 7" + "4520": "Undefined Access (no effect) Bit 8" + "4521": "Undefined Access (no effect) Bit 9" + "4522": "Undefined Access (no effect) Bit 10" + "4523": "Undefined Access (no effect) Bit 11" + "4524": "Undefined Access (no effect) Bit 12" + "4525": "Undefined Access (no effect) Bit 13" + "4526": "Undefined Access (no effect) Bit 14" + "4527": "Undefined Access (no effect) Bit 15" + "4528": "Query semaphore state" + "4529": "Modify semaphore state" + "4530": "Undefined Access (no effect) Bit 2" + "4531": "Undefined Access (no effect) Bit 3" + "4532": "Undefined Access (no effect) Bit 4" + "4533": "Undefined Access (no effect) Bit 5" + "4534": "Undefined Access (no effect) Bit 6" + "4535": "Undefined Access (no effect) Bit 7" + "4536": "Undefined Access (no effect) Bit 8" + "4537": "Undefined Access (no effect) Bit 9" + "4538": "Undefined Access (no effect) Bit 10" + "4539": "Undefined Access (no effect) Bit 11" + "4540": "Undefined Access (no effect) Bit 12" + "4541": "Undefined Access (no effect) Bit 13" + "4542": "Undefined Access (no effect) Bit 14" + "4543": "Undefined Access (no effect) Bit 15" + "4544": "Use symbolic link" + "4545": "Undefined Access (no effect) Bit 1" + "4546": "Undefined Access (no effect) Bit 2" + "4547": "Undefined Access (no effect) Bit 3" + "4548": "Undefined Access (no effect) Bit 4" + "4549": "Undefined Access (no effect) Bit 5" + "4550": "Undefined Access (no effect) Bit 6" + "4551": "Undefined Access (no effect) Bit 7" + "4552": "Undefined Access (no effect) Bit 8" + "4553": "Undefined Access (no effect) Bit 9" + "4554": "Undefined Access (no effect) Bit 10" + "4555": "Undefined Access (no effect) Bit 11" + "4556": "Undefined Access (no effect) Bit 12" + "4557": "Undefined Access (no effect) Bit 13" + "4558": "Undefined Access (no effect) Bit 14" + "4559": "Undefined Access (no effect) Bit 15" + "4560": "Force thread termination" + "4561": "Suspend or resume thread" + "4562": "Send an alert to thread" + "4563": "Get thread context" + "4564": "Set thread context" + "4565": "Set thread information" + "4566": "Query thread information" + "4567": "Assign a token to the thread" + "4568": "Cause thread to directly impersonate another thread" + "4569": "Directly impersonate this thread" + "4570": "Undefined Access (no effect) Bit 10" + "4571": "Undefined Access (no effect) Bit 11" + "4572": "Undefined Access (no effect) Bit 12" + "4573": "Undefined Access (no effect) Bit 13" + "4574": "Undefined Access (no effect) Bit 14" + "4575": "Undefined Access (no effect) Bit 15" + "4576": "Query timer state" + "4577": "Modify timer state" + "4578": "Undefined Access (no effect) Bit 2" + "4579": "Undefined Access (no effect) Bit 3" + "4580": "Undefined Access (no effect) Bit 4" + "4581": "Undefined Access (no effect) Bit 5" + "4582": "Undefined Access (no effect) Bit 6" + "4584": "Undefined Access (no effect) Bit 8" + "4585": "Undefined Access (no effect) Bit 9" + "4586": "Undefined Access (no effect) Bit 10" + "4587": "Undefined Access (no effect) Bit 11" + "4588": "Undefined Access (no effect) Bit 12" + "4589": "Undefined Access (no effect) Bit 13" + "4590": "Undefined Access (no effect) Bit 14" + "4591": "Undefined Access (no effect) Bit 15" + "4592": "AssignAsPrimary" + "4593": "Duplicate" + "4594": "Impersonate" + "4595": "Query" + "4596": "QuerySource" + "4597": "AdjustPrivileges" + "4598": "AdjustGroups" + "4599": "AdjustDefaultDacl" + "4600": "AdjustSessionID" + "4601": "Undefined Access (no effect) Bit 9" + "4602": "Undefined Access (no effect) Bit 10" + "4603": "Undefined Access (no effect) Bit 11" + "4604": "Undefined Access (no effect) Bit 12" + "4605": "Undefined Access (no effect) Bit 13" + "4606": "Undefined Access (no effect) Bit 14" + "4607": "Undefined Access (no effect) Bit 15" + "4608": "Create instance of object type" + "4609": "Undefined Access (no effect) Bit 1" + "4610": "Undefined Access (no effect) Bit 2" + "4611": "Undefined Access (no effect) Bit 3" + "4612": "Undefined Access (no effect) Bit 4" + "4613": "Undefined Access (no effect) Bit 5" + "4614": "Undefined Access (no effect) Bit 6" + "4615": "Undefined Access (no effect) Bit 7" + "4616": "Undefined Access (no effect) Bit 8" + "4617": "Undefined Access (no effect) Bit 9" + "4618": "Undefined Access (no effect) Bit 10" + "4619": "Undefined Access (no effect) Bit 11" + "4620": "Undefined Access (no effect) Bit 12" + "4621": "Undefined Access (no effect) Bit 13" + "4622": "Undefined Access (no effect) Bit 14" + "4623": "Undefined Access (no effect) Bit 15" + "4864": "Query State" + "4865": "Modify State" + "5120": "Channel read message" + "5121": "Channel write message" + "5122": "Channel query information" + "5123": "Channel set information" + "5124": "Undefined Access (no effect) Bit 4" + "5125": "Undefined Access (no effect) Bit 5" + "5126": "Undefined Access (no effect) Bit 6" + "5127": "Undefined Access (no effect) Bit 7" + "5128": "Undefined Access (no effect) Bit 8" + "5129": "Undefined Access (no effect) Bit 9" + "5130": "Undefined Access (no effect) Bit 10" + "5131": "Undefined Access (no effect) Bit 11" + "5132": "Undefined Access (no effect) Bit 12" + "5133": "Undefined Access (no effect) Bit 13" + "5134": "Undefined Access (no effect) Bit 14" + "5135": "Undefined Access (no effect) Bit 15" + "5136": "Assign process" + "5137": "Set Attributes" + "5138": "Query Attributes" + "5139": "Terminate Job" + "5140": "Set Security Attributes" + "5141": "Undefined Access (no effect) Bit 5" + "5142": "Undefined Access (no effect) Bit 6" + "5143": "Undefined Access (no effect) Bit 7" + "5144": "Undefined Access (no effect) Bit 8" + "5145": "Undefined Access (no effect) Bit 9" + "5146": "Undefined Access (no effect) Bit 10" + "5147": "Undefined Access (no effect) Bit 11" + "5148": "Undefined Access (no effect) Bit 12" + "5149": "Undefined Access (no effect) Bit 13" + "5150": "Undefined Access (no effect) Bit 14" + "5151": "Undefined Access (no effect) Bit 15" + "5376": "ConnectToServer" + "5377": "ShutdownServer" + "5378": "InitializeServer" + "5379": "CreateDomain" + "5380": "EnumerateDomains" + "5381": "LookupDomain" + "5382": "Undefined Access (no effect) Bit 6" + "5383": "Undefined Access (no effect) Bit 7" + "5384": "Undefined Access (no effect) Bit 8" + "5385": "Undefined Access (no effect) Bit 9" + "5386": "Undefined Access (no effect) Bit 10" + "5387": "Undefined Access (no effect) Bit 11" + "5388": "Undefined Access (no effect) Bit 12" + "5389": "Undefined Access (no effect) Bit 13" + "5390": "Undefined Access (no effect) Bit 14" + "5391": "Undefined Access (no effect) Bit 15" + "5392": "ReadPasswordParameters" + "5393": "WritePasswordParameters" + "5394": "ReadOtherParameters" + "5395": "WriteOtherParameters" + "5396": "CreateUser" + "5397": "CreateGlobalGroup" + "5398": "CreateLocalGroup" + "5399": "GetLocalGroupMembership" + "5400": "ListAccounts" + "5401": "LookupIDs" + "5402": "AdministerServer" + "5403": "Undefined Access (no effect) Bit 11" + "5404": "Undefined Access (no effect) Bit 12" + "5405": "Undefined Access (no effect) Bit 13" + "5406": "Undefined Access (no effect) Bit 14" + "5407": "Undefined Access (no effect) Bit 15" + "5408": "ReadInformation" + "5409": "WriteAccount" + "5410": "AddMember" + "5411": "RemoveMember" + "5412": "ListMembers" + "5413": "Undefined Access (no effect) Bit 5" + "5414": "Undefined Access (no effect) Bit 6" + "5415": "Undefined Access (no effect) Bit 7" + "5416": "Undefined Access (no effect) Bit 8" + "5417": "Undefined Access (no effect) Bit 9" + "5418": "Undefined Access (no effect) Bit 10" + "5419": "Undefined Access (no effect) Bit 11" + "5420": "Undefined Access (no effect) Bit 12" + "5421": "Undefined Access (no effect) Bit 13" + "5422": "Undefined Access (no effect) Bit 14" + "5423": "Undefined Access (no effect) Bit 15" + "5424": "AddMember" + "5425": "RemoveMember" + "5426": "ListMembers" + "5427": "ReadInformation" + "5428": "WriteAccount" + "5429": "Undefined Access (no effect) Bit 5" + "5430": "Undefined Access (no effect) Bit 6" + "5431": "Undefined Access (no effect) Bit 7" + "5432": "Undefined Access (no effect) Bit 8" + "5433": "Undefined Access (no effect) Bit 9" + "5434": "Undefined Access (no effect) Bit 10" + "5435": "Undefined Access (no effect) Bit 11" + "5436": "Undefined Access (no effect) Bit 12" + "5437": "Undefined Access (no effect) Bit 13" + "5438": "Undefined Access (no effect) Bit 14" + "5439": "Undefined Access (no effect) Bit 15" + "5440": "ReadGeneralInformation" + "5441": "ReadPreferences" + "5442": "WritePreferences" + "5443": "ReadLogon" + "5444": "ReadAccount" + "5445": "WriteAccount" + "5446": "ChangePassword (with knowledge of old password)" + "5447": "SetPassword (without knowledge of old password)" + "5448": "ListGroups" + "5449": "ReadGroupMembership" + "5450": "ChangeGroupMembership" + "5451": "Undefined Access (no effect) Bit 11" + "5452": "Undefined Access (no effect) Bit 12" + "5453": "Undefined Access (no effect) Bit 13" + "5454": "Undefined Access (no effect) Bit 14" + "5455": "Undefined Access (no effect) Bit 15" + "5632": "View non-sensitive policy information" + "5633": "View system audit requirements" + "5634": "Get sensitive policy information" + "5635": "Modify domain trust relationships" + "5636": "Create special accounts (for assignment of user rights)" + "5637": "Create a secret object" + "5638": "Create a privilege" + "5639": "Set default quota limits" + "5640": "Change system audit requirements" + "5641": "Administer audit log attributes" + "5642": "Enable/Disable LSA" + "5643": "Lookup Names/SIDs" + "5648": "Change secret value" + "5649": "Query secret value" + "5650": "Undefined Access (no effect) Bit 2" + "5651": "Undefined Access (no effect) Bit 3" + "5652": "Undefined Access (no effect) Bit 4" + "5653": "Undefined Access (no effect) Bit 5" + "5654": "Undefined Access (no effect) Bit 6" + "5655": "Undefined Access (no effect) Bit 7" + "5656": "Undefined Access (no effect) Bit 8" + "5657": "Undefined Access (no effect) Bit 9" + "5658": "Undefined Access (no effect) Bit 10" + "5659": "Undefined Access (no effect) Bit 11" + "5660": "Undefined Access (no effect) Bit 12" + "5661": "Undefined Access (no effect) Bit 13" + "5662": "Undefined Access (no effect) Bit 14" + "5663": "Undefined Access (no effect) Bit 15" + "5664": "Query trusted domain name/SID" + "5665": "Retrieve the controllers in the trusted domain" + "5666": "Change the controllers in the trusted domain" + "5667": "Query the Posix ID offset assigned to the trusted domain" + "5668": "Change the Posix ID offset assigned to the trusted domain" + "5669": "Undefined Access (no effect) Bit 5" + "5670": "Undefined Access (no effect) Bit 6" + "5671": "Undefined Access (no effect) Bit 7" + "5672": "Undefined Access (no effect) Bit 8" + "5673": "Undefined Access (no effect) Bit 9" + "5674": "Undefined Access (no effect) Bit 10" + "5675": "Undefined Access (no effect) Bit 11" + "5676": "Undefined Access (no effect) Bit 12" + "5677": "Undefined Access (no effect) Bit 13" + "5678": "Undefined Access (no effect) Bit 14" + "5679": "Undefined Access (no effect) Bit 15" + "5680": "Query account information" + "5681": "Change privileges assigned to account" + "5682": "Change quotas assigned to account" + "5683": "Change logon capabilities assigned to account" + "5684": "Change the Posix ID offset assigned to the accounted domain" + "5685": "Undefined Access (no effect) Bit 5" + "5686": "Undefined Access (no effect) Bit 6" + "5687": "Undefined Access (no effect) Bit 7" + "5688": "Undefined Access (no effect) Bit 8" + "5689": "Undefined Access (no effect) Bit 9" + "5690": "Undefined Access (no effect) Bit 10" + "5691": "Undefined Access (no effect) Bit 11" + "5692": "Undefined Access (no effect) Bit 12" + "5693": "Undefined Access (no effect) Bit 13" + "5694": "Undefined Access (no effect) Bit 14" + "5695": "Undefined Access (no effect) Bit 15" + "5696": "KeyedEvent Wait" + "5697": "KeyedEvent Wake" + "5698": "Undefined Access (no effect) Bit 2" + "5699": "Undefined Access (no effect) Bit 3" + "5700": "Undefined Access (no effect) Bit 4" + "5701": "Undefined Access (no effect) Bit 5" + "5702": "Undefined Access (no effect) Bit 6" + "5703": "Undefined Access (no effect) Bit 7" + "5704": "Undefined Access (no effect) Bit 8" + "5705": "Undefined Access (no effect) Bit 9" + "5706": "Undefined Access (no effect) Bit 10" + "5707": "Undefined Access (no effect) Bit 11" + "5708": "Undefined Access (no effect) Bit 12" + "5709": "Undefined Access (no effect) Bit 13" + "5710": "Undefined Access (no effect) Bit 14" + "5711": "Undefined Access (no effect) Bit 15" + "6656": "Enumerate desktops" + "6657": "Read attributes" + "6658": "Access Clipboard" + "6659": "Create desktop" + "6660": "Write attributes" + "6661": "Access global atoms" + "6662": "Exit windows" + "6663": "Unused Access Flag" + "6664": "Include this windowstation in enumerations" + "6665": "Read screen" + "6672": "Read Objects" + "6673": "Create window" + "6674": "Create menu" + "6675": "Hook control" + "6676": "Journal (record)" + "6677": "Journal (playback)" + "6678": "Include this desktop in enumerations" + "6679": "Write objects" + "6680": "Switch to this desktop" + "6912": "Administer print server" + "6913": "Enumerate printers" + "6930": "Full Control" + "6931": "Print" + "6948": "Administer Document" + "7168": "Connect to service controller" + "7169": "Create a new service" + "7170": "Enumerate services" + "7171": "Lock service database for exclusive access" + "7172": "Query service database lock state" + "7173": "Set last-known-good state of service database" + "7184": "Query service configuration information" + "7185": "Set service configuration information" + "7186": "Query status of service" + "7187": "Enumerate dependencies of service" + "7188": "Start the service" + "7189": "Stop the service" + "7190": "Pause or continue the service" + "7191": "Query information from service" + "7192": "Issue service-specific control commands" + "7424": "DDE Share Read" + "7425": "DDE Share Write" + "7426": "DDE Share Initiate Static" + "7427": "DDE Share Initiate Link" + "7428": "DDE Share Request" + "7429": "DDE Share Advise" + "7430": "DDE Share Poke" + "7431": "DDE Share Execute" + "7432": "DDE Share Add Items" + "7433": "DDE Share List Items" + "7680": "Create Child" + "7681": "Delete Child" + "7682": "List Contents" + "7683": "Write Self" + "7684": "Read Property" + "7685": "Write Property" + "7686": "Delete Tree" + "7687": "List Object" + "7688": "Control Access" + "7689": "Undefined Access (no effect) Bit 9" + "7690": "Undefined Access (no effect) Bit 10" + "7691": "Undefined Access (no effect) Bit 11" + "7692": "Undefined Access (no effect) Bit 12" + "7693": "Undefined Access (no effect) Bit 13" + "7694": "Undefined Access (no effect) Bit 14" + "7695": "Undefined Access (no effect) Bit 15" + "7936": "Audit Set System Policy" + "7937": "Audit Query System Policy" + "7938": "Audit Set Per User Policy" + "7939": "Audit Query Per User Policy" + "7940": "Audit Enumerate Users" + "7941": "Audit Set Options" + "7942": "Audit Query Options" + "8064": "Port sharing (read)" + "8065": "Port sharing (write)" + "8096": "Default credentials" + "8097": "Credentials manager" + "8098": "Fresh credentials" + "8192": "Kerberos" + "8193": "Preshared key" + "8194": "Unknown authentication" + "8195": "DES" + "8196": "3DES" + "8197": "MD5" + "8198": "SHA1" + "8199": "Local computer" + "8200": "Remote computer" + "8201": "No state" + "8202": "Sent first (SA) payload" + "8203": "Sent second (KE) payload" + "8204": "Sent third (ID) payload" + "8205": "Initiator" + "8206": "Responder" + "8207": "No state" + "8208": "Sent first (SA) payload" + "8209": "Sent final payload" + "8210": "Complete" + "8211": "Unknown" + "8212": "Transport" + "8213": "Tunnel" + "8214": "IKE/AuthIP DoS prevention mode started" + "8215": "IKE/AuthIP DoS prevention mode stopped" + "8216": "Enabled" + "8217": "Not enabled" + "8218": "No state" + "8219": "Sent first (EM attributes) payload" + "8220": "Sent second (SSPI) payload" + "8221": "Sent third (hash) payload" + "8222": "IKEv1" + "8223": "AuthIP" + "8224": "Anonymous" + "8225": "NTLM V2" + "8226": "CGA" + "8227": "Certificate" + "8228": "SSL" + "8229": "None" + "8230": "DH group 1" + "8231": "DH group 2" + "8232": "DH group 14" + "8233": "DH group ECP 256" + "8234": "DH group ECP 384" + "8235": "AES-128" + "8236": "AES-192" + "8237": "AES-256" + "8238": "Certificate ECDSA P256" + "8239": "Certificate ECDSA P384" + "8240": "SSL ECDSA P256" + "8241": "SSL ECDSA P384" + "8242": "SHA 256" + "8243": "SHA 384" + "8244": "IKEv2" + "8245": "EAP payload sent" + "8246": "Authentication payload sent" + "8247": "EAP" + "8248": "DH group 24" + "8272": "System" + "8273": "Logon/Logoff" + "8274": "Object Access" + "8275": "Privilege Use" + "8276": "Detailed Tracking" + "8277": "Policy Change" + "8278": "Account Management" + "8279": "DS Access" + "8280": "Account Logon" + "8448": "Success removed" + "8449": "Success Added" + "8450": "Failure removed" + "8451": "Failure Added" + "8452": "Success include removed" + "8453": "Success include added" + "8454": "Success exclude removed" + "8455": "Success exclude added" + "8456": "Failure include removed" + "8457": "Failure include added" + "8458": "Failure exclude removed" + "8459": "Failure exclude added" + "12288": "Security State Change" + "12289": "Security System Extension" + "12290": "System Integrity" + "12291": "IPsec Driver" + "12292": "Other System Events" + "12544": "Logon" + "12545": "Logoff" + "12546": "Account Lockout" + "12547": "IPsec Main Mode" + "12548": "Special Logon" + "12549": "IPsec Quick Mode" + "12550": "IPsec Extended Mode" + "12551": "Other Logon/Logoff Events" + "12552": "Network Policy Server" + "12553": "User / Device Claims" + "12554": "Group Membership" + "12800": "File System" + "12801": "Registry" + "12802": "Kernel Object" + "12803": "SAM" + "12804": "Other Object Access Events" + "12805": "Certification Services" + "12806": "Application Generated" + "12807": "Handle Manipulation" + "12808": "File Share" + "12809": "Filtering Platform Packet Drop" + "12810": "Filtering Platform Connection" + "12811": "Detailed File Share" + "12812": "Removable Storage" + "12813": "Central Policy Staging" + "13056": "Sensitive Privilege Use" + "13057": "Non Sensitive Privilege Use" + "13058": "Other Privilege Use Events" + "13312": "Process Creation" + "13313": "Process Termination" + "13314": "DPAPI Activity" + "13315": "RPC Events" + "13316": "Plug and Play Events" + "13317": "Token Right Adjusted Events" + "13568": "Audit Policy Change" + "13569": "Authentication Policy Change" + "13570": "Authorization Policy Change" + "13571": "MPSSVC Rule-Level Policy Change" + "13572": "Filtering Platform Policy Change" + "13573": "Other Policy Change Events" + "13824": "User Account Management" + "13825": "Computer Account Management" + "13826": "Security Group Management" + "13827": "Distribution Group Management" + "13828": "Application Group Management" + "13829": "Other Account Management Events" + "14080": "Directory Service Access" + "14081": "Directory Service Changes" + "14082": "Directory Service Replication" + "14083": "Detailed Directory Service Replication" + "14336": "Credential Validation" + "14337": "Kerberos Service Ticket Operations" + "14338": "Other Account Logon Events" + "14339": "Kerberos Authentication Service" + "14592": "Inbound" + "14593": "Outbound" + "14594": "Forward" + "14595": "Bidirectional" + "14596": "IP Packet" + "14597": "Transport" + "14598": "Forward" + "14599": "Stream" + "14600": "Datagram Data" + "14601": "ICMP Error" + "14602": "MAC 802.3" + "14603": "MAC Native" + "14604": "vSwitch" + "14608": "Resource Assignment" + "14609": "Listen" + "14610": "Receive/Accept" + "14611": "Connect" + "14612": "Flow Established" + "14614": "Resource Release" + "14615": "Endpoint Closure" + "14616": "Connect Redirect" + "14617": "Bind Redirect" + "14624": "Stream Packet" + "14640": "ICMP Echo-Request" + "14641": "vSwitch Ingress" + "14642": "vSwitch Egress" + "14672": "" + "14673": "[NULL]" + "14674": "Value Added" + "14675": "Value Deleted" + "14676": "Active Directory Domain Services" + "14677": "Active Directory Lightweight Directory Services" + "14678": "Yes" + "14679": "No" + "14680": "Value Added With Expiration Time" + "14681": "Value Deleted With Expiration Time" + "14688": "Value Auto Deleted With Expiration Time" + "16384": "Add" + "16385": "Delete" + "16386": "Boot-time" + "16387": "Persistent" + "16388": "Not persistent" + "16389": "Block" + "16390": "Permit" + "16391": "Callout" + "16392": "MD5" + "16393": "SHA-1" + "16394": "SHA-256" + "16395": "AES-GCM 128" + "16396": "AES-GCM 192" + "16397": "AES-GCM 256" + "16398": "DES" + "16399": "3DES" + "16400": "AES-128" + "16401": "AES-192" + "16402": "AES-256" + "16403": "Transport" + "16404": "Tunnel" + "16405": "Responder" + "16406": "Initiator" + "16407": "AES-GMAC 128" + "16408": "AES-GMAC 192" + "16409": "AES-GMAC 256" + "16416": "AuthNoEncap Transport" + "16896": "Enable WMI Account" + "16897": "Execute Method" + "16898": "Full Write" + "16899": "Partial Write" + "16900": "Provider Write" + "16901": "Remote Access" + "16902": "Subscribe" + "16903": "Publish" + AccessMaskDescriptions: + "0x00000001": Create Child + "0x00000002": Delete Child + "0x00000004": List Contents + "0x00000008": SELF + "0x00000010": Read Property + "0x00000020": Write Property + "0x00000040": Delete Treee + "0x00000080": List Object + "0x00000100": Control Access + "0x00010000": DELETE + "0x00020000": READ_CONTROL + "0x00040000": WRITE_DAC + "0x00080000": WRITE_OWNER + "0x00100000": SYNCHRONIZE + "0x00F00000": STANDARD_RIGHTS_REQUIRED + "0x001F0000": STANDARD_RIGHTS_ALL + "0x0000FFFF": SPECIFIC_RIGHTS_ALL + "0x01000000": ADS_RIGHT_ACCESS_SYSTEM_SECURITY + "0x10000000": ADS_RIGHT_GENERIC_ALL + "0x20000000": ADS_RIGHT_GENERIC_EXECUTE + "0x40000000": ADS_RIGHT_GENERIC_WRITE + "0x80000000": ADS_RIGHT_GENERIC_READ + source: |- + if (ctx?.winlog?.event_data?.FailureReason != null) { + def code = ctx.winlog.event_data.FailureReason.replace("%%",""); + if (params.descriptions.containsKey(code)) { + if (ctx?.winlog?.logon == null ) { + HashMap hm = new HashMap(); + ctx.winlog.put("logon", hm); + } + if (ctx?.winlog?.logon?.failure == null) { + HashMap hm = new HashMap(); + ctx.winlog.logon.put("failure", hm); + } + ctx.winlog.logon.failure.put("reason", params.descriptions[code]); + } + } + if (ctx?.winlog?.event_data?.AuditPolicyChanges != null) { + ArrayList results = new ArrayList(); + for (elem in ctx.winlog.event_data.AuditPolicyChanges.splitOnToken(",")) { + def code = elem.replace("%%","").trim(); + if (params.descriptions.containsKey(code)) { + results.add(params.descriptions[code]); + } + } + if (results.length > 0) { + ctx.winlog.event_data.put("AuditPolicyChangesDescription", results); + } + } + if (ctx?.winlog?.event_data?.AccessList != null) { + ArrayList results = new ArrayList(); + for (elem in ctx.winlog.event_data.AccessList.splitOnToken(" ")) { + def code = elem.replace("%%","").trim(); + if (params.descriptions.containsKey(code)) { + results.add(params.descriptions[code]); + } + } + if (results.length > 0) { + ctx.winlog.event_data.put("AccessListDescription", results); + } + } + if (ctx?.winlog?.event_data?.AccessMask != null) { + ArrayList results = new ArrayList(); + Long accessMask = Long.decode(ctx.winlog.event_data.AccessMask); + for (entry in params.AccessMaskDescriptions.entrySet()) { + Long accessFlag = Long.decode(entry.getKey()); + if ((accessMask.longValue() & accessFlag.longValue()) == accessFlag.longValue()) { + results.add(entry.getValue()); + } + } + if (results.length > 0) { + ctx.winlog.event_data.put("AccessMaskDescription", results); + } + } + - script: + lang: painless + ignore_failure: false + tag: 4625 and 4776 Set Status and SubStatus + description: 4625 and 4776 Set Status and SubStatus + # Descriptions of failure status codes. + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4625 + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4776 + params: + "0xc000005e": "There are currently no logon servers available to service the logon request." + "0xc0000064": "User logon with misspelled or bad user account" + "0xc000006a": "User logon with misspelled or bad password" + "0xc000006d": "This is either due to a bad username or authentication information" + "0xc000006e": "Unknown user name or bad password." + "0xc000006f": "User logon outside authorized hours" + "0xc0000070": "User logon from unauthorized workstation" + "0xc0000071": "User logon with expired password" + "0xc0000072": "User logon to account disabled by administrator" + "0xc00000dc": "Indicates the Sam Server was in the wrong state to perform the desired operation." + "0xc0000133": "Clocks between DC and other computer too far out of sync" + "0xc000015b": "The user has not been granted the requested logon type (aka logon right) at this machine" + "0xc000018c": "The logon request failed because the trust relationship between the primary domain and the trusted domain failed." + "0xc0000192": "An attempt was made to logon, but the Netlogon service was not started." + "0xc0000193": "User logon with expired account" + "0xc0000224": "User is required to change password at next logon" + "0xc0000225": "Evidently a bug in Windows and not a risk" + "0xc0000234": "User logon with account locked" + "0xc00002ee": "Failure Reason: An Error occurred during Logon" + "0xc0000413": "Logon Failure: The machine you are logging onto is protected by an authentication firewall. The specified account is not allowed to authenticate to the machine." + "0xc0000371": "The local account store does not contain secret material for the specified account" + "0x0": "Status OK." + source: |- + if (ctx?.winlog?.event_data?.Status == null || + ctx?.event?.code == null || + !["4625", "4776"].contains(ctx.event.code)) { + return; + } + if (params.containsKey(ctx.winlog.event_data.Status)) { + if (ctx?.winlog?.logon == null ) { + HashMap hm = new HashMap(); + ctx.winlog.put("logon", hm); + } + if (ctx?.winlog?.logon?.failure == null) { + HashMap hm = new HashMap(); + ctx.winlog.logon.put("failure", hm); + } + ctx.winlog.logon.failure.put("status", params[ctx.winlog.event_data.Status]); + } + if (ctx?.winlog?.event_data?.SubStatus == null || !params.containsKey(ctx.winlog.event_data.SubStatus)) { + return; + } + if (ctx?.winlog?.logon == null ) { + HashMap hm = new HashMap(); + ctx.winlog.put("logon", hm); + } + if (ctx?.winlog?.logon?.failure == null) { + HashMap hm = new HashMap(); + ctx.winlog.logon.put("failure", hm); + } + ctx.winlog.logon.failure.put("sub_status", params[ctx.winlog.event_data.SubStatus]); + - script: + lang: painless + ignore_failure: false + tag: Set Trust Type + description: Set Trust Type + # Trust Types + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4706 + params: + "1": "TRUST_TYPE_DOWNLEVEL" + "2": "TRUST_TYPE_UPLEVEL" + "3": "TRUST_TYPE_MIT" + "4": "TRUST_TYPE_DCE" + source: |- + if (ctx?.winlog?.event_data?.TdoType == null) { + return; + } + if (!params.containsKey(ctx.winlog.event_data.TdoType)) { + return; + } + ctx.winlog.put("trustType", params[ctx.winlog.event_data.TdoType]); + - script: + lang: painless + ignore_failure: false + tag: Set Trust Direction + description: Set Trust Direction + # Trust Direction + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4706 + params: + "0": "TRUST_DIRECTION_DISABLED" + "1": "TRUST_DIRECTION_INBOUND" + "2": "TRUST_DIRECTION_OUTBOUND" + "3": "TRUST_DIRECTION_BIDIRECTIONAL" + source: |- + if (ctx?.winlog?.event_data?.TdoDirection == null) { + return; + } + if (!params.containsKey(ctx.winlog.event_data.TdoDirection)) { + return; + } + ctx.winlog.put("trustDirection", params[ctx.winlog.event_data.TdoDirection]); + - script: + lang: painless + ignore_failure: false + tag: Set Trust Attributes + description: Set Trust Attributes + # Trust Attributes + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4706 + params: + "0": "UNDEFINED" + "1": "TRUST_ATTRIBUTE_NON_TRANSITIVE" + "2": "TRUST_ATTRIBUTE_UPLEVEL_ONLY" + "4": "TRUST_ATTRIBUTE_QUARANTINED_DOMAIN" + "8": "TRUST_ATTRIBUTE_FOREST_TRANSITIVE" + "16": "TRUST_ATTRIBUTE_CROSS_ORGANIZATION" + "32": "TRUST_ATTRIBUTE_WITHIN_FOREST" + "64": "TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL" + "128": "TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION" + "512": "TRUST_ATTRIBUTE_CROSS_ORGANIZATION_NO_TGT_DELEGATION" + "1024": "TRUST_ATTRIBUTE_PIM_TRUST" + source: |- + if (ctx?.winlog?.event_data?.TdoAttributes == null) { + return; + } + if (!params.containsKey(ctx.winlog.event_data.TdoAttributes)) { + return; + } + ctx.winlog.put("trustAttribute", params[ctx.winlog.event_data.TdoAttributes]); + - script: + lang: painless + ignore_failure: false + tag: Add Session Events + description: Add Session Events + source: |- + if (ctx?.event?.code == null || + !["4778", "4779"].contains(ctx.event.code)) { + return; + } + //AccountName to user.name and related.user + if (ctx?.winlog?.event_data?.AccountName != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + ctx.user.put("name", ctx.winlog.event_data.AccountName); + if (!ctx.related.user.contains(ctx.winlog.event_data.AccountName)) { + ctx.related.user.add(ctx.winlog.event_data.AccountName); + } + } + + //AccountDomain to user.domain + if (ctx?.winlog?.event_data?.AccountDomain != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + ctx.user.put("domain", ctx.winlog.event_data.AccountDomain); + } + + //ClientAddress to source.ip and related.ip + if (ctx?.winlog?.event_data?.ClientAddress != null && + ctx.winlog.event_data.ClientAddress != "-") { + if (ctx?.source == null) { + HashMap hm = new HashMap(); + ctx.put("source", hm); + } + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.ip == null) { + ArrayList al = new ArrayList(); + ctx.related.put("ip", al); + } + ctx.source.put("ip", ctx.winlog.event_data.ClientAddress); + if (!ctx.related.ip.contains(ctx.winlog.event_data.ClientAddress)) { + ctx.related.ip.add(ctx.winlog.event_data.ClientAddress); + } + } + + //ClientName to source.domain + if (ctx?.winlog?.event_data?.ClientName != null) { + if (ctx?.source == null) { + HashMap hm = new HashMap(); + ctx.put("source", hm); + } + ctx.source.put("domain", ctx.winlog.event_data.ClientName); + } + + //LogonID to winlog.logon.id + if (ctx?.winlog?.event_data?.LogonID != null) { + if (ctx?.winlog?.logon == null) { + HashMap hm = new HashMap(); + ctx.winlog.put("logon", hm); + } + ctx.winlog.logon.put("id", ctx.winlog.event_data.LogonID); + } + + - script: + lang: painless + ignore_failure: false + tag: Copy Target User + description: Copy Target User + source: |- + if (ctx?.event?.code == null || + !["4624", "4625", "4634", "4647", "4648", "4768", "4769", "4770", + "4771", "4776", "4964"].contains(ctx.event.code)) { + return; + } + + def targetUserId = ctx?.winlog?.event_data?.TargetUserSid; + if (targetUserId == null) { + targetUserId = ctx?.winlog?.event_data?.TargetSid; + } + + //TargetUserSid to user.id or user.target.id + if (targetUserId != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.user?.id == null) { + ctx.user.put("id", targetUserId); + } else { + if (ctx?.user?.target == null) { + HashMap hm = new HashMap(); + ctx.user.put("target", hm); + } + ctx.user.target.put("id", targetUserId); + } + } + + //TargetUserName to related.user and user.name or user.target.name + if (ctx?.winlog?.event_data?.TargetUserName != null) { + def tun = ctx.winlog.event_data.TargetUserName.splitOnToken("@"); + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.user?.name == null) { + ctx.user.put("name", tun[0]); + } else { + if (ctx?.user?.target == null) { + HashMap hm = new HashMap(); + ctx.user.put("target", hm); + } + ctx.user.target.put("name", tun[0]); + } + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + if (!ctx.related.user.contains(tun[0])) { + ctx.related.user.add(tun[0]); + } + } + //TargetUserDomain to user.domain or user.target.domain + if (ctx?.winlog?.event_data?.TargetDomainName != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.user?.domain == null) { + ctx.user.put("domain", ctx.winlog.event_data.TargetDomainName); + } else { + if (ctx?.user?.target == null){ + HashMap hm = new HashMap(); + ctx.user.put("target", hm); + } + ctx.user.target.put("domain", ctx.winlog.event_data.TargetDomainName); + } + } + - script: + lang: painless + ignore_failure: false + tag: Copy MemberName to User and User to Group + description: Copy MemberName to User and User to Group + source: |- + if (ctx?.event?.code == null || + !["4727", "4728", "4729", "4730", "4731", "4732", "4733", "4734", "4735", + "4737", "4744", "4745", "4746", "4747", "4748", "4749", "4750", "4751", + "4752", "4753", "4754", "4755", "4756", "4757", "4758", "4759", "4760", + "4761", "4762", "4763", "4764", "4799"].contains(ctx.event.code)) { + return; + } + if (ctx?.winlog?.event_data?.MemberName != null) { + def memberNameParts = ctx.winlog.event_data.MemberName.splitOnToken(","); + def memberName = memberNameParts[0].replace("CN=","").replace("cn=",""); + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.user?.target == null){ + HashMap hm = new HashMap(); + ctx.user.put("target", hm); + } + ctx.user.target.put("name", memberName); + if (!ctx.related.user.contains(memberName)) { + ctx.related.user.add(memberName); + } + if (memberNameParts.length >= 4) { + def domain = memberNameParts[3].replace("DC=", "").replace("dc=", ""); + ctx.user.target.put("domain", domain); + } + } + if (ctx?.winlog?.event_data?.TargetUserSid != null) { + if (ctx?.group == null) { + HashMap hm = new HashMap(); + ctx.put("group", hm); + } + ctx.group.put("id", ctx.winlog.event_data.TargetUserSid); + } + if (ctx?.winlog?.event_data?.TargetSid != null) { + if (ctx?.group == null) { + HashMap hm = new HashMap(); + ctx.put("group", hm); + } + ctx.group.put("id", ctx.winlog.event_data.TargetSid); + } + if (ctx?.winlog?.event_data?.TargetUserName != null) { + if (ctx?.group == null) { + HashMap hm = new HashMap(); + ctx.put("group", hm); + } + ctx.group.put("name", ctx.winlog.event_data.TargetUserName); + } + if (ctx?.winlog?.event_data?.TargetDomainName != null) { + if (ctx?.group == null) { + HashMap hm = new HashMap(); + ctx.put("group", hm); + } + def domain = ctx.winlog.event_data.TargetDomainName.replace("DC=", "").replace("dc=", ""); + ctx.group.put("domain", domain); + } + if (ctx?.user?.target != null) { + if (ctx?.user?.target?.group == null) { + HashMap hm = new HashMap(); + ctx.user.target.put("group", hm); + } + if (ctx?.group?.id != null) { + ctx.user.target.group.put("id", ctx.group.id); + } + if (ctx?.group?.name != null) { + ctx.user.target.group.put("name", ctx.group.name); + } + if (ctx?.group?.domain != null) { + ctx.user.target.group.put("domain", ctx.group.domain); + } + } + + - script: + lang: painless + ignore_failure: false + tag: Copy Target User to Computer Object + description: Copy Target User to Computer Object + source: |- + if (ctx?.event?.code == null || + !["4741", "4742", "4743"].contains(ctx.event.code)) { + return; + } + if (ctx?.winlog?.event_data?.TargetSid != null) { + if (ctx?.winlog?.computerObject == null) { + HashMap hm = new HashMap(); + ctx.winlog.put("computerObject", hm); + } + ctx.winlog.computerObject.put("id", ctx.winlog.event_data.TargetSid); + } + if (ctx?.winlog?.event_data?.TargetUserName != null) { + if (ctx?.winlog?.computerObject == null) { + HashMap hm = new HashMap(); + ctx.winlog.put("computerObject", hm); + } + ctx.winlog.computerObject.put("name", ctx.winlog.event_data.TargetUserName); + } + if (ctx?.winlog?.event_data?.TargetDomainName != null) { + if (ctx?.winlog?.computerObject == null) { + HashMap hm = new HashMap(); + ctx.winlog.put("computerObject", hm); + } + ctx.winlog.computerObject.put("domain", ctx.winlog.event_data.TargetDomainName); + } + + - set: + field: winlog.logon.id + copy_from: winlog.event_data.TargetLogonId + ignore_failure: false + if: ctx?.event?.code != null && ["4634", "4647", "4964"].contains(ctx.event.code) + + - script: + lang: painless + ignore_failure: false + tag: Copy Subject User from Event Data + description: Copy Subject User from Event Data + source: |- + if (ctx?.event?.code == null || + !["4657", "4670", "4672", "4673", "4674", "4688", "4689", "4697", + "4698", "4699", "4700", "4701", "4702", "4706", "4707", "4713", + "4716", "4717", "4718", "4719", "4720", "4722", "4723", "4724", + "4725", "4726", "4727", "4728", "4729", "4730", "4731", "4732", + "4733", "4734", "4735", "4737", "4738", "4739", "4740", "4741", + "4742", "4743", "4744", "4745", "4746", "4747", "4748", "4749", + "4750", "4751", "4752", "4753", "4754", "4755", "4756", "4757", + "4758", "4759", "4760", "4761", "4762", "4763", "4764", "4767", + "4781", "4798", "4799", "4817", "4904", "4905", "4907", "4912", + "4648"].contains(ctx.event.code)) { + return; + } + if (ctx?.winlog?.event_data?.SubjectUserSid != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + ctx.user.put("id", ctx.winlog.event_data.SubjectUserSid); + } + if (ctx?.winlog?.event_data?.SubjectUserName != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + ctx.user.put("name", ctx.winlog.event_data.SubjectUserName); + if (!ctx.related.user.contains(ctx.winlog.event_data.SubjectUserName)) { + ctx.related.user.add(ctx.winlog.event_data.SubjectUserName); + } + } + if (ctx?.winlog?.event_data?.SubjectDomainName != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + ctx.user.put("domain", ctx.winlog.event_data.SubjectDomainName); + } + + - script: + lang: painless + ignore_failure: false + tag: Copy Target User to Target + description: Copy Target User to Target + source: |- + if (ctx?.event?.code == null || + !["4670", "4720", "4722", "4723", "4724", "4725", + "4726", "4738", "4740", "4767", "4798", "4817", + "4907"].contains(ctx.event.code)) { + return; + } + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.user?.target == null) { + HashMap hm = new HashMap(); + ctx.user.put("target", hm); + } + def userId = ctx?.winlog?.event_data?.TargetSid; + if (userId != null && userId != "" && userId != "-") ctx.user.target.id = userId; + def userName = ctx?.winlog?.event_data?.TargetUserName; + if (userName != null && userName != "" && userName != "-") { + ctx.user.target.name = userName; + def parts = userName.splitOnToken("@"); + if (parts.length > 1) { + ctx.user.target.name = parts[0]; + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + if (!ctx.related.user.contains(ctx.user.target.name)) { + ctx.related.user.add(ctx.user.target.name); + } + } + def userDomain = ctx?.winlog?.event_data?.TargetDomainName; + if (userDomain != null && userDomain != "" && userDomain != "-") ctx.user.target.domain = userDomain; + if (ctx.user?.target != null && ctx.user.target.size() == 0) ctx.user.remove("target"); + + - script: + lang: painless + ignore_failure: false + tag: Copy Target User to Effective + description: Copy Target User to Effective + source: |- + if (ctx?.event?.code == null || + !["4648", "4688"].contains(ctx.event.code)) { + return; + } + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.user?.effective == null) { + HashMap hm = new HashMap(); + ctx.user.put("effective", hm); + } + def userId = ctx?.winlog?.event_data?.TargetUserSid; + if (userId != null && userId != "" && userId != "-") ctx.user.effective.id = userId; + def userName = ctx?.winlog?.event_data?.TargetUserName; + if (userName != null && userName != "" && userName != "-") { + ctx.user.effective.name = userName; + def parts = userName.splitOnToken("@"); + if (parts.length > 1) { + ctx.user.effective.name = parts[0]; + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + if (!ctx.related.user.contains(ctx.user.effective.name)) { + ctx.related.user.add(ctx.user.effective.name); + } + } + def userDomain = ctx?.winlog?.event_data?.TargetDomainName; + if (userDomain != null && userDomain != "" && userDomain != "-") ctx.user.effective.domain = userDomain; + if (ctx.user?.effective != null && ctx.user.effective.size() == 0) ctx.user.remove("effective"); + + - script: + lang: painless + ignore_failure: false + tag: Copy Subject User from user_data + description: Copy Subject User from user_data + source: |- + if (ctx?.event?.code == null || + !["1102"].contains(ctx.event.code)) { + return; + } + if (ctx?.winlog?.user_data?.SubjectUserSid != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + ctx.user.put("id", ctx.winlog.user_data.SubjectUserSid); + } + if (ctx?.winlog?.user_data?.SubjectUserName != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + ctx.user.put("name", ctx.winlog.user_data.SubjectUserName); + if (!ctx.related.user.contains(ctx.winlog.user_data.SubjectUserName)) { + ctx.related.user.add(ctx.winlog.user_data.SubjectUserName); + } + } + if (ctx?.winlog?.user_data?.SubjectDomainName != null) { + if (ctx?.user == null) { + HashMap hm = new HashMap(); + ctx.put("user", hm); + } + ctx.user.put("domain", ctx.winlog.user_data.SubjectDomainName); + } + + - set: + field: winlog.logon.id + copy_from: winlog.event_data.SubjectLogonId + ignore_failure: true + + - set: + field: winlog.logon.id + copy_from: winlog.user_data.SubjectLogonId + ignore_failure: true + if: |- + ctx?.event?.code != null && + ["1102"].contains(ctx.event.code) + + - script: + lang: painless + ignore_failure: false + tag: Rename Common Auth Fields + description: Rename Common Auth Fields + source: |- + if (ctx?.event?.code == null || + !["1100", "1102", "1104", "1105", "1108", "4624", "4648", "4625", + "4670", "4673", "4674", "4689", "4697", "4719", "4720", "4722", + "4723", "4724", "4725", "4726", "4727", "4728", "4729", "4730", + "4731", "4732", "4733", "4734", "4735", "4737", "4738", "4740", + "4741", "4742", "4743", "4744", "4745", "4746", "4747", "4748", + "4749", "4750", "4751", "4752", "4753", "4754", "4755", "4756", + "4757", "4758", "4759", "4760", "4761", "4762", "4763", "4764", + "4767", "4768", "4769", "4770", "4771", "4798", "4799", "4817", + "4904", "4905", "4907", "4912"].contains(ctx.event.code)) { + return; + } + if (ctx?.winlog?.event_data?.ProcessId != null) { + if (ctx?.process == null) { + HashMap hm = new HashMap(); + ctx.put("process", hm); + } + if (ctx.winlog.event_data.ProcessId instanceof String) { + Long pid = Long.decode(ctx.winlog.event_data.ProcessId); + ctx.process.put("pid", pid.longValue()); + } else { + ctx.process.put("pid", ctx.winlog.event_data.ProcessId); + } + ctx.winlog.event_data.remove("ProcessId"); + } + if (ctx?.winlog?.event_data?.ProcessName != null) { + if (ctx?.process == null) { + HashMap hm = new HashMap(); + ctx.put("process", hm); + } + ctx.process.put("executable", ctx.winlog.event_data.ProcessName); + ctx.winlog.event_data.remove("ProcessName"); + } + if (ctx?.winlog?.event_data?.IpAddress != null && + ctx.winlog.event_data.IpAddress != "-") { + if (ctx?.source == null) { + HashMap hm = new HashMap(); + ctx.put("source", hm); + } + ctx.source.put("ip", ctx.winlog.event_data.IpAddress); + ctx.winlog.event_data.remove("IpAddress"); + } + if (ctx?.winlog?.event_data?.IpPort != null && ctx.winlog.event_data.IpPort != "-") { + if (ctx?.source == null) { + HashMap hm = new HashMap(); + ctx.put("source", hm); + } + ctx.source.put("port", Long.decode(ctx.winlog.event_data.IpPort)); + ctx.winlog.event_data.remove("IpPort"); + } + if (ctx?.winlog?.event_data?.WorkstationName != null) { + if (ctx?.source == null) { + HashMap hm = new HashMap(); + ctx.put("source", hm); + } + ctx.source.put("domain", ctx.winlog.event_data.WorkstationName); + ctx.winlog.event_data.remove("WorkstationName"); + } + if (ctx?.winlog?.event_data?.ClientAddress != null && + ctx.winlog.event_data.ClientAddress != "-") { + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + ctx.related.put("ip", ctx.winlog.event_data.ClientAddress); + ctx.winlog.event_data.remove("ClientAddress"); + } + if (ctx?.process?.name == null && ctx?.process?.executable != null) { + def parts = ctx.process.executable.splitOnToken("\\"); + ctx.process.put("name", parts[-1]); + } + + - script: + lang: painless + ignore_failure: false + tag: Process Event 4688 + description: Process Event 4688 + source: |- + if (ctx?.event?.code == null || + !["4688"].contains(ctx.event.code)) { + return; + } + if (ctx?.winlog?.event_data?.NewProcessId != null) { + if (ctx?.process == null) { + HashMap hm = new HashMap(); + ctx.put("process", hm); + } + if (ctx.winlog.event_data.NewProcessId instanceof String) { + Long pid = Long.decode(ctx.winlog.event_data.NewProcessId); + ctx.process.put("pid", pid.longValue()); + } else { + ctx.process.put("pid", ctx.winlog.event_data.NewProcessId); + } + ctx.winlog.event_data.remove("NewProcessId"); + } + if (ctx?.winlog?.event_data?.NewProcessName != null) { + if (ctx?.process == null) { + HashMap hm = new HashMap(); + ctx.put("process", hm); + } + ctx.process.put("executable", ctx.winlog.event_data.NewProcessName); + ctx.winlog.event_data.remove("NewProcessName"); + } + if (ctx?.winlog?.event_data?.ParentProcessName != null) { + if (ctx?.process == null) { + HashMap hm = new HashMap(); + ctx.put("process", hm); + } + if (ctx?.process?.parent == null) { + HashMap hm = new HashMap(); + ctx.process.put("parent", hm); + } + ctx.process.parent.put("executable", ctx.winlog.event_data.ParentProcessName); + ctx.winlog.event_data.remove("ParentProcessName"); + } + if (ctx?.process?.name == null && ctx?.process?.executable != null) { + def parts = ctx.process.executable.splitOnToken("\\"); + ctx.process.put("name", parts[-1]); + } + if (ctx?.process?.parent?.name == null && ctx?.process?.parent?.executable != null) { + def parts = ctx.process.parent.executable.splitOnToken("\\"); + ctx.process.parent.put("name", parts[-1]); + } + if (ctx?.winlog?.event_data?.CommandLine != null) { + int start = 0; + int end = 0; + boolean in_quote = false; + ArrayList al = new ArrayList(); + for (int i = 0; i < ctx.winlog.event_data.CommandLine.length(); i++) { + end = i; + if (Character.compare(ctx.winlog.event_data.CommandLine.charAt(i), "\"".charAt(0)) == 0) { + if (in_quote) { + in_quote = false; + } else { + in_quote = true; + } + } + if (Character.isWhitespace(ctx.winlog.event_data.CommandLine.charAt(i)) && !in_quote) { + al.add(ctx.winlog.event_data.CommandLine.substring(start, end)); + start = i + 1; + } + if (i == ctx.winlog.event_data.CommandLine.length() - 1) { + al.add(ctx.winlog.event_data.CommandLine.substring(start, end + 1)); + } + } + if (ctx?.process == null) { + HashMap hm = new HashMap(); + ctx.put("process", hm); + } + ctx.process.put("args", al); + ctx.process.put("command_line", ctx.winlog.event_data.CommandLine); + } + if ((ctx?.winlog?.event_data?.TargetUserName != null) && + (!ctx.winlog.event_data.TargetUserName.equals("-"))) { + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + if (!ctx.related.user.contains(ctx.winlog.event_data.TargetUserName)) { + ctx.related.user.add(ctx.winlog.event_data.TargetUserName); + } + } + + - append: + field: related.user + value: '{{winlog.event_data.SubjectUserName}}' + allow_duplicates: false + if: |- + ctx?.event?.code != null && + ["4624", "4648"].contains(ctx.event.code) && + ctx?.winlog?.event_data?.SubjectUserName != null && + ctx.winlog.event_data.SubjectUserName != "-" + + - append: + field: related.user + value: '{{winlog.event_data.TargetUserName}}' + allow_duplicates: false + if: |- + ctx?.event?.code != null && + ["4688", "4720", "4722", "4723", "4724", "4725", "4726", "4738", + "4740", "4767", "4798"].contains(ctx.event.code) && + ctx?.winlog?.event_data?.TargetUserName != null && + ctx.winlog.event_data.TargetUserName != "-" + + - split: + field: winlog.event_data.PrivilegeList + separator: "\\s+" + if: |- + ctx?.event?.code != null && + ["4672", "4673", "4674", "4741", "4742", "4743"].contains(ctx.event.code) && + ctx?.winlog?.event_data?.PrivilegeList != null + + - set: + field: user.target.name + copy_from: winlog.event_data.OldTargetUserName + ignore_empty_value: true + + - set: + field: user.changes.name + copy_from: winlog.event_data.NewTargetUserName + ignore_empty_value: true + + - append: + field: related.user + value: '{{winlog.event_data.NewTargetUserName}}' + allow_duplicates: false + if: |- + ctx?.winlog?.event_data?.NewTargetUserName != null && + ctx.winlog.event_data.NewTargetUserName != "-" + + - append: + field: related.user + value: '{{winlog.event_data.OldTargetUserName}}' + allow_duplicates: false + if: |- + ctx?.winlog?.event_data?.OldTargetUserName != null && + ctx.winlog.event_data.OldTargetUserName != "-" + + - gsub: + field: source.ip + pattern: "::ffff:" + replacement: "" + ignore_missing: true + + - append: + field: related.ip + value: '{{source.ip}}' + allow_duplicates: false + if: |- + ctx?.source?.ip != null && + ctx.source.ip != "-" + + - script: + lang: painless + ignore_failure: false + tag: Object Policy Change and SidListDesc + description: Object Policy Change and SidListDesc + # SDDL Ace Types + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4715 + # https://docs.microsoft.com/en-us/windows/win32/secauthz/ace-strings + # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/f4296d69-1c0f-491f-9587-a960b292d070 + # SDDL Permissions + # https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4715 + # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/f4296d69-1c0f-491f-9587-a960b292d070 + # Known SIDs + # https://support.microsoft.com/en-au/help/243330/well-known-security-identifier"S-in-window"S-operating-systems + # https://docs.microsoft.com/en-us/windows/win32/secauthz/sid-strings + # Domain-specific SIDs + # https://support.microsoft.com/en-au/help/243330/well-known-security-identifiers-in-windows-operating-systems + # Object Permission Flags + # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/7a53f60e-e730-4dfe-bbe9-b21b62eb790b + params: + AccountSIDDescription: + AO: Account operators + RU: Alias to allow previous Windows 2000 + AN: Anonymous logon + AU: Authenticated users + BA: Built-in administrators + BG: Built-in guests + BO: Backup operators + BU: Built-in users + CA: Certificate server administrators + CG: Creator group + CO: Creator owner + DA: Domain administrators + DC: Domain computers + DD: Domain controllers + DG: Domain guests + DU: Domain users + EA: Enterprise administrators + ED: Enterprise domain controllers + WD: Everyone + PA: Group Policy administrators + IU: Interactively logged-on user + LA: Local administrator + LG: Local guest + LS: Local service account + SY: Local system + NU: Network logon user + "NO": Network configuration operators + NS: Network service account + PO: Printer operators + PS: Personal self + PU: Power users + RS: RAS servers group + RD: Terminal server users + RE: Replicator + RC: Restricted code + SA: Schema administrators + SO: Server operators + SU: Service logon user + S-1-0: Null Authority + S-1-0-0: Nobody + S-1-1: World Authority + S-1-1-0: Everyone + S-1-16-0: Untrusted Mandatory Level + S-1-16-12288: High Mandatory Level + S-1-16-16384: System Mandatory Level + S-1-16-20480: Protected Process Mandatory Level + S-1-16-28672: Secure Process Mandatory Level + S-1-16-4096: Low Mandatory Level + S-1-16-8192: Medium Mandatory Level + S-1-16-8448: Medium Plus Mandatory Level + S-1-2: Local Authority + S-1-2-0: Local + S-1-2-1: Console Logon + S-1-3: Creator Authority + S-1-3-0: Creator Owner + S-1-3-1: Creator Group + S-1-3-2: Creator Owner Server + S-1-3-3: Creator Group Server + S-1-3-4: Owner Rights + S-1-4: Non-unique Authority + S-1-5: NT Authority + S-1-5-1: Dialup + S-1-5-10: Principal Self + S-1-5-11: Authenticated Users + S-1-5-12: Restricted Code + S-1-5-13: Terminal Server Users + S-1-5-14: Remote Interactive Logon + S-1-5-15: This Organization + S-1-5-17: This Organization + S-1-5-18: Local System + S-1-5-19: NT Authority + S-1-5-2: Network + S-1-5-20: NT Authority + S-1-5-3: Batch + S-1-5-32-544: Administrators + S-1-5-32-545: Users + S-1-5-32-546: Guests + S-1-5-32-547: Power Users + S-1-5-32-548: Account Operators + S-1-5-32-549: Server Operators + S-1-5-32-550: Print Operators + S-1-5-32-551: Backup Operators + S-1-5-32-552: Replicators + S-1-5-32-554: Builtin\Pre-Windows 2000 Compatible Access + S-1-5-32-555: Builtin\Remote Desktop Users + S-1-5-32-556: Builtin\Network Configuration Operators + S-1-5-32-557: Builtin\Incoming Forest Trust Builders + S-1-5-32-558: Builtin\Performance Monitor Users + S-1-5-32-559: Builtin\Performance Log Users + S-1-5-32-560: Builtin\Windows Authorization Access Group + S-1-5-32-561: Builtin\Terminal Server License Servers + S-1-5-32-562: Builtin\Distributed COM Users + S-1-5-32-569: Builtin\Cryptographic Operators + S-1-5-32-573: Builtin\Event Log Readers + S-1-5-32-574: Builtin\Certificate Service DCOM Access + S-1-5-32-575: Builtin\RDS Remote Access Servers + S-1-5-32-576: Builtin\RDS Endpoint Servers + S-1-5-32-577: Builtin\RDS Management Servers + S-1-5-32-578: Builtin\Hyper-V Administrators + S-1-5-32-579: Builtin\Access Control Assistance Operators + S-1-5-32-580: Builtin\Remote Management Users + S-1-5-32-582: Storage Replica Administrators + S-1-5-4: Interactive + S-1-5-5-X-Y: Logon Session + S-1-5-6: Service + S-1-5-64-10: NTLM Authentication + S-1-5-64-14: SChannel Authentication + S-1-5-64-21: Digest Authentication + S-1-5-7: Anonymous + S-1-5-8: Proxy + S-1-5-80: NT Service + S-1-5-80-0: All Services + S-1-5-83-0: NT Virtual Machine\Virtual Machines + S-1-5-9: Enterprise Domain Controllers + S-1-5-90-0: Windows Manager\Windows Manager Group + AceTypes: + A: Access Allowed + D: Access Denied + OA: Object Access Allowed + OD: Object Access Denied + AU: System Audit + AL: System Alarm + OU: System Object Audit + OL: System Object Alarm + ML: System Mandatory Label + SP: Central Policy ID + DomainSpecificSID: + "498": Enterprise Read-only Domain Controllers + "500": Administrator + "501": Guest + "502": KRBTGT + "512": Domain Admins + "513": Domain Users + "514": Domain Guests + "515": Domain Computers + "516": Domain Controllers + "517": Cert Publishers + "518": Schema Admins + "519": Enterprise Admins + "520": Group Policy Creator Owners + "521": Read-only Domain Controllers + "522": Cloneable Domain Controllers + "526": Key Admins + "527": Enterprise Key Admins + "553": RAS and IAS Servers + "571": Allowed RODC Password Replication Group + "572": Denied RODC Password Replication Group + PermissionDescription: + GA: Generic All + GR: Generic Read + GW: Generic Write + GX: Generic Execute + RC: Read Permissions + SD: Delete + WD: Modify Permissions + WO: Modify Owner + RP: Read All Properties + WP: Write All Properties + CC: Create All Child Objects + DC: Delete All Child Objects + LC: List Contents + SW: All Validated + LO: List Object + DT: Delete Subtree + CR: All Extended Rights + FA: File All Access + FR: File Generic Read + FX: FILE GENERIC EXECUTE + FW: FILE GENERIC WRITE + KA: KEY ALL ACCESS + KR: KEY READ + KW: KEY WRITE + KX: KEY EXECUTE + PermsFlags: + "0x80000000": 'Generic Read' + "0x4000000": 'Generic Write' + "0x20000000": 'Generic Execute' + "0x10000000": 'Generic All' + "0x02000000": 'Maximum Allowed' + "0x01000000": 'Access System Security' + "0x00100000": 'Syncronize' + "0x00080000": 'Write Owner' + "0x00040000": 'Write DACL' + "0x00020000": 'Read Control' + "0x00010000": 'Delete' + source: |- + ArrayList translatePermissionMask(def mask, def params) { + ArrayList al = new ArrayList(); + Long permCode = Long.decode(mask); + for (entry in params.PermsFlags.entrySet()) { + Long permFlag = Long.decode(entry.getKey()); + if ((permCode.longValue() & permFlag.longValue()) == permFlag.longValue()) { + al.add(entry.getValue()); + } + } + if (al.length == 0) { + al.add(mask); + } + return al; + } + + HashMap translateACL(def dacl, def params) { + def aceArray = dacl.splitOnToken(";"); + HashMap hm = new HashMap(); + + if (aceArray.length >= 6 ) { + hm.put("grantee", translateSID(aceArray[5], params)); + } + + if (aceArray.length >= 1) { + hm.put("type", params.AceTypes[aceArray[0]]); + } + + if (aceArray.length >= 3) { + if (aceArray[2].startsWith("0x")) { + hm.put("perms", translatePermissionMask(aceArray[2], params)); + } else { + ArrayList al = new ArrayList(); + Pattern permPattern = /.{1,2}/; + Matcher permMatcher = permPattern.matcher(aceArray[2]); + while (permMatcher.find()) { + al.add(params.PermissionDescription[permMatcher.group(0)]); + } + hm.put("perms", al); + } + } + return hm; + } + String translateSID(def sid, def params) { + if (!params.AccountSIDDescription.containsKey(sid)) { + if (sid.startsWith("S-1-5-21")) { + Pattern uidPattern = /[0-9]{1,5}$/; + Matcher uidMatcher = uidPattern.matcher(sid); + if (uidMatcher.find()) { + return params.DomainSpecificSID[uidMatcher.group(0)]; + } + return sid; + } + return sid; + } + return params.AccountSIDDescription[sid]; + } + + void enrichSDDL(def sddlStr, def Sd, def params, def ctx) { + Pattern sdOwnerPattern = /^O\:[A-Z]{2}/; + Matcher sdOwnerMatcher = sdOwnerPattern.matcher(sddlStr); + if (sdOwnerMatcher.find()) { + ctx.winlog.event_data.put(Sd + "Owner", translateSID(sdOwnerMatcher.group(0), params)); + } + + Pattern sdGroupPattern = /^G\:[A-Z]{2}/; + Matcher sdGroupMatcher = sdGroupPattern.matcher(sddlStr); + if (sdGroupMatcher.find()) { + ctx.winlog.event_data.put(Sd + "Group", translateSID(sdGroupMatcher.group(0), params)); + } + + Pattern sdDaclPattern = /(D:([A-Z]*(\(.*\))*))/; + Matcher sdDaclMatcher = sdDaclPattern.matcher(sddlStr); + if (sdDaclMatcher.find()) { + Pattern dacListPattern = /\([^*\)]*\)/; + Matcher dacListMatcher = dacListPattern.matcher(sdDaclMatcher.group(1)); + for (def i = 0; dacListMatcher.find(); i++) { + def newDacl = translateACL(dacListMatcher.group(0).replace("(","").replace(")",""), params); + ctx.winlog.event_data.put(Sd + "Dacl" + i.toString(), newDacl['grantee'] + " :" + newDacl['type'] + " (" + newDacl['perms'] + ")"); + if (["Administrator", "Guest", "KRBTGT"].contains(newDacl['grantee'])) { + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + if (!ctx.related.user.contains(newDacl['grantee'])) { + ctx.related.user.add(newDacl['grantee']); + } + } + } + } + + Pattern sdSaclPattern = /(S:([A-Z]*(\(.*\))*))?$/; + Matcher sdSaclMatcher = sdSaclPattern.matcher(sddlStr); + if (sdSaclMatcher.find()) { + Pattern sacListPattern = /\([^*\)]*\)/; + Matcher sacListMatcher = sacListPattern.matcher(sdSaclMatcher.group(0)); + for (def i = 0; sacListMatcher.find(); i++) { + def newSacl = translateACL(sacListMatcher.group(0).replace("(","").replace(")",""), params); + ctx.winlog.event_data.put(Sd + "Sacl" + i.toString(), newSacl['grantee'] + " :" + newSacl['type'] + " (" + newSacl['perms'] + ")"); + if (["Administrator", "Guest", "KRBTGT"].contains(newSacl['grantee'])) { + if (ctx?.related == null) { + HashMap hm = new HashMap(); + ctx.put("related", hm); + } + if (ctx?.related?.user == null) { + ArrayList al = new ArrayList(); + ctx.related.put("user", al); + } + if (!ctx.related.user.contains(newSacl['grantee'])) { + ctx.related.user.add(newSacl['grantee']); + } + } + } + } + } + + void splitSidList(def sids, def params, def ctx) { + ArrayList al = new ArrayList(); + def sidList = sids.splitOnToken(" "); + ctx.winlog.event_data.put("SidList", sidList); + for (def i = 0; i < sidList.length; i++ ) { + al.add(translateSID(sidList[i].replace("%", "").replace("{", "").replace("}", "").replace(" ",""), params)); + } + ctx.winlog.event_data.put("SidListDesc", al); + } + + if (ctx?.event?.code == null || + !["4670", "4817", "4907", "4908"].contains(ctx.event.code)) { + return; + } + if (ctx?.winlog?.event_data?.OldSd != null) { + enrichSDDL(ctx.winlog.event_data.OldSd, "OldSd", params, ctx); + } + if (ctx?.winlog?.event_data?.NewSd != null) { + enrichSDDL(ctx.winlog.event_data.NewSd, "NewSd", params, ctx); + } + if (ctx?.winlog?.event_data?.SidList != null) { + splitSidList(ctx.winlog.event_data.SidList, params, ctx); + } + + - convert: + field: winlog.record_id + type: string + ignore_missing: true + + - convert: + field: winlog.event_id + type: string + ignore_missing: true + + - set: + field: ecs.version + value: '1.12.0' + + - set: + field: log.level + copy_from: winlog.level + ignore_empty_value: true + ignore_failure: true + if: ctx?.winlog?.level != "" + + - date: + field: winlog.time_created + formats: + - ISO8601 + ignore_failure: true + if: ctx?.winlog?.time_created != null + + - remove: + field: event.original + if: "ctx?.tags == null || !(ctx.tags.contains('preserve_original_event'))" + ignore_failure: true + ignore_missing: true + +on_failure: + - set: + field: error.message + value: |- + Processor "{{ _ingest.on_failure_processor_type }}" with tag "{{ _ingest.on_failure_processor_tag }}" in pipeline "{{ _ingest.on_failure_pipeline }}" failed with message "{{ _ingest.on_failure_message }}" diff --git a/x-pack/winlogbeat/module/security/test/security_windows_test.go b/x-pack/winlogbeat/module/security/test/security_windows_test.go deleted file mode 100644 index 79c8d36cc59c..000000000000 --- a/x-pack/winlogbeat/module/security/test/security_windows_test.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License; -// you may not use this file except in compliance with the Elastic License. - -package test - -import ( - "testing" - - "github.com/elastic/beats/v7/x-pack/winlogbeat/module" - - // Register required processors. - _ "github.com/elastic/beats/v7/libbeat/cmd/instance" - _ "github.com/elastic/beats/v7/libbeat/processors/timestamp" -) - -// Ignore these fields because they can be different on different versions -// of windows. -var ignoreFields = []string{ - "message", -} - -func TestSecurity(t *testing.T) { - module.TestPipeline(t, "testdata/*.evtx", "../config/winlogbeat-security.js", - module.WithFieldFilter(ignoreFields)) -} diff --git a/x-pack/winlogbeat/module/sysmon/config/winlogbeat-sysmon.js b/x-pack/winlogbeat/module/sysmon/config/winlogbeat-sysmon.js deleted file mode 100644 index c91649249f64..000000000000 --- a/x-pack/winlogbeat/module/sysmon/config/winlogbeat-sysmon.js +++ /dev/null @@ -1,1802 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License; -// you may not use this file except in compliance with the Elastic License. - -// Polyfill for String startsWith. -if (!String.prototype.startsWith) { - Object.defineProperty(String.prototype, "startsWith", { - value: function (search, pos) { - pos = !pos || pos < 0 ? 0 : +pos; - return this.substring(pos, pos + search.length) === search; - }, - }); -} - -var sysmon = (function () { - var path = require("path"); - var processor = require("processor"); - var windows = require("windows"); - var net = require("net"); - - // Windows error codes for DNS. This list was generated using - // 'go run gen_dns_error_codes.go'. - var dnsQueryStatusCodes = { - "0": "SUCCESS", - "5": "ERROR_ACCESS_DENIED", - "8": "ERROR_NOT_ENOUGH_MEMORY", - "13": "ERROR_INVALID_DATA", - "14": "ERROR_OUTOFMEMORY", - "123": "ERROR_INVALID_NAME", - "1214": "ERROR_INVALID_NETNAME", - "1223": "ERROR_CANCELLED", - "1460": "ERROR_TIMEOUT", - "4312": "ERROR_OBJECT_NOT_FOUND", - "9001": "DNS_ERROR_RCODE_FORMAT_ERROR", - "9002": "DNS_ERROR_RCODE_SERVER_FAILURE", - "9003": "DNS_ERROR_RCODE_NAME_ERROR", - "9004": "DNS_ERROR_RCODE_NOT_IMPLEMENTED", - "9005": "DNS_ERROR_RCODE_REFUSED", - "9006": "DNS_ERROR_RCODE_YXDOMAIN", - "9007": "DNS_ERROR_RCODE_YXRRSET", - "9008": "DNS_ERROR_RCODE_NXRRSET", - "9009": "DNS_ERROR_RCODE_NOTAUTH", - "9010": "DNS_ERROR_RCODE_NOTZONE", - "9016": "DNS_ERROR_RCODE_BADSIG", - "9017": "DNS_ERROR_RCODE_BADKEY", - "9018": "DNS_ERROR_RCODE_BADTIME", - "9101": "DNS_ERROR_KEYMASTER_REQUIRED", - "9102": "DNS_ERROR_NOT_ALLOWED_ON_SIGNED_ZONE", - "9103": "DNS_ERROR_NSEC3_INCOMPATIBLE_WITH_RSA_SHA1", - "9104": "DNS_ERROR_NOT_ENOUGH_SIGNING_KEY_DESCRIPTORS", - "9105": "DNS_ERROR_UNSUPPORTED_ALGORITHM", - "9106": "DNS_ERROR_INVALID_KEY_SIZE", - "9107": "DNS_ERROR_SIGNING_KEY_NOT_ACCESSIBLE", - "9108": "DNS_ERROR_KSP_DOES_NOT_SUPPORT_PROTECTION", - "9109": "DNS_ERROR_UNEXPECTED_DATA_PROTECTION_ERROR", - "9110": "DNS_ERROR_UNEXPECTED_CNG_ERROR", - "9111": "DNS_ERROR_UNKNOWN_SIGNING_PARAMETER_VERSION", - "9112": "DNS_ERROR_KSP_NOT_ACCESSIBLE", - "9113": "DNS_ERROR_TOO_MANY_SKDS", - "9114": "DNS_ERROR_INVALID_ROLLOVER_PERIOD", - "9115": "DNS_ERROR_INVALID_INITIAL_ROLLOVER_OFFSET", - "9116": "DNS_ERROR_ROLLOVER_IN_PROGRESS", - "9117": "DNS_ERROR_STANDBY_KEY_NOT_PRESENT", - "9118": "DNS_ERROR_NOT_ALLOWED_ON_ZSK", - "9119": "DNS_ERROR_NOT_ALLOWED_ON_ACTIVE_SKD", - "9120": "DNS_ERROR_ROLLOVER_ALREADY_QUEUED", - "9121": "DNS_ERROR_NOT_ALLOWED_ON_UNSIGNED_ZONE", - "9122": "DNS_ERROR_BAD_KEYMASTER", - "9123": "DNS_ERROR_INVALID_SIGNATURE_VALIDITY_PERIOD", - "9124": "DNS_ERROR_INVALID_NSEC3_ITERATION_COUNT", - "9125": "DNS_ERROR_DNSSEC_IS_DISABLED", - "9126": "DNS_ERROR_INVALID_XML", - "9127": "DNS_ERROR_NO_VALID_TRUST_ANCHORS", - "9128": "DNS_ERROR_ROLLOVER_NOT_POKEABLE", - "9129": "DNS_ERROR_NSEC3_NAME_COLLISION", - "9130": "DNS_ERROR_NSEC_INCOMPATIBLE_WITH_NSEC3_RSA_SHA1", - "9501": "DNS_INFO_NO_RECORDS", - "9502": "DNS_ERROR_BAD_PACKET", - "9503": "DNS_ERROR_NO_PACKET", - "9504": "DNS_ERROR_RCODE", - "9505": "DNS_ERROR_UNSECURE_PACKET", - "9506": "DNS_REQUEST_PENDING", - "9551": "DNS_ERROR_INVALID_TYPE", - "9552": "DNS_ERROR_INVALID_IP_ADDRESS", - "9553": "DNS_ERROR_INVALID_PROPERTY", - "9554": "DNS_ERROR_TRY_AGAIN_LATER", - "9555": "DNS_ERROR_NOT_UNIQUE", - "9556": "DNS_ERROR_NON_RFC_NAME", - "9557": "DNS_STATUS_FQDN", - "9558": "DNS_STATUS_DOTTED_NAME", - "9559": "DNS_STATUS_SINGLE_PART_NAME", - "9560": "DNS_ERROR_INVALID_NAME_CHAR", - "9561": "DNS_ERROR_NUMERIC_NAME", - "9562": "DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER", - "9563": "DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION", - "9564": "DNS_ERROR_CANNOT_FIND_ROOT_HINTS", - "9565": "DNS_ERROR_INCONSISTENT_ROOT_HINTS", - "9566": "DNS_ERROR_DWORD_VALUE_TOO_SMALL", - "9567": "DNS_ERROR_DWORD_VALUE_TOO_LARGE", - "9568": "DNS_ERROR_BACKGROUND_LOADING", - "9569": "DNS_ERROR_NOT_ALLOWED_ON_RODC", - "9570": "DNS_ERROR_NOT_ALLOWED_UNDER_DNAME", - "9571": "DNS_ERROR_DELEGATION_REQUIRED", - "9572": "DNS_ERROR_INVALID_POLICY_TABLE", - "9573": "DNS_ERROR_ADDRESS_REQUIRED", - "9601": "DNS_ERROR_ZONE_DOES_NOT_EXIST", - "9602": "DNS_ERROR_NO_ZONE_INFO", - "9603": "DNS_ERROR_INVALID_ZONE_OPERATION", - "9604": "DNS_ERROR_ZONE_CONFIGURATION_ERROR", - "9605": "DNS_ERROR_ZONE_HAS_NO_SOA_RECORD", - "9606": "DNS_ERROR_ZONE_HAS_NO_NS_RECORDS", - "9607": "DNS_ERROR_ZONE_LOCKED", - "9608": "DNS_ERROR_ZONE_CREATION_FAILED", - "9609": "DNS_ERROR_ZONE_ALREADY_EXISTS", - "9610": "DNS_ERROR_AUTOZONE_ALREADY_EXISTS", - "9611": "DNS_ERROR_INVALID_ZONE_TYPE", - "9612": "DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP", - "9613": "DNS_ERROR_ZONE_NOT_SECONDARY", - "9614": "DNS_ERROR_NEED_SECONDARY_ADDRESSES", - "9615": "DNS_ERROR_WINS_INIT_FAILED", - "9616": "DNS_ERROR_NEED_WINS_SERVERS", - "9617": "DNS_ERROR_NBSTAT_INIT_FAILED", - "9618": "DNS_ERROR_SOA_DELETE_INVALID", - "9619": "DNS_ERROR_FORWARDER_ALREADY_EXISTS", - "9620": "DNS_ERROR_ZONE_REQUIRES_MASTER_IP", - "9621": "DNS_ERROR_ZONE_IS_SHUTDOWN", - "9622": "DNS_ERROR_ZONE_LOCKED_FOR_SIGNING", - "9651": "DNS_ERROR_PRIMARY_REQUIRES_DATAFILE", - "9652": "DNS_ERROR_INVALID_DATAFILE_NAME", - "9653": "DNS_ERROR_DATAFILE_OPEN_FAILURE", - "9654": "DNS_ERROR_FILE_WRITEBACK_FAILED", - "9655": "DNS_ERROR_DATAFILE_PARSING", - "9701": "DNS_ERROR_RECORD_DOES_NOT_EXIST", - "9702": "DNS_ERROR_RECORD_FORMAT", - "9703": "DNS_ERROR_NODE_CREATION_FAILED", - "9704": "DNS_ERROR_UNKNOWN_RECORD_TYPE", - "9705": "DNS_ERROR_RECORD_TIMED_OUT", - "9706": "DNS_ERROR_NAME_NOT_IN_ZONE", - "9707": "DNS_ERROR_CNAME_LOOP", - "9708": "DNS_ERROR_NODE_IS_CNAME", - "9709": "DNS_ERROR_CNAME_COLLISION", - "9710": "DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT", - "9711": "DNS_ERROR_RECORD_ALREADY_EXISTS", - "9712": "DNS_ERROR_SECONDARY_DATA", - "9713": "DNS_ERROR_NO_CREATE_CACHE_DATA", - "9714": "DNS_ERROR_NAME_DOES_NOT_EXIST", - "9715": "DNS_WARNING_PTR_CREATE_FAILED", - "9716": "DNS_WARNING_DOMAIN_UNDELETED", - "9717": "DNS_ERROR_DS_UNAVAILABLE", - "9718": "DNS_ERROR_DS_ZONE_ALREADY_EXISTS", - "9719": "DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE", - "9720": "DNS_ERROR_NODE_IS_DNAME", - "9721": "DNS_ERROR_DNAME_COLLISION", - "9722": "DNS_ERROR_ALIAS_LOOP", - "9751": "DNS_INFO_AXFR_COMPLETE", - "9752": "DNS_ERROR_AXFR", - "9753": "DNS_INFO_ADDED_LOCAL_WINS", - "9801": "DNS_STATUS_CONTINUE_NEEDED", - "9851": "DNS_ERROR_NO_TCPIP", - "9852": "DNS_ERROR_NO_DNS_SERVERS", - "9901": "DNS_ERROR_DP_DOES_NOT_EXIST", - "9902": "DNS_ERROR_DP_ALREADY_EXISTS", - "9903": "DNS_ERROR_DP_NOT_ENLISTED", - "9904": "DNS_ERROR_DP_ALREADY_ENLISTED", - "9905": "DNS_ERROR_DP_NOT_AVAILABLE", - "9906": "DNS_ERROR_DP_FSMO_ERROR", - "9911": "DNS_ERROR_RRL_NOT_ENABLED", - "9912": "DNS_ERROR_RRL_INVALID_WINDOW_SIZE", - "9913": "DNS_ERROR_RRL_INVALID_IPV4_PREFIX", - "9914": "DNS_ERROR_RRL_INVALID_IPV6_PREFIX", - "9915": "DNS_ERROR_RRL_INVALID_TC_RATE", - "9916": "DNS_ERROR_RRL_INVALID_LEAK_RATE", - "9917": "DNS_ERROR_RRL_LEAK_RATE_LESSTHAN_TC_RATE", - "9921": "DNS_ERROR_VIRTUALIZATION_INSTANCE_ALREADY_EXISTS", - "9922": "DNS_ERROR_VIRTUALIZATION_INSTANCE_DOES_NOT_EXIST", - "9923": "DNS_ERROR_VIRTUALIZATION_TREE_LOCKED", - "9924": "DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME", - "9925": "DNS_ERROR_DEFAULT_VIRTUALIZATION_INSTANCE", - "9951": "DNS_ERROR_ZONESCOPE_ALREADY_EXISTS", - "9952": "DNS_ERROR_ZONESCOPE_DOES_NOT_EXIST", - "9953": "DNS_ERROR_DEFAULT_ZONESCOPE", - "9954": "DNS_ERROR_INVALID_ZONESCOPE_NAME", - "9955": "DNS_ERROR_NOT_ALLOWED_WITH_ZONESCOPES", - "9956": "DNS_ERROR_LOAD_ZONESCOPE_FAILED", - "9957": "DNS_ERROR_ZONESCOPE_FILE_WRITEBACK_FAILED", - "9958": "DNS_ERROR_INVALID_SCOPE_NAME", - "9959": "DNS_ERROR_SCOPE_DOES_NOT_EXIST", - "9960": "DNS_ERROR_DEFAULT_SCOPE", - "9961": "DNS_ERROR_INVALID_SCOPE_OPERATION", - "9962": "DNS_ERROR_SCOPE_LOCKED", - "9963": "DNS_ERROR_SCOPE_ALREADY_EXISTS", - "9971": "DNS_ERROR_POLICY_ALREADY_EXISTS", - "9972": "DNS_ERROR_POLICY_DOES_NOT_EXIST", - "9973": "DNS_ERROR_POLICY_INVALID_CRITERIA", - "9974": "DNS_ERROR_POLICY_INVALID_SETTINGS", - "9975": "DNS_ERROR_CLIENT_SUBNET_IS_ACCESSED", - "9976": "DNS_ERROR_CLIENT_SUBNET_DOES_NOT_EXIST", - "9977": "DNS_ERROR_CLIENT_SUBNET_ALREADY_EXISTS", - "9978": "DNS_ERROR_SUBNET_DOES_NOT_EXIST", - "9979": "DNS_ERROR_SUBNET_ALREADY_EXISTS", - "9980": "DNS_ERROR_POLICY_LOCKED", - "9981": "DNS_ERROR_POLICY_INVALID_WEIGHT", - "9982": "DNS_ERROR_POLICY_INVALID_NAME", - "9983": "DNS_ERROR_POLICY_MISSING_CRITERIA", - "9984": "DNS_ERROR_INVALID_CLIENT_SUBNET_NAME", - "9985": "DNS_ERROR_POLICY_PROCESSING_ORDER_INVALID", - "9986": "DNS_ERROR_POLICY_SCOPE_MISSING", - "9987": "DNS_ERROR_POLICY_SCOPE_NOT_ALLOWED", - "9988": "DNS_ERROR_SERVERSCOPE_IS_REFERENCED", - "9989": "DNS_ERROR_ZONESCOPE_IS_REFERENCED", - "9990": "DNS_ERROR_POLICY_INVALID_CRITERIA_CLIENT_SUBNET", - "9991": "DNS_ERROR_POLICY_INVALID_CRITERIA_TRANSPORT_PROTOCOL", - "9992": "DNS_ERROR_POLICY_INVALID_CRITERIA_NETWORK_PROTOCOL", - "9993": "DNS_ERROR_POLICY_INVALID_CRITERIA_INTERFACE", - "9994": "DNS_ERROR_POLICY_INVALID_CRITERIA_FQDN", - "9995": "DNS_ERROR_POLICY_INVALID_CRITERIA_QUERY_TYPE", - "9996": "DNS_ERROR_POLICY_INVALID_CRITERIA_TIME_OF_DAY", - "10054": "WSAECONNRESET", - "10055": "WSAENOBUFS", - "10060": "WSAETIMEDOUT", - }; - - // Windows DNS record type constants. - // https://docs.microsoft.com/en-us/windows/win32/dns/dns-constants - var dnsRecordTypes = { - "1": "A", - "2": "NS", - "3": "MD", - "4": "MF", - "5": "CNAME", - "6": "SOA", - "7": "MB", - "8": "MG", - "9": "MR", - "10": "NULL", - "11": "WKS", - "12": "PTR", - "13": "HINFO", - "14": "MINFO", - "15": "MX", - "16": "TXT", - "17": "RP", - "18": "AFSDB", - "19": "X25", - "20": "ISDN", - "21": "RT", - "22": "NSAP", - "23": "NSAPPTR", - "24": "SIG", - "25": "KEY", - "26": "PX", - "27": "GPOS", - "28": "AAAA", - "29": "LOC", - "30": "NXT", - "31": "EID", - "32": "NIMLOC", - "33": "SRV", - "34": "ATMA", - "35": "NAPTR", - "36": "KX", - "37": "CERT", - "38": "A6", - "39": "DNAME", - "40": "SINK", - "41": "OPT", - "43": "DS", - "46": "RRSIG", - "47": "NSEC", - "48": "DNSKEY", - "49": "DHCID", - "100": "UINFO", - "101": "UID", - "102": "GID", - "103": "UNSPEC", - "248": "ADDRS", - "249": "TKEY", - "250": "TSIG", - "251": "IXFR", - "252": "AXFR", - "253": "MAILB", - "254": "MAILA", - "255": "ANY", - "65281": "WINS", - "65282": "WINSR", - }; - - var setProcessNameUsingExe = function (evt) { - setProcessNameFromPath(evt, "process.executable", "process.name"); - }; - - var setParentProcessNameUsingExe = function (evt) { - setProcessNameFromPath( - evt, - "process.parent.executable", - "process.parent.name" - ); - }; - - var setProcessNameFromPath = function (evt, pathField, nameField) { - var name = evt.Get(nameField); - if (name) { - return; - } - var exe = evt.Get(pathField); - if (!exe) { - return; - } - evt.Put(nameField, path.basename(exe)); - }; - - var splitCommandLine = function (evt, source, target) { - var commandLine = evt.Get(source); - if (!commandLine) { - return; - } - evt.Put(target, windows.splitCommandLine(commandLine)); - }; - - var splitProcessArgs = function (evt) { - splitCommandLine(evt, "process.command_line", "process.args"); - }; - - var splitParentProcessArgs = function (evt) { - splitCommandLine( - evt, - "process.parent.command_line", - "process.parent.args" - ); - }; - - var addUser = function (evt) { - var id = evt.Get("winlog.user.identifier"); - if (id) { - evt.Put("user.id", id); - } - var userParts = evt.Get("winlog.event_data.User"); - if (!userParts) { - return; - } - userParts = userParts.split("\\"); - if (userParts.length === 2) { - evt.Put("user.domain", userParts[0]); - evt.Put("user.name", userParts[1]); - evt.AppendTo("related.user", userParts[1]); - evt.Delete("winlog.event_data.User"); - } - }; - - var setRuleName = function (evt) { - var ruleName = evt.Get("winlog.event_data.RuleName"); - evt.Delete("winlog.event_data.RuleName"); - - if (!ruleName || ruleName === "-") { - return; - } - - evt.Put("rule.name", ruleName); - }; - - var addNetworkDirection = function (evt) { - switch (evt.Get("winlog.event_data.Initiated")) { - case "true": - evt.Put("network.direction", "egress"); - break; - case "false": - evt.Put("network.direction", "ingress"); - break; - } - evt.Delete("winlog.event_data.Initiated"); - }; - - var addNetworkType = function (evt) { - switch (evt.Get("winlog.event_data.SourceIsIpv6")) { - case "true": - evt.Put("network.type", "ipv6"); - break; - case "false": - evt.Put("network.type", "ipv4"); - break; - } - evt.Delete("winlog.event_data.SourceIsIpv6"); - evt.Delete("winlog.event_data.DestinationIsIpv6"); - }; - - var setRelatedIP = function (evt) { - var sourceIP = evt.Get("source.ip"); - if (sourceIP) { - evt.AppendTo("related.ip", sourceIP); - } - - var destIP = evt.Get("destination.ip"); - if (destIP) { - evt.AppendTo("related.ip", destIP); - } - }; - - var getHashPath = function (namespace, hashKey) { - if (hashKey === "imphash") { - return namespace + ".pe.imphash"; - } - - return namespace + ".hash." + hashKey; - }; - - var emptyHashRegex = /^0*$/; - - var hashIsEmpty = function (value) { - if (!value) { - return true; - } - - return emptyHashRegex.test(value); - } - - // Adds hashes from the given hashField in the event to the 'hash' key - // in the specified namespace. It also adds all the hashes to 'related.hash'. - var addHashes = function (evt, namespace, hashField) { - var hashes = evt.Get(hashField); - if (!hashes) { - return; - } - evt.Delete(hashField); - hashes.split(",").forEach(function (hash) { - var parts = hash.split("="); - if (parts.length !== 2) { - return; - } - - var key = parts[0].toLowerCase(); - var value = parts[1].toLowerCase(); - - if (hashIsEmpty(value)) { - return; - } - - var path = getHashPath(namespace, key); - - evt.Put(path, value); - evt.AppendTo("related.hash", value); - }); - }; - - var splitFileHashes = function (evt) { - addHashes(evt, "file", "winlog.event_data.Hashes"); - }; - - var splitFileHash = function (evt) { - addHashes(evt, "file", "winlog.event_data.Hash"); - }; - - var splitProcessHashes = function (evt) { - addHashes(evt, "process", "winlog.event_data.Hashes"); - }; - - var removeEmptyEventData = function (evt) { - var eventData = evt.Get("winlog.event_data"); - if (eventData && Object.keys(eventData).length === 0) { - evt.Delete("winlog.event_data"); - } - }; - - var translateDnsQueryStatus = function (evt) { - var statusCode = evt.Get("sysmon.dns.status"); - if (!statusCode) { - return; - } - var statusName = dnsQueryStatusCodes[statusCode]; - if (statusName === undefined) { - return; - } - evt.Put("sysmon.dns.status", statusName); - }; - - // Splits the QueryResults field that contains the DNS responses. - // Example: "type: 5 f2.taboola.map.fastly.net;::ffff:151.101.66.2;::ffff:151.101.130.2;::ffff:151.101.194.2;::ffff:151.101.2.2;" - var splitDnsQueryResults = function (evt) { - var results = evt.Get("winlog.event_data.QueryResults"); - if (!results) { - return; - } - results = results.split(";"); - - var answers = []; - var ips = []; - for (var i = 0; i < results.length; i++) { - var answer = results[i]; - if (!answer) { - continue; - } - - if (answer.startsWith("type:")) { - var parts = answer.split(/\s+/); - if (parts.length !== 3) { - throw "unexpected QueryResult format"; - } - - answers.push({ - type: dnsRecordTypes[parts[1]], - data: parts[2], - }); - } else { - // Convert V4MAPPED addresses. - answer = answer.replace("::ffff:", ""); - if (net.isIP(answer)) { - ips.push(answer); - - // Synthesize record type based on IP address type. - var type = "A"; - if (answer.indexOf(":") !== -1) { - type = "AAAA"; - } - answers.push({ - type: type, - data: answer, - }); - } - } - } - - if (answers.length > 0) { - evt.Put("dns.answers", answers); - } - if (ips.length > 0) { - evt.Put("dns.resolved_ip", ips); - } - evt.Delete("winlog.event_data.QueryResults"); - }; - - var parseUtcTime = new processor.Timestamp({ - field: "winlog.event_data.UtcTime", - target_field: "winlog.event_data.UtcTime", - timezone: "UTC", - layouts: ["2006-01-02 15:04:05.999"], - tests: ["2019-06-26 21:19:43.237"], - ignore_missing: true, - }); - - var setAdditionalSignatureFields = function (evt) { - var signed = evt.Get("winlog.event_data.Signed"); - if (!signed) { - return; - } - evt.Put("file.code_signature.signed", true); - var signatureStatus = evt.Get("winlog.event_data.SignatureStatus"); - evt.Put("file.code_signature.valid", signatureStatus === "Valid"); - }; - - var setAdditionalFileFieldsFromPath = function (evt) { - var filePath = evt.Get("file.path"); - if (!filePath) { - return; - } - - evt.Put("file.name", path.basename(filePath)); - evt.Put("file.directory", path.dirname(filePath)); - - // path returns extensions with a preceding ., e.g.: .tmp, .png - // according to ecs the expected format is without it, so we need to remove it. - var ext = path.extname(filePath); - if (!ext) { - return; - } - - if (ext.charAt(0) === ".") { - ext = ext.substr(1); - } - evt.Put("file.extension", ext); - }; - - // https://docs.microsoft.com/en-us/windows/win32/sysinfo/registry-hives - var commonRegistryHives = { - HKEY_CLASSES_ROOT: "HKCR", - HKCR: "HKCR", - HKEY_CURRENT_CONFIG: "HKCC", - HKCC: "HKCC", - HKEY_CURRENT_USER: "HKCU", - HKCU: "HKCU", - HKEY_DYN_DATA: "HKDD", - HKDD: "HKDD", - HKEY_LOCAL_MACHINE: "HKLM", - HKLM: "HKLM", - HKEY_PERFORMANCE_DATA: "HKPD", - HKPD: "HKPD", - HKEY_USERS: "HKU", - HKU: "HKU", - }; - - var qwordRegex = new RegExp(/QWORD \(((0x\d{8})-(0x\d{8}))\)/, "i"); - var dwordRegex = new RegExp(/DWORD \((0x\d{8})\)/, "i"); - - var setRegistryFields = function (evt) { - var path = evt.Get("winlog.event_data.TargetObject"); - if (!path) { - return; - } - evt.Put("registry.path", path); - var pathTokens = path.split("\\"); - var hive = commonRegistryHives[pathTokens[0]]; - if (hive) { - evt.Put("registry.hive", hive); - pathTokens.splice(0, 1); - if (pathTokens.length > 0) { - evt.Put("registry.key", pathTokens.join("\\")); - } - } - var value = pathTokens[pathTokens.length - 1]; - evt.Put("registry.value", value); - var data = evt.Get("winlog.event_data.Details"); - if (!data) { - return; - } - // sysmon only returns details of a registry modification - // if it's a qword or dword - var dataType; - var dataValue; - var match = qwordRegex.exec(data); - if (match && match.length > 0) { - var parsedHighByte = parseInt(match[2]); - var parsedLowByte = parseInt(match[3]); - if (!isNaN(parsedHighByte) && !isNaN(parsedLowByte)) { - dataValue = "" + ((parsedHighByte << 8) + parsedLowByte); - dataType = "SZ_QWORD"; - } - } else { - match = dwordRegex.exec(data); - if (match && match.length > 0) { - var parsedValue = parseInt(match[1]); - if (!isNaN(parsedValue)) { - dataType = "SZ_DWORD"; - dataValue = "" + parsedValue; - } - } - } - if (dataType) { - evt.Put("registry.data.strings", [dataValue]); - evt.Put("registry.data.type", dataType); - } - }; - - // Event ID 1 - Process Create. - var event1 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["process"], - type: ["start", "process_start"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.CommandLine", - to: "process.command_line", - }, - { - from: "winlog.event_data.CurrentDirectory", - to: "process.working_directory", - }, - { - from: "winlog.event_data.ParentProcessGuid", - to: "process.parent.entity_id", - }, - { - from: "winlog.event_data.ParentProcessId", - to: "process.parent.pid", - type: "long", - }, - { - from: "winlog.event_data.ParentImage", - to: "process.parent.executable", - }, - { - from: "winlog.event_data.ParentCommandLine", - to: "process.parent.command_line", - }, - { - from: "winlog.event_data.OriginalFileName", - to: "process.pe.original_file_name", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Convert({ - fields: [{ - from: "winlog.event_data.Company", - to: "process.pe.company", - }, - { - from: "winlog.event_data.Description", - to: "process.pe.description", - }, - { - from: "winlog.event_data.FileVersion", - to: "process.pe.file_version", - }, - { - from: "winlog.event_data.Product", - to: "process.pe.product", - }, - ], - mode: "copy", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setProcessNameUsingExe) - .Add(splitProcessArgs) - .Add(addUser) - .Add(splitProcessHashes) - .Add(setParentProcessNameUsingExe) - .Add(splitParentProcessArgs) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 2 - File creation time changed. - var event2 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["file"], - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.TargetFilename", - to: "file.path", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setAdditionalFileFieldsFromPath) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 3 - Network connection detected. - var event3 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["network"], - type: ["connection", "start", "protocol"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.Protocol", - to: "network.transport", - }, - { - from: "winlog.event_data.SourceIp", - to: "source.ip", - type: "ip", - }, - { - from: "winlog.event_data.SourceHostname", - to: "source.domain", - type: "string", - }, - { - from: "winlog.event_data.SourcePort", - to: "source.port", - type: "long", - }, - { - from: "winlog.event_data.DestinationIp", - to: "destination.ip", - type: "ip", - }, - { - from: "winlog.event_data.DestinationHostname", - to: "destination.domain", - type: "string", - }, - { - from: "winlog.event_data.DestinationPort", - to: "destination.port", - type: "long", - }, - { - from: "winlog.event_data.DestinationPortName", - to: "network.protocol", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setRelatedIP) - .Add(setProcessNameUsingExe) - .Add(addUser) - .Add(addNetworkDirection) - .Add(addNetworkType) - .CommunityID() - .Add(removeEmptyEventData) - .Build(); - - // Event ID 4 - Sysmon service state changed. - var event4 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["process"], - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 5 - Process terminated. - var event5 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["process"], - type: ["end", "process_end"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 6 - Driver loaded. - var event6 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["driver"], - type: ["start"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ImageLoaded", - to: "file.path", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Convert({ - fields: [{ - from: "winlog.event_data.Signature", - to: "file.code_signature.subject_name", - }, - { - from: "winlog.event_data.SignatureStatus", - to: "file.code_signature.status", - }, - ], - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setAdditionalFileFieldsFromPath) - .Add(setAdditionalSignatureFields) - .Add(splitFileHashes) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 7 - Image loaded. - var event7 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["process"], - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.ImageLoaded", - to: "file.path", - }, - { - from: "winlog.event_data.OriginalFileName", - to: "file.pe.original_file_name", - }, - - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Convert({ - fields: [{ - from: "winlog.event_data.Signature", - to: "file.code_signature.subject_name", - }, - { - from: "winlog.event_data.SignatureStatus", - to: "file.code_signature.status", - }, - { - from: "winlog.event_data.Company", - to: "file.pe.company", - }, - { - from: "winlog.event_data.Description", - to: "file.pe.description", - }, - { - from: "winlog.event_data.FileVersion", - to: "file.pe.file_version", - }, - { - from: "winlog.event_data.Product", - to: "file.pe.product", - }, - ], - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setAdditionalFileFieldsFromPath) - .Add(setAdditionalSignatureFields) - .Add(setProcessNameUsingExe) - .Add(splitFileHashes) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 8 - CreateRemoteThread detected. - var event8 = new processor.Chain() - .Add(parseUtcTime) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.SourceProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.SourceProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.SourceImage", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 9 - RawAccessRead detected. - var event9 = new processor.Chain() - .Add(parseUtcTime) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.Device", - to: "file.path", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setAdditionalFileFieldsFromPath) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 10 - Process accessed. - var event10 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["process"], - type: ["access"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.SourceProcessGUID", - to: "process.entity_id", - }, - { - from: "winlog.event_data.SourceProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.SourceThreadId", - to: "process.thread.id", - type: "long", - }, - { - from: "winlog.event_data.SourceImage", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 11 - File created. - var event11 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["file"], - type: ["creation"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.TargetFilename", - to: "file.path", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setAdditionalFileFieldsFromPath) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 12 - Registry object added or deleted. - var event12 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["configuration", "registry"], - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setRegistryFields) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 13 - Registry value set. - var event13 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["configuration", "registry"], - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setRegistryFields) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 14 - Registry object renamed. - var event14 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["configuration", "registry"], - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setRegistryFields) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 15 - File stream created. - var event15 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["file"], - type: ["access"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.TargetFilename", - to: "file.path", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setAdditionalFileFieldsFromPath) - .Add(setProcessNameUsingExe) - .Add(splitFileHash) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 16 - Sysmon config state changed. - var event16 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["configuration"], - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 17 - Pipe Created. - var event17 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["file"], // pipes are files - type: ["creation"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.PipeName", - to: "file.name", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 18 - Pipe Connected. - var event18 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["file"], // pipes are files - type: ["access"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.PipeName", - to: "file.name", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 19 - WmiEventFilter activity detected. - var event19 = new processor.Chain() - .Add(parseUtcTime) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(addUser) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 20 - WmiEventConsumer activity detected. - var event20 = new processor.Chain() - .Add(parseUtcTime) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.Destination", - to: "process.executable", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(addUser) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 21 - WmiEventConsumerToFilter activity detected. - var event21 = new processor.Chain() - .Add(parseUtcTime) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(addUser) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 22 - DNSEvent (DNS query). - var event22 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["network"], - type: ["connection", "protocol", "info"], - }, - target: "event", - }) - .AddFields({ - fields: { - protocol: "dns", - }, - target: "network", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.QueryName", - to: "dns.question.name", - }, - { - from: "winlog.event_data.QueryStatus", - to: "sysmon.dns.status", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .RegisteredDomain({ - ignore_failure: true, - ignore_missing: true, - field: "dns.question.name", - target_field: "dns.question.registered_domain", - target_subdomain_field: "dns.question.subdomain", - target_etld_field: "dns.question.top_level_domain", - }) - .Add(setRuleName) - .Add(translateDnsQueryStatus) - .Add(splitDnsQueryResults) - .Add(setProcessNameUsingExe) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 23 - FileDelete (A file delete was detected). - var event23 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["file"], // pipes are files - type: ["deletion"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.RuleName", - to: "rule.name", - }, - { - from: "winlog.event_data.TargetFilename", - to: "file.path", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.Archived", - to: "sysmon.file.archived", - type: "boolean", - }, - { - from: "winlog.event_data.IsExecutable", - to: "sysmon.file.is_executable", - type: "boolean", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(addUser) - .Add(splitProcessHashes) - .Add(setProcessNameUsingExe) - .Add(setAdditionalFileFieldsFromPath) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 24 - ClipboardChange (New content in the clipboard). - var event24 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.Archived", - to: "sysmon.file.archived", - type: "boolean", - }, - { - from: "winlog.event_data.IsExecutable", - to: "sysmon.file.is_executable", - type: "boolean", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(addUser) - .Add(splitProcessHashes) - .Add(setProcessNameUsingExe) - .Add(setAdditionalFileFieldsFromPath) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 25 - ProcessTampering (Process image change). - var event25 = new processor.Chain() - .Add(parseUtcTime) - .AddFields({ - fields: { - category: ["process"], - type: ["change"], - }, - target: "event", - }) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ProcessGuid", - to: "process.entity_id", - }, - { - from: "winlog.event_data.ProcessId", - to: "process.pid", - type: "long", - }, - { - from: "winlog.event_data.Image", - to: "process.executable", - }, - { - from: "winlog.event_data.Archived", - to: "sysmon.file.archived", - type: "boolean", - }, - { - from: "winlog.event_data.IsExecutable", - to: "sysmon.file.is_executable", - type: "boolean", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(setRuleName) - .Add(addUser) - .Add(splitProcessHashes) - .Add(setProcessNameUsingExe) - .Add(setAdditionalFileFieldsFromPath) - .Add(removeEmptyEventData) - .Build(); - - // Event ID 255 - Error report. - var event255 = new processor.Chain() - .Add(parseUtcTime) - .Convert({ - fields: [{ - from: "winlog.event_data.UtcTime", - to: "@timestamp", - }, - { - from: "winlog.event_data.ID", - to: "error.code", - }, - ], - mode: "rename", - ignore_missing: true, - fail_on_error: false, - }) - .Add(removeEmptyEventData) - .Build(); - - return { - 1: event1.Run, - 2: event2.Run, - 3: event3.Run, - 4: event4.Run, - 5: event5.Run, - 6: event6.Run, - 7: event7.Run, - 8: event8.Run, - 9: event9.Run, - 10: event10.Run, - 11: event11.Run, - 12: event12.Run, - 13: event13.Run, - 14: event14.Run, - 15: event15.Run, - 16: event16.Run, - 17: event17.Run, - 18: event18.Run, - 19: event19.Run, - 20: event20.Run, - 21: event21.Run, - 22: event22.Run, - 23: event23.Run, - 24: event24.Run, - 25: event25.Run, - 255: event255.Run, - - process: function (evt) { - var event_id = evt.Get("winlog.event_id"); - var processor = this[event_id]; - if (processor === undefined) { - throw "unexpected sysmon event_id"; - } - evt.Put("event.module", "sysmon"); - processor(evt); - }, - }; -})(); - -function process(evt) { - return sysmon.process(evt); -} diff --git a/x-pack/winlogbeat/module/sysmon/ingest/sysmon.yml b/x-pack/winlogbeat/module/sysmon/ingest/sysmon.yml new file mode 100644 index 000000000000..db28eb13cf78 --- /dev/null +++ b/x-pack/winlogbeat/module/sysmon/ingest/sysmon.yml @@ -0,0 +1,1253 @@ +--- +description: Pipeline for Windows Sysmon Event Logs +processors: +## ECS and Event fields. + + - set: + field: ecs.version + value: '1.12.0' + - rename: + field: winlog.level + target_field: log.level + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.level != "" + - date: + field: winlog.time_created + target_field: event.created + formats: + - ISO8601 + ignore_failure: true + if: ctx?.winlog?.time_created != null + - date: + field: winlog.event_data.UtcTime + formats: + - yyyy-MM-dd HH:mm:ss.SSS + timezone: UTC + ignore_failure: true + if: ctx?.winlog?.event_data?.UtcTime != null + + - set: + field: event.ingested + value: '{{_ingest.timestamp}}' + - set: + field: event.kind + value: event + - set: + field: event.code + value: '{{winlog.event_id}}' + + - script: + description: Set event category and type for all event types. + lang: painless + params: + "1": + category: + - process + type: + - start + "2": + category: + - file + type: + - change + "3": + category: + - network + type: + - start + - connection + - protocol + "4": + category: + - process + type: + - change + "5": + category: + - process + type: + - end + "6": + category: + - driver + type: + - start + "7": + category: + - process + type: + - change + "10": + category: + - process + type: + - access + "11": + category: + - file + type: + - creation + "12": + category: + - configuration + - registry + type: + - change + "13": + category: + - configuration + - registry + type: + - change + "14": + category: + - configuration + - registry + type: + - change + "15": + category: + - file + type: + - access + "16": + category: + - configuration + type: + - change + "17": + category: + - file + type: + - creation + "18": + category: + - file + type: + - access + "22": + category: + - network + type: + - connection + - protocol + - info + "23": + category: + - file + type: + - deletion + "24": + type: + - change + "25": + category: + - process + type: + - change + tag: Add ECS categorization fields + source: |- + if (ctx?.event?.code == null || params.get(ctx.event.code) == null) { + return; + } + def hm = new HashMap(params[ctx.event.code]); + hm.forEach((k, v) -> ctx.event[k] = v); + - convert: + field: winlog.record_id + type: string + ignore_failure: true + ignore_missing: true + + - rename: + field: winlog.event_data.ID + target_field: error.code + ignore_failure: true + ignore_missing: true + if: ctx.event.code == "255" && ctx.winlog?.event_data?.ID != null && ctx.winlog?.event_data?.ID != "" + + - rename: + field: winlog.event_data.RuleName + target_field: rule.name + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.RuleName != null && ctx?.winlog?.event_data?.RuleName != "" && ctx?.winlog?.event_data?.RuleName != "-" + + + - rename: + field: winlog.event_data.Type + target_field: message + ignore_missing: true + ignore_failure: true + if: ctx.event.code == "25" && ctx?.winlog?.event_data?.Type != null && ctx?.winlog?.event_data?.Type != "" + + - rename: + field: winlog.event_data.Hash + target_field: winlog.event_data.Hashes + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.Hash != null && ctx?.winlog?.event_data?.Hash != "" + - kv: + field: winlog.event_data.Hashes + target_field: _temp.hashes + field_split: "," + value_split: "=" + ignore_failure: true + if: ctx?.winlog?.event_data?.Hashes != null + - script: + lang: painless + if: ctx?._temp?.hashes != null + source: |- + def hashIsEmpty(String hash) { + if (hash == "") { + return true; + } + + Pattern emptyHashRegex = /^0*$/; + def matcher = emptyHashRegex.matcher(hash); + + return matcher.matches(); + } + + def hashes = new HashMap(); + def related = [ + "hash": new ArrayList() + ]; + for (entry in ctx._temp.hashes.entrySet()) { + def key = entry.getKey().toString().toLowerCase(); + def value = entry.getValue().toString().toLowerCase(); + + if (hashIsEmpty(value)) { + continue; + } + + hashes[key] = value; + related.hash.add(value); + } + + ctx._temp.hashes = hashes; + if (related.hash.length > 0) { + ctx.related = related; + } + +## Process fields + + - rename: + field: _temp.hashes + target_field: process.hash + if: |- + ctx?._temp?.hashes != null && + ["1", "23", "24", "25"].contains(ctx.event.code) + - rename: + field: process.hash.imphash + target_field: process.pe.imphash + ignore_failure: true + ignore_missing: true + - rename: + field: winlog.event_data.ProcessGuid + target_field: process.entity_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.ProcessGuid != null && ctx?.winlog?.event_data?.ProcessGuid != "" + - convert: + field: winlog.event_data.ProcessId + target_field: process.pid + type: long + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.ProcessId != null && ctx?.winlog?.event_data?.ProcessId != "" + - rename: + field: winlog.event_data.Image + target_field: process.executable + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.Image != null && ctx?.winlog?.event_data?.Image != "" + - rename: + field: winlog.event_data.SourceProcessGuid + target_field: process.entity_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.SourceProcessGuid != null && ctx?.winlog?.event_data?.SourceProcessGuid != "" + - rename: + field: winlog.event_data.SourceProcessGUID + target_field: process.entity_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.SourceProcessGUID != null && ctx?.winlog?.event_data?.SourceProcessGUID != "" + - convert: + field: winlog.event_data.SourceProcessId + target_field: process.pid + type: long + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.SourceProcessId != null && ctx?.winlog?.event_data?.SourceProcessId != "" + - convert: + field: winlog.event_data.SourceThreadId + target_field: process.thread.id + type: long + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.SourceThreadId != null && ctx?.winlog?.event_data?.SourceThreadId != "" + - rename: + field: winlog.event_data.SourceImage + target_field: process.executable + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.SourceImage != null && ctx?.winlog?.event_data?.SourceImage != "" + - rename: + field: winlog.event_data.Destination + target_field: process.executable + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.Destination != null && ctx?.winlog?.event_data?.Destination != "" + - rename: + field: winlog.event_data.CommandLine + target_field: process.command_line + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.CommandLine != null && ctx?.winlog?.event_data?.CommandLine != "" + - rename: + field: winlog.event_data.CurrentDirectory + target_field: process.working_directory + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.CurrentDirectory != null && ctx?.winlog?.event_data?.CurrentDirectory != "" + - rename: + field: winlog.event_data.ParentProcessGuid + target_field: process.parent.entity_id + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.ParentProcessGuid != null && ctx?.winlog?.event_data?.ParentProcessGuid != "" + - convert: + field: winlog.event_data.ParentProcessId + target_field: process.parent.pid + type: long + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.ParentProcessId != null && ctx?.winlog?.event_data?.ParentProcessId != "" + - rename: + field: winlog.event_data.ParentImage + target_field: process.parent.executable + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.ParentImage != null && ctx?.winlog?.event_data?.ParentImage != "" + - rename: + field: winlog.event_data.ParentCommandLine + target_field: process.parent.command_line + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.ParentCommandLine != null && ctx?.winlog?.event_data?.ParentCommandLine != "" + - rename: + field: winlog.event_data.OriginalFileName + target_field: process.pe.original_file_name + ignore_missing: true + ignore_failure: true + if: ctx.event.code != "7" && ctx?.winlog?.event_data?.OriginalFileName != null && ctx?.winlog?.event_data?.OriginalFileName != "" + - set: + field: process.pe.company + copy_from: winlog.event_data.Company + ignore_empty_value: true + ignore_failure: true + if: ctx.event.code != "7" + - set: + field: process.pe.description + copy_from: winlog.event_data.Description + ignore_empty_value: true + ignore_failure: true + if: ctx.event.code != "7" + - set: + field: process.pe.file_version + copy_from: winlog.event_data.FileVersion + ignore_empty_value: true + ignore_failure: true + if: ctx.event.code != "7" + - set: + field: process.pe.product + copy_from: winlog.event_data.Product + ignore_empty_value: true + ignore_failure: true + if: ctx.event.code != "7" + + - script: + description: Implements Windows-like SplitCommandLine + lang: painless + if: |- + (ctx?.process?.command_line != null && ctx.process.command_line != "") || + (ctx?.process?.parent?.command_line != null && ctx.process.parent.command_line != "") + source: |- + // appendBSBytes appends n '\\' bytes to b and returns the resulting slice. + def appendBSBytes(StringBuilder b, int n) { + for (; n > 0; n--) { + b.append('\\'); + } + return b; + } + + // readNextArg splits command line string cmd into next + // argument and command line remainder. + def readNextArg(String cmd) { + def b = new StringBuilder(); + boolean inquote; + int nslash; + for (; cmd.length() > 0; cmd = cmd.substring(1)) { + def c = cmd.charAt(0); + if (c == (char)' ' || c == (char)0x09) { + if (!inquote) { + return [ + "arg": appendBSBytes(b, nslash).toString(), + "rest": cmd.substring(1) + ]; + } + } else if (c == (char)'"') { + b = appendBSBytes(b, nslash/2); + if (nslash%2 == 0) { + // use "Prior to 2008" rule from + // http://daviddeley.com/autohotkey/parameters/parameters.htm + // section 5.2 to deal with double double quotes + if (inquote && cmd.length() > 1 && cmd.charAt(1) == (char)'"') { + b.append(c); + cmd = cmd.substring(1); + } + inquote = !inquote; + } else { + b.append(c); + } + nslash = 0; + continue; + } else if (c == (char)'\\') { + nslash++; + continue; + } + b = appendBSBytes(b, nslash); + nslash = 0; + b.append(c); + } + return [ + "arg": appendBSBytes(b, nslash).toString(), + "rest": '' + ]; + } + + // commandLineToArgv splits a command line into individual argument + // strings, following the Windows conventions documented + // at http://daviddeley.com/autohotkey/parameters/parameters.htm#WINARGV + // Original implementation found at: https://github.com/golang/go/commit/39c8d2b7faed06b0e91a1ad7906231f53aab45d1 + def commandLineToArgv(String cmd) { + def args = new ArrayList(); + while (cmd.length() > 0) { + if (cmd.charAt(0) == (char)' ' || cmd.charAt(0) == (char)0x09) { + cmd = cmd.substring(1); + continue; + } + def next = readNextArg(cmd); + cmd = next.rest; + args.add(next.arg); + } + return args; + } + + def cmd = ctx?.process?.command_line; + if (cmd != null && cmd != "") { + ctx.process.args = commandLineToArgv(cmd); + ctx.process.args_count = ctx.process.args.length; + } + + def parentCmd = ctx?.process?.parent?.command_line; + if (parentCmd != null && parentCmd != "") { + ctx.process.parent.args = commandLineToArgv(parentCmd); + ctx.process.parent.args_count = ctx.process.parent.args.length; + } + + - script: + description: Adds process name information. + lang: painless + if: |- + (ctx?.process?.executable != null && ctx.process.executable.length() > 1) || + (ctx?.process?.parent?.executable != null && ctx.process.parent.executable.length() > 1) + source: |- + def getProcessName(def path) { + def idx = path.lastIndexOf("\\"); + if (idx > -1) { + return path.substring(idx+1); + } + return ""; + } + + def cmd = ctx?.process?.executable; + if (cmd != null && cmd != "" && ctx?.process?.name == null) { + def name = getProcessName(cmd); + if (name != "") { + ctx.process.name = name; + } + } + + def parentCmd = ctx?.process?.parent?.executable; + if (parentCmd != null && parentCmd != "" && ctx?.process?.parent?.name == null) { + def name = getProcessName(parentCmd); + if (name != "") { + ctx.process.parent.name = name; + } + } + +## File fields + + - rename: + field: _temp.hashes + target_field: file.hash + if: |- + ctx?._temp?.hashes != null && + ["6", "7", "15"].contains(ctx.event.code) + - rename: + field: file.hash.imphash + target_field: file.pe.imphash + ignore_failure: true + ignore_missing: true + - rename: + field: winlog.event_data.TargetFilename + target_field: file.path + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.TargetFilename != null && ctx?.winlog?.event_data?.TargetFilename != "" + - rename: + field: winlog.event_data.Device + target_field: file.path + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.Device != null && ctx?.winlog?.event_data?.Device != "" + - rename: + field: winlog.event_data.PipeName + target_field: file.name + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.PipeName != null && ctx?.winlog?.event_data?.PipeName != "" + - rename: + field: winlog.event_data.ImageLoaded + target_field: file.path + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.ImageLoaded != null && ctx?.winlog?.event_data?.ImageLoaded != "" + - set: + field: file.code_signature.subject_name + copy_from: winlog.event_data.Signature + ignore_failure: true + ignore_empty_value: true + - set: + field: file.code_signature.status + copy_from: winlog.event_data.SignatureStatus + ignore_failure: true + ignore_empty_value: true + - rename: + field: winlog.event_data.OriginalFileName + target_field: file.pe.original_file_name + ignore_missing: true + ignore_failure: true + if: ctx.event.code == "7" && ctx?.winlog?.event_data?.OriginalFileName != null && ctx?.winlog?.event_data?.OriginalFileName != "" + - set: + field: file.pe.company + copy_from: winlog.event_data.Company + ignore_failure: true + ignore_empty_value: true + if: ctx.event.code == "7" + - set: + field: file.pe.description + copy_from: winlog.event_data.Description + ignore_failure: true + ignore_empty_value: true + if: ctx.event.code == "7" + - set: + field: file.pe.file_version + copy_from: winlog.event_data.FileVersion + ignore_failure: true + ignore_empty_value: true + if: ctx.event.code == "7" + - set: + field: file.pe.product + copy_from: winlog.event_data.Product + ignore_failure: true + ignore_empty_value: true + if: ctx.event.code == "7" + - set: + field: file.code_signature.signed + value: true + if: ctx?.winlog?.event_data?.Signed != null && ctx.winlog.event_data.Signed == true + - set: + field: file.code_signature.valid + value: true + if: ctx?.winlog?.event_data?.SignatureStatus != null && ctx?.winlog?.event_data?.SignatureStatus == "Valid" + + - script: + description: Adds file information. + lang: painless + if: ctx?.file?.path != null && ctx.file.path.length() > 1 + source: |- + def path = ctx.file.path; + def idx = path.lastIndexOf("\\"); + if (idx > -1) { + if (ctx?.file == null) { + ctx.file = new HashMap(); + } + ctx.file.name = path.substring(idx+1); + ctx.file.directory = path.substring(0, idx); + + def extIdx = path.lastIndexOf("."); + if (extIdx > -1) { + ctx.file.extension = path.substring(extIdx+1); + } + } + +## Network, Destination, and Source fields + + - rename: + field: winlog.event_data.Protocol + target_field: network.transport + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.Protocol != null && ctx?.winlog?.event_data?.Protocol != "" + - rename: + field: winlog.event_data.DestinationPortName + target_field: network.protocol + ignore_missing: true + ignore_failure: true + if: ctx.event.code != "22" && ctx?.winlog?.event_data?.DestinationPortName != null && ctx?.winlog?.event_data?.DestinationPortName != "" + - rename: + field: winlog.event_data.SourcePortName + target_field: network.protocol + ignore_missing: true + ignore_failure: true + if: ctx.event.code != "22" && ctx?.winlog?.event_data?.SourcePortName != null && ctx?.winlog?.event_data?.SourcePortName != "" + - set: + field: network.protocol + value: dns + if: ctx.event.code == "22" + - convert: + field: winlog.event_data.SourceIp + target_field: source.ip + type: ip + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.SourceIp != null && ctx?.winlog?.event_data?.SourceIp != "" + - rename: + field: winlog.event_data.SourceHostname + target_field: source.domain + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.SourceHostname != null && ctx?.winlog?.event_data?.SourceHostname != "" + - convert: + field: winlog.event_data.SourcePort + target_field: source.port + type: long + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.SourcePort != null && ctx?.winlog?.event_data?.SourcePort != "" + - convert: + field: winlog.event_data.DestinationIp + target_field: destination.ip + type: ip + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.DestinationIp != null && ctx?.winlog?.event_data?.DestinationIp != "" + - rename: + field: winlog.event_data.DestinationHostname + target_field: destination.domain + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.DestinationHostname != null && ctx?.winlog?.event_data?.DestinationHostname != "" + - convert: + field: winlog.event_data.DestinationPort + target_field: destination.port + type: long + ignore_failure: true + ignore_missing: true + if: ctx?.winlog?.event_data?.DestinationPort != null && ctx?.winlog?.event_data?.DestinationPort != "" + - rename: + field: winlog.event_data.QueryName + target_field: dns.question.name + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.QueryName != null && ctx?.winlog?.event_data?.QueryName != "" + - set: + field: network.direction + value: egress + if: ctx?.winlog?.event_data?.Initiated != null && ctx?.winlog?.event_data?.Initiated == "true" + - set: + field: network.direction + value: ingress + if: ctx?.winlog?.event_data?.Initiated != null && ctx?.winlog?.event_data?.Initiated == "false" + - set: + field: network.type + value: ipv4 + if: ctx?.winlog?.event_data?.SourceIsIpv6 != null && ctx?.winlog?.event_data?.SourceIsIpv6 == "false" + - set: + field: network.type + value: ipv6 + if: ctx?.winlog?.event_data?.SourceIsIpv6 != null && ctx?.winlog?.event_data?.SourceIsIpv6 == "true" + - script: + description: | + Splits the QueryResults field that contains the DNS responses. + Example: "type: 5 f2.taboola.map.fastly.net;::ffff:151.101.66.2;::ffff:151.101.130.2;::ffff:151.101.194.2;::ffff:151.101.2.2;" + lang: painless + if: ctx?.winlog?.event_data?.QueryResults != null && ctx?.winlog?.event_data?.QueryResults != "" + params: + "1": "A" + "2": "NS" + "3": "MD" + "4": "MF" + "5": "CNAME" + "6": "SOA" + "7": "MB" + "8": "MG" + "9": "MR" + "10": "NULL" + "11": "WKS" + "12": "PTR" + "13": "HINFO" + "14": "MINFO" + "15": "MX" + "16": "TXT" + "17": "RP" + "18": "AFSDB" + "19": "X25" + "20": "ISDN" + "21": "RT" + "22": "NSAP" + "23": "NSAPPTR" + "24": "SIG" + "25": "KEY" + "26": "PX" + "27": "GPOS" + "28": "AAAA" + "29": "LOC" + "30": "NXT" + "31": "EID" + "32": "NIMLOC" + "33": "SRV" + "34": "ATMA" + "35": "NAPTR" + "36": "KX" + "37": "CERT" + "38": "A6" + "39": "DNAME" + "40": "SINK" + "41": "OPT" + "43": "DS" + "46": "RRSIG" + "47": "NSEC" + "48": "DNSKEY" + "49": "DHCID" + "100": "UINFO" + "101": "UID" + "102": "GID" + "103": "UNSPEC" + "248": "ADDRS" + "249": "TKEY" + "250": "TSIG" + "251": "IXFR" + "252": "AXFR" + "253": "MAILB" + "254": "MAILA" + "255": "ANY" + "65281": "WINS" + "65282": "WINSR" + source: |- + def results = /;/.split(ctx.winlog.event_data.QueryResults); + def answers = new ArrayList(); + def ips = new ArrayList(); + def relatedHosts = new ArrayList(); + for (def i = 0; i < results.length; i++) { + def answer = results[i]; + if (answer == "") { + continue; + } + + if (answer.startsWith("type:")) { + def parts = /\s+/.split(answer); + if (parts.length != 3) { + throw new Exception("unexpected QueryResult format"); + } + + answers.add([ + "type": params[parts[1]], + "data": parts[2] + ]); + relatedHosts.add(parts[2]); + } else { + answer = answer.replace("::ffff:", ""); + ips.add(answer); + } + } + + if (answers.length > 0) { + ctx.dns.answers = answers; + } + if (ips.length > 0) { + ctx.dns.resolved_ip = ips; + } + if (relatedHosts.length > 0) { + if (ctx?.related == null) { + ctx.related = new HashMap(); + } + ctx.related.hosts = relatedHosts; + } + - foreach: + field: dns.resolved_ip + ignore_missing: true + processor: + convert: + field: _ingest._value + type: ip + on_failure: + - remove: + field: _ingest._value + - script: + description: Convert V4MAPPED addresses. + lang: painless + if: ctx?.dns?.resolved_ip != null + source: |- + if (ctx.dns.answers == null) { + ctx.dns.answers = new ArrayList(); + } + for (def i = 0; i < ctx.dns.resolved_ip.length; i++) { + def ip = ctx.dns.resolved_ip[i]; + if (ip == null) { + ctx.dns.resolved_ip.remove(i); + continue; + } + + // Synthesize record type based on IP address type. + def type = "A"; + if (ip.indexOf(":") != -1) { + type = "AAAA"; + } + ctx.dns.answers.add([ + "type": type, + "data": ip + ]); + } + - registered_domain: + field: dns.question.name + target_field: dns.question + ignore_failure: true + ignore_missing: true + - append: + field: related.hosts + value: "{{dns.question.name}}" + allow_duplicates: false + if: ctx?.dns?.question?.name != null && ctx?.dns?.question?.name != "" + - remove: + description: Remove dns.question.domain because it is not part of ECS and is redundant with dns.question.name. + field: dns.question.domain + ignore_missing: true + ignore_failure: true + - foreach: + field: dns.resolved_ip + ignore_missing: true + processor: + append: + field: related.ip + value: "{{_ingest._value}}" + allow_duplicates: false + ignore_failure: true + - community_id: + ignore_failure: true + ignore_missing: false + +## User fields + + - set: + field: user.id + copy_from: winlog.user.identifier + ignore_empty_value: true + ignore_failure: true + - split: + field: winlog.event_data.User + target_field: "_temp.user_parts" + separator: '\\' + if: ctx?.winlog?.event_data?.User != null + - set: + field: user.domain + value: "{{_temp.user_parts.0}}" + ignore_failure: true + ignore_empty_value: true + if: ctx?._temp?.user_parts != null && ctx._temp.user_parts.size() == 2 + - set: + field: user.name + value: "{{_temp.user_parts.1}}" + ignore_failure: true + ignore_empty_value: true + if: ctx?._temp?.user_parts != null && ctx._temp.user_parts.size() == 2 + +## Sysmon fields + + - rename: + field: winlog.event_data.QueryStatus + target_field: sysmon.dns.status + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.QueryStatus != null && ctx?.winlog?.event_data?.QueryStatus != "" + - script: + description: Translate DNS Query status. + lang: painless + params: + "5": "ERROR_ACCESS_DENIED" + "0": "SUCCESS" + "8": "ERROR_NOT_ENOUGH_MEMORY" + "13": "ERROR_INVALID_DATA" + "14": "ERROR_OUTOFMEMORY" + "123": "ERROR_INVALID_NAME" + "1214": "ERROR_INVALID_NETNAME" + "1223": "ERROR_CANCELLED" + "1460": "ERROR_TIMEOUT" + "4312": "ERROR_OBJECT_NOT_FOUND" + "9001": "DNS_ERROR_RCODE_FORMAT_ERROR" + "9002": "DNS_ERROR_RCODE_SERVER_FAILURE" + "9003": "DNS_ERROR_RCODE_NAME_ERROR" + "9004": "DNS_ERROR_RCODE_NOT_IMPLEMENTED" + "9005": "DNS_ERROR_RCODE_REFUSED" + "9006": "DNS_ERROR_RCODE_YXDOMAIN" + "9007": "DNS_ERROR_RCODE_YXRRSET" + "9008": "DNS_ERROR_RCODE_NXRRSET" + "9009": "DNS_ERROR_RCODE_NOTAUTH" + "9010": "DNS_ERROR_RCODE_NOTZONE" + "9016": "DNS_ERROR_RCODE_BADSIG" + "9017": "DNS_ERROR_RCODE_BADKEY" + "9018": "DNS_ERROR_RCODE_BADTIME" + "9101": "DNS_ERROR_KEYMASTER_REQUIRED" + "9102": "DNS_ERROR_NOT_ALLOWED_ON_SIGNED_ZONE" + "9103": "DNS_ERROR_NSEC3_INCOMPATIBLE_WITH_RSA_SHA1" + "9104": "DNS_ERROR_NOT_ENOUGH_SIGNING_KEY_DESCRIPTORS" + "9105": "DNS_ERROR_UNSUPPORTED_ALGORITHM" + "9106": "DNS_ERROR_INVALID_KEY_SIZE" + "9107": "DNS_ERROR_SIGNING_KEY_NOT_ACCESSIBLE" + "9108": "DNS_ERROR_KSP_DOES_NOT_SUPPORT_PROTECTION" + "9109": "DNS_ERROR_UNEXPECTED_DATA_PROTECTION_ERROR" + "9110": "DNS_ERROR_UNEXPECTED_CNG_ERROR" + "9111": "DNS_ERROR_UNKNOWN_SIGNING_PARAMETER_VERSION" + "9112": "DNS_ERROR_KSP_NOT_ACCESSIBLE" + "9113": "DNS_ERROR_TOO_MANY_SKDS" + "9114": "DNS_ERROR_INVALID_ROLLOVER_PERIOD" + "9115": "DNS_ERROR_INVALID_INITIAL_ROLLOVER_OFFSET" + "9116": "DNS_ERROR_ROLLOVER_IN_PROGRESS" + "9117": "DNS_ERROR_STANDBY_KEY_NOT_PRESENT" + "9118": "DNS_ERROR_NOT_ALLOWED_ON_ZSK" + "9119": "DNS_ERROR_NOT_ALLOWED_ON_ACTIVE_SKD" + "9120": "DNS_ERROR_ROLLOVER_ALREADY_QUEUED" + "9121": "DNS_ERROR_NOT_ALLOWED_ON_UNSIGNED_ZONE" + "9122": "DNS_ERROR_BAD_KEYMASTER" + "9123": "DNS_ERROR_INVALID_SIGNATURE_VALIDITY_PERIOD" + "9124": "DNS_ERROR_INVALID_NSEC3_ITERATION_COUNT" + "9125": "DNS_ERROR_DNSSEC_IS_DISABLED" + "9126": "DNS_ERROR_INVALID_XML" + "9127": "DNS_ERROR_NO_VALID_TRUST_ANCHORS" + "9128": "DNS_ERROR_ROLLOVER_NOT_POKEABLE" + "9129": "DNS_ERROR_NSEC3_NAME_COLLISION" + "9130": "DNS_ERROR_NSEC_INCOMPATIBLE_WITH_NSEC3_RSA_SHA1" + "9501": "DNS_INFO_NO_RECORDS" + "9502": "DNS_ERROR_BAD_PACKET" + "9503": "DNS_ERROR_NO_PACKET" + "9504": "DNS_ERROR_RCODE" + "9505": "DNS_ERROR_UNSECURE_PACKET" + "9506": "DNS_REQUEST_PENDING" + "9551": "DNS_ERROR_INVALID_TYPE" + "9552": "DNS_ERROR_INVALID_IP_ADDRESS" + "9553": "DNS_ERROR_INVALID_PROPERTY" + "9554": "DNS_ERROR_TRY_AGAIN_LATER" + "9555": "DNS_ERROR_NOT_UNIQUE" + "9556": "DNS_ERROR_NON_RFC_NAME" + "9557": "DNS_STATUS_FQDN" + "9558": "DNS_STATUS_DOTTED_NAME" + "9559": "DNS_STATUS_SINGLE_PART_NAME" + "9560": "DNS_ERROR_INVALID_NAME_CHAR" + "9561": "DNS_ERROR_NUMERIC_NAME" + "9562": "DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER" + "9563": "DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION" + "9564": "DNS_ERROR_CANNOT_FIND_ROOT_HINTS" + "9565": "DNS_ERROR_INCONSISTENT_ROOT_HINTS" + "9566": "DNS_ERROR_DWORD_VALUE_TOO_SMALL" + "9567": "DNS_ERROR_DWORD_VALUE_TOO_LARGE" + "9568": "DNS_ERROR_BACKGROUND_LOADING" + "9569": "DNS_ERROR_NOT_ALLOWED_ON_RODC" + "9570": "DNS_ERROR_NOT_ALLOWED_UNDER_DNAME" + "9571": "DNS_ERROR_DELEGATION_REQUIRED" + "9572": "DNS_ERROR_INVALID_POLICY_TABLE" + "9573": "DNS_ERROR_ADDRESS_REQUIRED" + "9601": "DNS_ERROR_ZONE_DOES_NOT_EXIST" + "9602": "DNS_ERROR_NO_ZONE_INFO" + "9603": "DNS_ERROR_INVALID_ZONE_OPERATION" + "9604": "DNS_ERROR_ZONE_CONFIGURATION_ERROR" + "9605": "DNS_ERROR_ZONE_HAS_NO_SOA_RECORD" + "9606": "DNS_ERROR_ZONE_HAS_NO_NS_RECORDS" + "9607": "DNS_ERROR_ZONE_LOCKED" + "9608": "DNS_ERROR_ZONE_CREATION_FAILED" + "9609": "DNS_ERROR_ZONE_ALREADY_EXISTS" + "9610": "DNS_ERROR_AUTOZONE_ALREADY_EXISTS" + "9611": "DNS_ERROR_INVALID_ZONE_TYPE" + "9612": "DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP" + "9613": "DNS_ERROR_ZONE_NOT_SECONDARY" + "9614": "DNS_ERROR_NEED_SECONDARY_ADDRESSES" + "9615": "DNS_ERROR_WINS_INIT_FAILED" + "9616": "DNS_ERROR_NEED_WINS_SERVERS" + "9617": "DNS_ERROR_NBSTAT_INIT_FAILED" + "9618": "DNS_ERROR_SOA_DELETE_INVALID" + "9619": "DNS_ERROR_FORWARDER_ALREADY_EXISTS" + "9620": "DNS_ERROR_ZONE_REQUIRES_MASTER_IP" + "9621": "DNS_ERROR_ZONE_IS_SHUTDOWN" + "9622": "DNS_ERROR_ZONE_LOCKED_FOR_SIGNING" + "9651": "DNS_ERROR_PRIMARY_REQUIRES_DATAFILE" + "9652": "DNS_ERROR_INVALID_DATAFILE_NAME" + "9653": "DNS_ERROR_DATAFILE_OPEN_FAILURE" + "9654": "DNS_ERROR_FILE_WRITEBACK_FAILED" + "9655": "DNS_ERROR_DATAFILE_PARSING" + "9701": "DNS_ERROR_RECORD_DOES_NOT_EXIST" + "9702": "DNS_ERROR_RECORD_FORMAT" + "9703": "DNS_ERROR_NODE_CREATION_FAILED" + "9704": "DNS_ERROR_UNKNOWN_RECORD_TYPE" + "9705": "DNS_ERROR_RECORD_TIMED_OUT" + "9706": "DNS_ERROR_NAME_NOT_IN_ZONE" + "9707": "DNS_ERROR_CNAME_LOOP" + "9708": "DNS_ERROR_NODE_IS_CNAME" + "9709": "DNS_ERROR_CNAME_COLLISION" + "9710": "DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT" + "9711": "DNS_ERROR_RECORD_ALREADY_EXISTS" + "9712": "DNS_ERROR_SECONDARY_DATA" + "9713": "DNS_ERROR_NO_CREATE_CACHE_DATA" + "9714": "DNS_ERROR_NAME_DOES_NOT_EXIST" + "9715": "DNS_WARNING_PTR_CREATE_FAILED" + "9716": "DNS_WARNING_DOMAIN_UNDELETED" + "9717": "DNS_ERROR_DS_UNAVAILABLE" + "9718": "DNS_ERROR_DS_ZONE_ALREADY_EXISTS" + "9719": "DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE" + "9720": "DNS_ERROR_NODE_IS_DNAME" + "9721": "DNS_ERROR_DNAME_COLLISION" + "9722": "DNS_ERROR_ALIAS_LOOP" + "9751": "DNS_INFO_AXFR_COMPLETE" + "9752": "DNS_ERROR_AXFR" + "9753": "DNS_INFO_ADDED_LOCAL_WINS" + "9801": "DNS_STATUS_CONTINUE_NEEDED" + "9851": "DNS_ERROR_NO_TCPIP" + "9852": "DNS_ERROR_NO_DNS_SERVERS" + "9901": "DNS_ERROR_DP_DOES_NOT_EXIST" + "9902": "DNS_ERROR_DP_ALREADY_EXISTS" + "9903": "DNS_ERROR_DP_NOT_ENLISTED" + "9904": "DNS_ERROR_DP_ALREADY_ENLISTED" + "9905": "DNS_ERROR_DP_NOT_AVAILABLE" + "9906": "DNS_ERROR_DP_FSMO_ERROR" + "9911": "DNS_ERROR_RRL_NOT_ENABLED" + "9912": "DNS_ERROR_RRL_INVALID_WINDOW_SIZE" + "9913": "DNS_ERROR_RRL_INVALID_IPV4_PREFIX" + "9914": "DNS_ERROR_RRL_INVALID_IPV6_PREFIX" + "9915": "DNS_ERROR_RRL_INVALID_TC_RATE" + "9916": "DNS_ERROR_RRL_INVALID_LEAK_RATE" + "9917": "DNS_ERROR_RRL_LEAK_RATE_LESSTHAN_TC_RATE" + "9921": "DNS_ERROR_VIRTUALIZATION_INSTANCE_ALREADY_EXISTS" + "9922": "DNS_ERROR_VIRTUALIZATION_INSTANCE_DOES_NOT_EXIST" + "9923": "DNS_ERROR_VIRTUALIZATION_TREE_LOCKED" + "9924": "DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME" + "9925": "DNS_ERROR_DEFAULT_VIRTUALIZATION_INSTANCE" + "9951": "DNS_ERROR_ZONESCOPE_ALREADY_EXISTS" + "9952": "DNS_ERROR_ZONESCOPE_DOES_NOT_EXIST" + "9953": "DNS_ERROR_DEFAULT_ZONESCOPE" + "9954": "DNS_ERROR_INVALID_ZONESCOPE_NAME" + "9955": "DNS_ERROR_NOT_ALLOWED_WITH_ZONESCOPES" + "9956": "DNS_ERROR_LOAD_ZONESCOPE_FAILED" + "9957": "DNS_ERROR_ZONESCOPE_FILE_WRITEBACK_FAILED" + "9958": "DNS_ERROR_INVALID_SCOPE_NAME" + "9959": "DNS_ERROR_SCOPE_DOES_NOT_EXIST" + "9960": "DNS_ERROR_DEFAULT_SCOPE" + "9961": "DNS_ERROR_INVALID_SCOPE_OPERATION" + "9962": "DNS_ERROR_SCOPE_LOCKED" + "9963": "DNS_ERROR_SCOPE_ALREADY_EXISTS" + "9971": "DNS_ERROR_POLICY_ALREADY_EXISTS" + "9972": "DNS_ERROR_POLICY_DOES_NOT_EXIST" + "9973": "DNS_ERROR_POLICY_INVALID_CRITERIA" + "9974": "DNS_ERROR_POLICY_INVALID_SETTINGS" + "9975": "DNS_ERROR_CLIENT_SUBNET_IS_ACCESSED" + "9976": "DNS_ERROR_CLIENT_SUBNET_DOES_NOT_EXIST" + "9977": "DNS_ERROR_CLIENT_SUBNET_ALREADY_EXISTS" + "9978": "DNS_ERROR_SUBNET_DOES_NOT_EXIST" + "9979": "DNS_ERROR_SUBNET_ALREADY_EXISTS" + "9980": "DNS_ERROR_POLICY_LOCKED" + "9981": "DNS_ERROR_POLICY_INVALID_WEIGHT" + "9982": "DNS_ERROR_POLICY_INVALID_NAME" + "9983": "DNS_ERROR_POLICY_MISSING_CRITERIA" + "9984": "DNS_ERROR_INVALID_CLIENT_SUBNET_NAME" + "9985": "DNS_ERROR_POLICY_PROCESSING_ORDER_INVALID" + "9986": "DNS_ERROR_POLICY_SCOPE_MISSING" + "9987": "DNS_ERROR_POLICY_SCOPE_NOT_ALLOWED" + "9988": "DNS_ERROR_SERVERSCOPE_IS_REFERENCED" + "9989": "DNS_ERROR_ZONESCOPE_IS_REFERENCED" + "9990": "DNS_ERROR_POLICY_INVALID_CRITERIA_CLIENT_SUBNET" + "9991": "DNS_ERROR_POLICY_INVALID_CRITERIA_TRANSPORT_PROTOCOL" + "9992": "DNS_ERROR_POLICY_INVALID_CRITERIA_NETWORK_PROTOCOL" + "9993": "DNS_ERROR_POLICY_INVALID_CRITERIA_INTERFACE" + "9994": "DNS_ERROR_POLICY_INVALID_CRITERIA_FQDN" + "9995": "DNS_ERROR_POLICY_INVALID_CRITERIA_QUERY_TYPE" + "9996": "DNS_ERROR_POLICY_INVALID_CRITERIA_TIME_OF_DAY" + "10054": "WSAECONNRESET" + "10055": "WSAENOBUFS" + "10060": "WSAETIMEDOUT" + if: ctx?.sysmon?.dns?.status != null && ctx?.sysmon?.dns?.status != "" + source: |- + def status = params[ctx.sysmon.dns.status]; + if (status != null) { + ctx.sysmon.dns.status = status; + } + - convert: + field: winlog.event_data.Archived + target_field: sysmon.file.archived + type: boolean + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.Archived != null && ctx?.winlog?.event_data?.Archived != "" + - convert: + field: winlog.event_data.IsExecutable + target_field: sysmon.file.is_executable + type: boolean + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data?.IsExecutable != null && ctx?.winlog?.event_data?.IsExecutable != "" + +## Related fields + + - append: + field: related.user + value: "{{user.name}}" + ignore_failure: true + allow_duplicates: false + if: ctx?.user?.name != null && ctx.user.name != "" + - append: + field: related.ip + value: "{{source.ip}}" + ignore_failure: true + allow_duplicates: false + if: ctx?.source?.ip != null && ctx.source.ip != "" + - append: + field: related.ip + value: "{{destination.ip}}" + ignore_failure: true + allow_duplicates: false + if: ctx?.destination?.ip != null && ctx.destination.ip != "" + +## Registry fields + + - script: + description: Set registry fields. + lang: painless + if: |- + ctx?.winlog?.event_data?.TargetObject != null && ctx?.winlog?.event_data?.TargetObject != "" && + ["12", "13", "14"].contains(ctx.event.code) + params: + HKEY_CLASSES_ROOT: "HKCR" + HKCR: "HKCR" + HKEY_CURRENT_CONFIG: "HKCC" + HKCC: "HKCC" + HKEY_CURRENT_USER: "HKCU" + HKCU: "HKCU" + HKEY_DYN_DATA: "HKDD" + HKDD: "HKDD" + HKEY_LOCAL_MACHINE: "HKLM" + HKLM: "HKLM" + HKEY_PERFORMANCE_DATA: "HKPD" + HKPD: "HKPD" + HKEY_USERS: "HKU" + HKU: "HKU" + source: |- + ctx.registry = new HashMap(); + Pattern qwordRegex = /(?i)QWORD \(((0x\d{8})-(0x\d{8}))\)/; + Pattern dwordRegex = /(?i)DWORD \((0x\d{8})\)/; + + def path = ctx.winlog.event_data.TargetObject; + ctx.registry.path = path; + + def pathTokens = Arrays.asList(/\\/.split(path)); + def hive = params[pathTokens[0]]; + if (hive != null) { + ctx.registry.hive = hive; + if (pathTokens.length > 1) { + ctx.registry.key = pathTokens.subList(1, pathTokens.length).join("\\"); + } + } + + def value = pathTokens[pathTokens.length - 1]; + ctx.registry.value = value; + + def data = ctx?.winlog?.event_data?.Details; + if (data != null && data != "") { + def prefixLen = 2; // to remove 0x prefix + def dataValue = ""; + def dataType = ""; + def matcher = qwordRegex.matcher(data); + if (matcher.matches()) { + def parsedHighByte = Long.parseLong(matcher.group(2).substring(prefixLen), 16); + def parsedLowByte = Long.parseLong(matcher.group(3).substring(prefixLen), 16); + if (!Double.isNaN(parsedHighByte) && !Double.isNaN(parsedLowByte)) { + dataType = "SZ_QWORD"; + dataValue = Long.toString(((parsedHighByte << 8) + parsedLowByte)); + } + } else { + matcher = dwordRegex.matcher(data); + if (matcher.matches()) { + def parsedValue = Long.parseLong(matcher.group(1).substring(prefixLen), 16); + if (!Double.isNaN(parsedValue)) { + dataType = "SZ_DWORD"; + dataValue = matcher.group(1); + } + } + } + + if (dataType != "") { + ctx.registry.data = [ + "strings": [dataValue], + "type": dataType + ]; + } + } + +## Cleanup + + - remove: + field: + - _temp + - winlog.event_data.ProcessId + - winlog.event_data.ParentProcessId + - winlog.event_data.SourceProcessId + - winlog.event_data.SourceThreadId + - winlog.event_data.SourceIp + - winlog.event_data.SourcePort + - winlog.event_data.SourcePortName + - winlog.event_data.DestinationIp + - winlog.event_data.DestinationPort + - winlog.event_data.DestinationPortName + - winlog.event_data.RuleName + - winlog.event_data.User + - winlog.event_data.Initiated + - winlog.event_data.SourceIsIpv6 + - winlog.event_data.DestinationIsIpv6 + - winlog.event_data.QueryStatus + - winlog.event_data.Archived + - winlog.event_data.IsExecutable + - winlog.event_data.QueryResults + - winlog.event_data.UtcTime + - winlog.event_data.Hash + - winlog.event_data.Hashes + - winlog.event_data.TargetObject + - winlog.event_data.Details + - winlog.time_created + - winlog.level + ignore_failure: true + ignore_missing: true + - script: + description: Remove all empty values from event_data. + lang: painless + source: ctx?.winlog?.event_data?.entrySet().removeIf(entry -> entry.getValue() == null || entry.getValue().equals("") || entry.getValue().equals("-")); + - remove: + description: Remove empty event data. + field: winlog.event_data + ignore_missing: true + ignore_failure: true + if: ctx?.winlog?.event_data != null && ctx.winlog.event_data.size() == 0 + +on_failure: + - set: + field: "error.message" + value: |- + Processor "{{ _ingest.on_failure_processor_type }}" with tag "{{ _ingest.on_failure_processor_tag }}" in pipeline "{{ _ingest.on_failure_pipeline }}" failed with message "{{ _ingest.on_failure_message }}" diff --git a/x-pack/winlogbeat/module/sysmon/test/sysmon_windows_test.go b/x-pack/winlogbeat/module/sysmon/test/sysmon_windows_test.go deleted file mode 100644 index 1f4d78ad017c..000000000000 --- a/x-pack/winlogbeat/module/sysmon/test/sysmon_windows_test.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License; -// you may not use this file except in compliance with the Elastic License. - -package test - -import ( - "testing" - - "github.com/elastic/beats/v7/x-pack/winlogbeat/module" - - // Register required processors. - _ "github.com/elastic/beats/v7/libbeat/cmd/instance" - _ "github.com/elastic/beats/v7/libbeat/processors/timestamp" -) - -// Ignore these fields so that the tests will pass if Sysmon is not installed. -var ignoreFields = []string{ - "event.action", - "message", - "winlog.opcode", - "winlog.task", - - // Ignore these fields as under some circumstances they are not populated. - // (observed under Windows 7). - "winlog.user.type", - "winlog.user.name", - "winlog.user.domain", -} - -func TestSysmon(t *testing.T) { - module.TestPipeline(t, "testdata/*.evtx", "../config/winlogbeat-sysmon.js", - module.WithFieldFilter(ignoreFields)) -} diff --git a/x-pack/winlogbeat/winlogbeat.reference.yml b/x-pack/winlogbeat/winlogbeat.reference.yml index d74e971638a3..0868d8c8027a 100644 --- a/x-pack/winlogbeat/winlogbeat.reference.yml +++ b/x-pack/winlogbeat/winlogbeat.reference.yml @@ -20,6 +20,11 @@ # batch of events has been published successfully. The default value is 5s. #winlogbeat.registry_flush: 5s +# By default Ingest pipelines are not updated if a pipeline with the same ID +# already exists. If this option is enabled Winlogbeat overwrites pipelines +# every time a new Elasticsearch connection is established. +#winlogbeat.overwrite_pipelines: false + # event_logs specifies a list of event logs to monitor as well as any # accompanying options. The YAML data type of event_logs is a list of # dictionaries. @@ -38,58 +43,17 @@ winlogbeat.event_logs: - name: System - name: Security - processors: - - script: - lang: javascript - id: security - file: ${path.home}/module/security/config/winlogbeat-security.js - name: Microsoft-Windows-Sysmon/Operational - processors: - - script: - lang: javascript - id: sysmon - file: ${path.home}/module/sysmon/config/winlogbeat-sysmon.js - name: Windows PowerShell event_id: 400, 403, 600, 800 - processors: - - script: - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - name: Microsoft-Windows-PowerShell/Operational event_id: 4103, 4104, 4105, 4106 - processors: - - script: - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - name: ForwardedEvents tags: [forwarded] - processors: - - script: - when.equals.winlog.channel: Security - lang: javascript - id: security - file: ${path.home}/module/security/config/winlogbeat-security.js - - script: - when.equals.winlog.channel: Microsoft-Windows-Sysmon/Operational - lang: javascript - id: sysmon - file: ${path.home}/module/sysmon/config/winlogbeat-sysmon.js - - script: - when.equals.winlog.channel: Windows PowerShell - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - - script: - when.equals.winlog.channel: Microsoft-Windows-PowerShell/Operational - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js # ================================== General =================================== diff --git a/x-pack/winlogbeat/winlogbeat.yml b/x-pack/winlogbeat/winlogbeat.yml index 15c1e10fdcc3..6ae52cd3f3a6 100644 --- a/x-pack/winlogbeat/winlogbeat.yml +++ b/x-pack/winlogbeat/winlogbeat.yml @@ -27,58 +27,17 @@ winlogbeat.event_logs: - name: System - name: Security - processors: - - script: - lang: javascript - id: security - file: ${path.home}/module/security/config/winlogbeat-security.js - name: Microsoft-Windows-Sysmon/Operational - processors: - - script: - lang: javascript - id: sysmon - file: ${path.home}/module/sysmon/config/winlogbeat-sysmon.js - name: Windows PowerShell event_id: 400, 403, 600, 800 - processors: - - script: - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - name: Microsoft-Windows-PowerShell/Operational event_id: 4103, 4104, 4105, 4106 - processors: - - script: - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - name: ForwardedEvents tags: [forwarded] - processors: - - script: - when.equals.winlog.channel: Security - lang: javascript - id: security - file: ${path.home}/module/security/config/winlogbeat-security.js - - script: - when.equals.winlog.channel: Microsoft-Windows-Sysmon/Operational - lang: javascript - id: sysmon - file: ${path.home}/module/sysmon/config/winlogbeat-sysmon.js - - script: - when.equals.winlog.channel: Windows PowerShell - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - - script: - when.equals.winlog.channel: Microsoft-Windows-PowerShell/Operational - lang: javascript - id: powershell - file: ${path.home}/module/powershell/config/winlogbeat-powershell.js # ====================== Elasticsearch template settings ======================= @@ -162,6 +121,9 @@ output.elasticsearch: #username: "elastic" #password: "changeme" + # Pipeline to route events to security, sysmon, or powershell pipelines. + pipeline: "winlogbeat-%{[agent.version]}-routing" + # ------------------------------ Logstash Output ------------------------------- #output.logstash: # The Logstash hosts