Skip to content

Commit

Permalink
[Winlogbeat] Add subdomain value for sysmon module (elastic#22999)
Browse files Browse the repository at this point in the history
* [Winlogbeat] Add subdomain value for sysmon module

* Add changelog entry

* Add target_subdomain_field to docs example
  • Loading branch information
Andrew Stucki committed Dec 9, 2020
1 parent 52fc1cf commit d38a5d0
Show file tree
Hide file tree
Showing 7 changed files with 349 additions and 171 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
- Add `event.outcome` to events based on the audit success and audit failure keywords. {pull}20564[20564]
- Add file.pe and process.pe fields to ProcessCreate & LoadImage events in Sysmon module. {issue}17335[17335] {pull}22217[22217]
- Add additional event categorization for security and sysmon modules. {pull}22988[22988]
- Add dns.question.subdomain fields for sysmon DNS events. {pull}22999[22999]

*Elastic Log Driver*

Expand Down
11 changes: 6 additions & 5 deletions libbeat/processors/registered_domain/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@
package registered_domain

type config struct {
Field string `config:"field" validate:"required"`
TargetField string `config:"target_field" validate:"required"`
IgnoreMissing bool `config:"ignore_missing"`
IgnoreFailure bool `config:"ignore_failure"`
ID string `config:"id"`
Field string `config:"field" validate:"required"`
TargetField string `config:"target_field" validate:"required"`
TargetSubdomainField string `config:"target_subdomain_field"`
IgnoreMissing bool `config:"ignore_missing"`
IgnoreFailure bool `config:"ignore_failure"`
ID string `config:"id"`
}

func defaultConfig() config {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ The `registered_domain` processor reads a field containing a hostname and then
writes the "registered domain" contained in the hostname to the target field.
For example, given `www.google.co.uk` the processor would output `google.co.uk`.
In other words the "registered domain" is the effective top-level domain
(`co.uk`) plus one level (`google`).
(`co.uk`) plus one level (`google`). Optionally, it can store the rest of the
domain, the `subdomain` into another target field.

This processor uses the Mozilla Public Suffix list to determine the value.

Expand All @@ -19,6 +20,7 @@ processors:
- registered_domain:
field: dns.question.name
target_field: dns.question.registered_domain
target_subdomain_field: dns.question.sudomain
ignore_missing: true
ignore_failure: true
----
Expand All @@ -28,10 +30,11 @@ The `registered_domain` processor has the following configuration settings:
.Registered Domain options
[options="header"]
|======
| Name | Required | Default | Description |
| `field` | yes | | Source field containing a fully qualified domain name (FQDN). |
| `target_field` | yes | | Target field for the registered domain value. |
| `ignore_missing` | no | false | Ignore errors when the source field is missing. |
| `ignore_failure` | no | false | Ignore all errors produced by the processor. |
| `id` | no | | An identifier for this processor instance. Useful for debugging. |
| Name | Required | Default | Description |
| `field` | yes | | Source field containing a fully qualified domain name (FQDN). |
| `target_field` | yes | | Target field for the registered domain value. |
| `target_subdomain_field` | no | | Target subdomain field for the subdomain value. |
| `ignore_missing` | no | false | Ignore errors when the source field is missing. |
| `ignore_failure` | no | false | Ignore all errors produced by the processor. |
| `id` | no | | An identifier for this processor instance. Useful for debugging. |
|======
14 changes: 14 additions & 0 deletions libbeat/processors/registered_domain/registered_domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package registered_domain

import (
"encoding/json"
"strings"

"github.com/pkg/errors"
"golang.org/x/net/publicsuffix"
Expand Down Expand Up @@ -105,5 +106,18 @@ func (p *processor) Run(event *beat.Event) (*beat.Event, error) {
return event, errors.Wrapf(err, "failed to write registered domain to target field [%v]", p.TargetField)
}

if p.TargetSubdomainField != "" {
subdomain := strings.TrimSuffix(strings.TrimSuffix(domain, rd), ".")
if subdomain != "" {
_, err = event.PutValue(p.TargetSubdomainField, subdomain)
if err != nil {
if p.IgnoreFailure {
return event, nil
}
return event, errors.Wrapf(err, "failed to write subdomain to target field [%v]", p.TargetSubdomainField)
}
}
}

return event, nil
}
26 changes: 17 additions & 9 deletions libbeat/processors/registered_domain/registered_domain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,25 @@ func TestProcessorRun(t *testing.T) {
Error bool
Domain string
RegisteredDomain string
Subdomain string
}{
{false, "www.google.com", "google.com"},
{false, "www.google.co.uk", "google.co.uk"},
{false, "google.com", "google.com"},
{false, "www.ak.local", "ak.local"},
{false, "www.navy.mil", "navy.mil"},
{false, "www.google.com", "google.com", "www"},
{false, "www.google.co.uk", "google.co.uk", "www"},
{false, "www.mail.google.co.uk", "google.co.uk", "www.mail"},
{false, "google.com", "google.com", ""},
{false, "www.ak.local", "ak.local", "www"},
{false, "www.navy.mil", "navy.mil", "www"},

{true, "com", ""},
{true, ".", "."},
{true, "", ""},
{true, "localhost", ""},
{true, "com", "", ""},
{true, ".", ".", ""},
{true, "", "", ""},
{true, "localhost", "", ""},
}

c := defaultConfig()
c.Field = "domain"
c.TargetField = "registered_domain"
c.TargetSubdomainField = "subdomain"
p, err := newRegisteredDomain(c)
if err != nil {
t.Fatal(err)
Expand All @@ -71,5 +74,10 @@ func TestProcessorRun(t *testing.T) {

rd, _ := evt.GetValue("registered_domain")
assert.Equal(t, tc.RegisteredDomain, rd)

if tc.Subdomain != "" {
subdomain, _ := evt.GetValue("subdomain")
assert.Equal(t, tc.Subdomain, subdomain)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1563,6 +1563,7 @@ var sysmon = (function () {
ignore_missing: true,
field: "dns.question.name",
target_field: "dns.question.registered_domain",
target_subdomain_field: "dns.question.subdomain",
})
.Add(setRuleName)
.Add(translateDnsQueryStatus)
Expand Down
Loading

0 comments on commit d38a5d0

Please sign in to comment.