howler-api 3.0.0.dev374__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of howler-api might be problematic. Click here for more details.
- howler/__init__.py +0 -0
- howler/actions/__init__.py +168 -0
- howler/actions/add_label.py +111 -0
- howler/actions/add_to_bundle.py +159 -0
- howler/actions/change_field.py +76 -0
- howler/actions/demote.py +160 -0
- howler/actions/example_plugin.py +104 -0
- howler/actions/prioritization.py +93 -0
- howler/actions/promote.py +147 -0
- howler/actions/remove_from_bundle.py +133 -0
- howler/actions/remove_label.py +111 -0
- howler/actions/transition.py +200 -0
- howler/api/__init__.py +249 -0
- howler/api/base.py +88 -0
- howler/api/socket.py +114 -0
- howler/api/v1/__init__.py +97 -0
- howler/api/v1/action.py +372 -0
- howler/api/v1/analytic.py +748 -0
- howler/api/v1/auth.py +382 -0
- howler/api/v1/clue.py +99 -0
- howler/api/v1/configs.py +58 -0
- howler/api/v1/dossier.py +222 -0
- howler/api/v1/help.py +28 -0
- howler/api/v1/hit.py +1181 -0
- howler/api/v1/notebook.py +82 -0
- howler/api/v1/overview.py +191 -0
- howler/api/v1/search.py +788 -0
- howler/api/v1/template.py +206 -0
- howler/api/v1/tool.py +183 -0
- howler/api/v1/user.py +416 -0
- howler/api/v1/utils/__init__.py +0 -0
- howler/api/v1/utils/etag.py +84 -0
- howler/api/v1/view.py +288 -0
- howler/app.py +235 -0
- howler/common/README.md +125 -0
- howler/common/__init__.py +0 -0
- howler/common/classification.py +979 -0
- howler/common/classification.yml +107 -0
- howler/common/exceptions.py +167 -0
- howler/common/loader.py +154 -0
- howler/common/logging/__init__.py +241 -0
- howler/common/logging/audit.py +138 -0
- howler/common/logging/format.py +38 -0
- howler/common/net.py +79 -0
- howler/common/net_static.py +1494 -0
- howler/common/random_user.py +316 -0
- howler/common/swagger.py +117 -0
- howler/config.py +64 -0
- howler/cronjobs/__init__.py +29 -0
- howler/cronjobs/retention.py +61 -0
- howler/cronjobs/rules.py +274 -0
- howler/cronjobs/view_cleanup.py +88 -0
- howler/datastore/README.md +112 -0
- howler/datastore/__init__.py +0 -0
- howler/datastore/bulk.py +72 -0
- howler/datastore/collection.py +2342 -0
- howler/datastore/constants.py +119 -0
- howler/datastore/exceptions.py +41 -0
- howler/datastore/howler_store.py +105 -0
- howler/datastore/migrations/fix_process.py +41 -0
- howler/datastore/operations.py +130 -0
- howler/datastore/schemas.py +90 -0
- howler/datastore/store.py +231 -0
- howler/datastore/support/__init__.py +0 -0
- howler/datastore/support/build.py +215 -0
- howler/datastore/support/schemas.py +90 -0
- howler/datastore/types.py +22 -0
- howler/error.py +91 -0
- howler/external/__init__.py +0 -0
- howler/external/generate_mitre.py +96 -0
- howler/external/generate_sigma_rules.py +31 -0
- howler/external/generate_tlds.py +47 -0
- howler/external/reindex_data.py +66 -0
- howler/external/wipe_databases.py +58 -0
- howler/gunicorn_config.py +25 -0
- howler/healthz.py +47 -0
- howler/helper/__init__.py +0 -0
- howler/helper/azure.py +50 -0
- howler/helper/discover.py +59 -0
- howler/helper/hit.py +236 -0
- howler/helper/oauth.py +247 -0
- howler/helper/search.py +92 -0
- howler/helper/workflow.py +110 -0
- howler/helper/ws.py +378 -0
- howler/odm/README.md +102 -0
- howler/odm/__init__.py +1 -0
- howler/odm/base.py +1543 -0
- howler/odm/charter.txt +146 -0
- howler/odm/helper.py +416 -0
- howler/odm/howler_enum.py +25 -0
- howler/odm/models/__init__.py +0 -0
- howler/odm/models/action.py +33 -0
- howler/odm/models/analytic.py +90 -0
- howler/odm/models/assemblyline.py +48 -0
- howler/odm/models/aws.py +23 -0
- howler/odm/models/azure.py +16 -0
- howler/odm/models/cbs.py +44 -0
- howler/odm/models/config.py +558 -0
- howler/odm/models/dossier.py +33 -0
- howler/odm/models/ecs/__init__.py +0 -0
- howler/odm/models/ecs/agent.py +17 -0
- howler/odm/models/ecs/autonomous_system.py +16 -0
- howler/odm/models/ecs/client.py +149 -0
- howler/odm/models/ecs/cloud.py +141 -0
- howler/odm/models/ecs/code_signature.py +27 -0
- howler/odm/models/ecs/container.py +32 -0
- howler/odm/models/ecs/dns.py +62 -0
- howler/odm/models/ecs/egress.py +10 -0
- howler/odm/models/ecs/elf.py +74 -0
- howler/odm/models/ecs/email.py +122 -0
- howler/odm/models/ecs/error.py +14 -0
- howler/odm/models/ecs/event.py +140 -0
- howler/odm/models/ecs/faas.py +24 -0
- howler/odm/models/ecs/file.py +84 -0
- howler/odm/models/ecs/geo.py +30 -0
- howler/odm/models/ecs/group.py +18 -0
- howler/odm/models/ecs/hash.py +16 -0
- howler/odm/models/ecs/host.py +17 -0
- howler/odm/models/ecs/http.py +37 -0
- howler/odm/models/ecs/ingress.py +12 -0
- howler/odm/models/ecs/interface.py +21 -0
- howler/odm/models/ecs/network.py +30 -0
- howler/odm/models/ecs/observer.py +45 -0
- howler/odm/models/ecs/organization.py +12 -0
- howler/odm/models/ecs/os.py +21 -0
- howler/odm/models/ecs/pe.py +17 -0
- howler/odm/models/ecs/process.py +216 -0
- howler/odm/models/ecs/registry.py +26 -0
- howler/odm/models/ecs/related.py +45 -0
- howler/odm/models/ecs/rule.py +51 -0
- howler/odm/models/ecs/server.py +24 -0
- howler/odm/models/ecs/threat.py +247 -0
- howler/odm/models/ecs/tls.py +58 -0
- howler/odm/models/ecs/url.py +51 -0
- howler/odm/models/ecs/user.py +57 -0
- howler/odm/models/ecs/user_agent.py +20 -0
- howler/odm/models/ecs/vulnerability.py +41 -0
- howler/odm/models/gcp.py +16 -0
- howler/odm/models/hit.py +356 -0
- howler/odm/models/howler_data.py +328 -0
- howler/odm/models/lead.py +24 -0
- howler/odm/models/localized_label.py +13 -0
- howler/odm/models/overview.py +16 -0
- howler/odm/models/pivot.py +40 -0
- howler/odm/models/template.py +24 -0
- howler/odm/models/user.py +83 -0
- howler/odm/models/view.py +34 -0
- howler/odm/random_data.py +888 -0
- howler/odm/randomizer.py +609 -0
- howler/patched.py +5 -0
- howler/plugins/__init__.py +25 -0
- howler/plugins/config.py +123 -0
- howler/remote/__init__.py +0 -0
- howler/remote/datatypes/README.md +355 -0
- howler/remote/datatypes/__init__.py +98 -0
- howler/remote/datatypes/counters.py +63 -0
- howler/remote/datatypes/events.py +66 -0
- howler/remote/datatypes/hash.py +206 -0
- howler/remote/datatypes/lock.py +42 -0
- howler/remote/datatypes/queues/__init__.py +0 -0
- howler/remote/datatypes/queues/comms.py +59 -0
- howler/remote/datatypes/queues/multi.py +32 -0
- howler/remote/datatypes/queues/named.py +93 -0
- howler/remote/datatypes/queues/priority.py +215 -0
- howler/remote/datatypes/set.py +118 -0
- howler/remote/datatypes/user_quota_tracker.py +54 -0
- howler/security/__init__.py +253 -0
- howler/security/socket.py +108 -0
- howler/security/utils.py +185 -0
- howler/services/__init__.py +0 -0
- howler/services/action_service.py +111 -0
- howler/services/analytic_service.py +128 -0
- howler/services/auth_service.py +323 -0
- howler/services/config_service.py +128 -0
- howler/services/dossier_service.py +252 -0
- howler/services/event_service.py +93 -0
- howler/services/hit_service.py +893 -0
- howler/services/jwt_service.py +158 -0
- howler/services/lucene_service.py +286 -0
- howler/services/notebook_service.py +119 -0
- howler/services/overview_service.py +44 -0
- howler/services/template_service.py +45 -0
- howler/services/user_service.py +331 -0
- howler/utils/__init__.py +0 -0
- howler/utils/annotations.py +28 -0
- howler/utils/chunk.py +38 -0
- howler/utils/dict_utils.py +200 -0
- howler/utils/isotime.py +17 -0
- howler/utils/list_utils.py +11 -0
- howler/utils/lucene.py +77 -0
- howler/utils/path.py +27 -0
- howler/utils/socket_utils.py +61 -0
- howler/utils/str_utils.py +256 -0
- howler/utils/uid.py +47 -0
- howler_api-3.0.0.dev374.dist-info/METADATA +71 -0
- howler_api-3.0.0.dev374.dist-info/RECORD +198 -0
- howler_api-3.0.0.dev374.dist-info/WHEEL +4 -0
- howler_api-3.0.0.dev374.dist-info/entry_points.txt +8 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from howler import odm
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@odm.model(
|
|
5
|
+
index=True,
|
|
6
|
+
store=True,
|
|
7
|
+
description="URL fields provide support for complete or partial URLs, and supports "
|
|
8
|
+
"the breaking down into scheme, domain, path, and so on.",
|
|
9
|
+
)
|
|
10
|
+
class URL(odm.Model):
|
|
11
|
+
domain = odm.Optional(odm.Domain(description='Domain of the url, such as "www.elastic.co".'))
|
|
12
|
+
extension = odm.Optional(
|
|
13
|
+
odm.Keyword(
|
|
14
|
+
description="The field contains the file extension from the original request "
|
|
15
|
+
"url, excluding the leading dot."
|
|
16
|
+
)
|
|
17
|
+
)
|
|
18
|
+
fragment = odm.Optional(odm.Keyword(description='Portion of the url after the #, such as "top".'))
|
|
19
|
+
full = odm.Optional(
|
|
20
|
+
odm.Keyword(
|
|
21
|
+
description="If full URLs are important to your use case, they should be stored "
|
|
22
|
+
"in url.full, whether this field is reconstructed or present in the event source."
|
|
23
|
+
)
|
|
24
|
+
)
|
|
25
|
+
original = odm.Optional(odm.Keyword(description="Unmodified original url as seen in the event source."))
|
|
26
|
+
password = odm.Optional(odm.Keyword(description="Password of the request."))
|
|
27
|
+
path = odm.Optional(odm.Keyword(description='Path of the request, such as "/search".'))
|
|
28
|
+
port = odm.Optional(odm.Integer(description="Port of the request, such as 443."))
|
|
29
|
+
query = odm.Optional(
|
|
30
|
+
odm.Keyword(
|
|
31
|
+
description="The query field describes the query string of the " 'request, such as "q=elasticsearch".'
|
|
32
|
+
)
|
|
33
|
+
)
|
|
34
|
+
registered_domain = odm.Optional(
|
|
35
|
+
odm.Keyword(description="The highest registered url domain, " "stripped of the subdomain.")
|
|
36
|
+
)
|
|
37
|
+
scheme = odm.Optional(odm.Keyword(description='Scheme of the request, such as "https".'))
|
|
38
|
+
subdomain = odm.Optional(
|
|
39
|
+
odm.Keyword(
|
|
40
|
+
description="The subdomain portion of a fully qualified domain name includes "
|
|
41
|
+
"all of the names except the host name under "
|
|
42
|
+
"the registered_domain."
|
|
43
|
+
)
|
|
44
|
+
)
|
|
45
|
+
top_level_domain = odm.Optional(
|
|
46
|
+
odm.Keyword(
|
|
47
|
+
description="The effective top level domain (eTLD), also known as "
|
|
48
|
+
"the domain suffix, is the last part of the domain name."
|
|
49
|
+
)
|
|
50
|
+
)
|
|
51
|
+
username = odm.Optional(odm.Keyword(description="Username of the request."))
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from howler import odm
|
|
2
|
+
from howler.odm.models.ecs.group import Group
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@odm.model(
|
|
6
|
+
index=True,
|
|
7
|
+
store=True,
|
|
8
|
+
description="The user fields describe information about the user that is relevant to the event.",
|
|
9
|
+
)
|
|
10
|
+
class UserNested(odm.Model):
|
|
11
|
+
domain = odm.Optional(odm.Keyword(description="Name of the directory the user is a member of."))
|
|
12
|
+
email = odm.Optional(odm.Email(description="User email address."))
|
|
13
|
+
full_name = odm.Optional(odm.Keyword(description="User’s full name, if available."))
|
|
14
|
+
hash = odm.Optional(
|
|
15
|
+
odm.Keyword(description="Unique user hash to correlate information for a user in anonymized form.")
|
|
16
|
+
)
|
|
17
|
+
id = odm.Optional(odm.Keyword(description="Unique identifier of the user."))
|
|
18
|
+
name = odm.Optional(odm.Keyword(description="Short name or login of the user."))
|
|
19
|
+
roles = odm.Optional(
|
|
20
|
+
odm.List(
|
|
21
|
+
odm.Keyword(),
|
|
22
|
+
default=[],
|
|
23
|
+
description="Array of user roles at the time of the event.",
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@odm.model(
|
|
29
|
+
index=True,
|
|
30
|
+
store=True,
|
|
31
|
+
description="The user fields describe information about the user that is relevant to the event.",
|
|
32
|
+
)
|
|
33
|
+
class User(odm.Model):
|
|
34
|
+
domain = odm.Optional(odm.Keyword(description="Name of the directory the user is a member of."))
|
|
35
|
+
email = odm.Optional(odm.Email(description="User email address."))
|
|
36
|
+
full_name = odm.Optional(odm.Keyword(description="User's full name, if available."))
|
|
37
|
+
group = odm.Optional(odm.Compound(Group, description="User's group relevant to the event."))
|
|
38
|
+
hash = odm.Optional(
|
|
39
|
+
odm.Keyword(description="Unique user hash to correlate information for a user in anonymized form.")
|
|
40
|
+
)
|
|
41
|
+
id = odm.Optional(odm.Keyword(description="Unique identifier of the user."))
|
|
42
|
+
name = odm.Optional(odm.Keyword(description="Short name or login of the user."))
|
|
43
|
+
roles = odm.Optional(
|
|
44
|
+
odm.List(
|
|
45
|
+
odm.Keyword(),
|
|
46
|
+
default=[],
|
|
47
|
+
description="Array of user roles at the time of the event.",
|
|
48
|
+
)
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@odm.model(index=True, store=True, description="Shorter representation of a user.")
|
|
53
|
+
class ShortUser(odm.Model):
|
|
54
|
+
id = odm.Optional(odm.Keyword(description="Unique identifier of the user."))
|
|
55
|
+
name = odm.Optional(odm.Keyword(description="Short name or login of the user."))
|
|
56
|
+
domain = odm.Optional(odm.Keyword(description="Name of the directory the user is a member of."))
|
|
57
|
+
email = odm.Optional(odm.Email(description="User email address."))
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from howler import odm
|
|
2
|
+
from howler.odm.models.ecs.os import OS
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@odm.model(index=True, store=True, description="Information about the device.")
|
|
6
|
+
class Device(odm.Model):
|
|
7
|
+
name = odm.Optional(odm.Keyword(description="Name of the device."))
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@odm.model(
|
|
11
|
+
index=True,
|
|
12
|
+
store=True,
|
|
13
|
+
description="The user_agent fields normally come from a browser request.",
|
|
14
|
+
)
|
|
15
|
+
class UserAgent(odm.Model):
|
|
16
|
+
device = odm.Optional(odm.Compound(Device, description="Information about the device."))
|
|
17
|
+
name = odm.Optional(odm.Keyword(description="Name of the user agent."))
|
|
18
|
+
original = odm.Optional(odm.Keyword(description="Unparsed user_agent string."))
|
|
19
|
+
os = odm.Optional(odm.Compound(OS, description="OS fields contain information about the operating system."))
|
|
20
|
+
version = odm.Optional(odm.Keyword(description="Version of the user agent."))
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from howler import odm
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@odm.model(
|
|
5
|
+
index=True,
|
|
6
|
+
store=True,
|
|
7
|
+
description="The user_agent fields normally come from a browser request.",
|
|
8
|
+
)
|
|
9
|
+
class Vulnerability(odm.Model):
|
|
10
|
+
category = odm.Optional(
|
|
11
|
+
odm.List(
|
|
12
|
+
odm.Keyword(),
|
|
13
|
+
description="The type of system or architecture that the vulnerability affects. These may be "
|
|
14
|
+
"platform-specific (for example, Debian or SUSE) or general (for example, Database or Firewall).",
|
|
15
|
+
)
|
|
16
|
+
)
|
|
17
|
+
classification = odm.Optional(
|
|
18
|
+
odm.Keyword(
|
|
19
|
+
description="The classification of the vulnerability scoring system. "
|
|
20
|
+
"For example (https://www.first.org/cvss/)"
|
|
21
|
+
)
|
|
22
|
+
)
|
|
23
|
+
description = odm.Optional(
|
|
24
|
+
odm.Keyword(
|
|
25
|
+
description="The description of the vulnerability that provides additional context of the vulnerability."
|
|
26
|
+
)
|
|
27
|
+
)
|
|
28
|
+
enumeration = odm.Optional(odm.Keyword(description="The type of identifier used for this vulnerability."))
|
|
29
|
+
id = odm.Optional(
|
|
30
|
+
odm.Keyword(
|
|
31
|
+
description="The identification (ID) is the number portion of a vulnerability entry. It includes a "
|
|
32
|
+
"unique identification number for the vulnerability."
|
|
33
|
+
)
|
|
34
|
+
)
|
|
35
|
+
reference = odm.Optional(
|
|
36
|
+
odm.Keyword(
|
|
37
|
+
description="A resource that provides additional information, context, and mitigations for the "
|
|
38
|
+
"identified vulnerability."
|
|
39
|
+
)
|
|
40
|
+
)
|
|
41
|
+
report_id = odm.Optional(odm.Keyword(description="The report or scan identification number."))
|
howler/odm/models/gcp.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from howler import odm
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@odm.model(
|
|
5
|
+
index=True,
|
|
6
|
+
store=True,
|
|
7
|
+
description="Fields related to Google Cloud Platform.",
|
|
8
|
+
)
|
|
9
|
+
class GCP(odm.Model):
|
|
10
|
+
project_id = odm.Optional(odm.Keyword(description="The unique identifier for the GCP project."))
|
|
11
|
+
network_id = odm.Optional(
|
|
12
|
+
odm.Keyword(description="The unique identifier for a Google Cloud Platform (GCP) network.")
|
|
13
|
+
)
|
|
14
|
+
zone = odm.Optional(odm.Keyword(description="The GCP zone of the instance."))
|
|
15
|
+
service_account_id = odm.Optional(odm.Keyword(description="Unique identifier for a GCP service account."))
|
|
16
|
+
resource_id = odm.Optional(odm.Keyword(description="Unique GCP resource identifier."))
|
howler/odm/models/hit.py
ADDED
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
# mypy: ignore-errors
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from howler import odm
|
|
5
|
+
from howler.common.logging import get_logger
|
|
6
|
+
from howler.odm.models.assemblyline import AssemblyLine
|
|
7
|
+
from howler.odm.models.aws import AWS
|
|
8
|
+
from howler.odm.models.azure import Azure
|
|
9
|
+
from howler.odm.models.cbs import CBS
|
|
10
|
+
from howler.odm.models.ecs.agent import Agent
|
|
11
|
+
from howler.odm.models.ecs.client import Client
|
|
12
|
+
from howler.odm.models.ecs.cloud import Cloud
|
|
13
|
+
from howler.odm.models.ecs.container import Container
|
|
14
|
+
from howler.odm.models.ecs.dns import DNS
|
|
15
|
+
from howler.odm.models.ecs.email import Email
|
|
16
|
+
from howler.odm.models.ecs.error import Error
|
|
17
|
+
from howler.odm.models.ecs.event import Event
|
|
18
|
+
from howler.odm.models.ecs.faas import FAAS
|
|
19
|
+
from howler.odm.models.ecs.file import File
|
|
20
|
+
from howler.odm.models.ecs.group import Group
|
|
21
|
+
from howler.odm.models.ecs.host import Host
|
|
22
|
+
from howler.odm.models.ecs.http import HTTP
|
|
23
|
+
from howler.odm.models.ecs.interface import Interface
|
|
24
|
+
from howler.odm.models.ecs.network import Network
|
|
25
|
+
from howler.odm.models.ecs.observer import Observer
|
|
26
|
+
from howler.odm.models.ecs.organization import Organization
|
|
27
|
+
from howler.odm.models.ecs.process import Process
|
|
28
|
+
from howler.odm.models.ecs.registry import Registry
|
|
29
|
+
from howler.odm.models.ecs.related import Related
|
|
30
|
+
from howler.odm.models.ecs.rule import Rule
|
|
31
|
+
from howler.odm.models.ecs.server import Server
|
|
32
|
+
from howler.odm.models.ecs.threat import Threat
|
|
33
|
+
from howler.odm.models.ecs.tls import TLS
|
|
34
|
+
from howler.odm.models.ecs.url import URL
|
|
35
|
+
from howler.odm.models.ecs.user import User
|
|
36
|
+
from howler.odm.models.ecs.user_agent import UserAgent
|
|
37
|
+
from howler.odm.models.ecs.vulnerability import Vulnerability
|
|
38
|
+
from howler.odm.models.gcp import GCP
|
|
39
|
+
from howler.odm.models.howler_data import HowlerData
|
|
40
|
+
|
|
41
|
+
logger = get_logger(__file__)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@odm.model(index=True, store=True, description="ECS model version")
|
|
45
|
+
class ECSVersion(odm.Model):
|
|
46
|
+
version: str = odm.Keyword(
|
|
47
|
+
default="8.3.0",
|
|
48
|
+
description="Additional information about the certificate status.",
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@odm.model(
|
|
53
|
+
index=True,
|
|
54
|
+
store=True,
|
|
55
|
+
description="Howler Outline schema which is an extended version of Elastic Common Schema (ECS)",
|
|
56
|
+
)
|
|
57
|
+
class Hit(odm.Model):
|
|
58
|
+
# Base Fields
|
|
59
|
+
timestamp: str = odm.Date(
|
|
60
|
+
default="NOW",
|
|
61
|
+
description="Date/time when the event originated.",
|
|
62
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-base.html",
|
|
63
|
+
)
|
|
64
|
+
labels: dict[str, str] = odm.Mapping(
|
|
65
|
+
odm.Keyword(),
|
|
66
|
+
default={},
|
|
67
|
+
description="Custom key/value pairs.",
|
|
68
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-base.html",
|
|
69
|
+
)
|
|
70
|
+
tags: list[str] = odm.List(
|
|
71
|
+
odm.Keyword(),
|
|
72
|
+
default=[],
|
|
73
|
+
description="List of keywords used to tag each event.",
|
|
74
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-base.html",
|
|
75
|
+
)
|
|
76
|
+
message: str = odm.Keyword(
|
|
77
|
+
default="",
|
|
78
|
+
description="Log message for log events, optimized for viewing in a log viewer",
|
|
79
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-base.html",
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# Howler extended fields. Deviates from ECS
|
|
83
|
+
howler: HowlerData = odm.Compound(
|
|
84
|
+
HowlerData,
|
|
85
|
+
description="Howler specific definition of the hit that matches the outline.",
|
|
86
|
+
reference="https://confluence.devtools.cse-cst.gc.ca/display/~jjgalar/Hit+Schema",
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
assemblyline: Optional[AssemblyLine] = odm.Optional(
|
|
90
|
+
odm.Compound(
|
|
91
|
+
AssemblyLine,
|
|
92
|
+
description="AssemblyLine metadata associated with this alert.",
|
|
93
|
+
)
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# Field Sets
|
|
97
|
+
agent: Agent = odm.Optional(
|
|
98
|
+
odm.Compound(
|
|
99
|
+
Agent,
|
|
100
|
+
description="The agent fields contain the data about the software entity, "
|
|
101
|
+
"if any, that collects, detects, or observes events on a host, or takes measurements on a host.",
|
|
102
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-agent.html",
|
|
103
|
+
)
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
aws: AWS = odm.Optional(
|
|
107
|
+
odm.Compound(
|
|
108
|
+
AWS,
|
|
109
|
+
description="Fields related to AWS.",
|
|
110
|
+
)
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
azure: Azure = odm.Optional(
|
|
114
|
+
odm.Compound(
|
|
115
|
+
Azure,
|
|
116
|
+
description="Fields related to Azure.",
|
|
117
|
+
)
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
cbs: CBS = odm.Optional(odm.Compound(CBS, description="CBS metadata associated with this alert."))
|
|
121
|
+
cloud: Cloud = odm.Optional(
|
|
122
|
+
odm.Compound(
|
|
123
|
+
Cloud,
|
|
124
|
+
description="Fields related to the cloud or infrastructure the events are coming from.",
|
|
125
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-cloud.html",
|
|
126
|
+
)
|
|
127
|
+
)
|
|
128
|
+
container: Container = odm.Optional(
|
|
129
|
+
odm.Compound(
|
|
130
|
+
Container,
|
|
131
|
+
description="Container fields are used for meta information about the specific container "
|
|
132
|
+
"that is the source of information.",
|
|
133
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-container.html",
|
|
134
|
+
)
|
|
135
|
+
)
|
|
136
|
+
destination: Client = odm.Optional(
|
|
137
|
+
odm.Compound(
|
|
138
|
+
Client,
|
|
139
|
+
description="Destination fields capture details about the receiver of a network exchange/packet.",
|
|
140
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-destination.html",
|
|
141
|
+
)
|
|
142
|
+
)
|
|
143
|
+
dns: DNS = odm.Optional(
|
|
144
|
+
odm.Compound(
|
|
145
|
+
DNS,
|
|
146
|
+
description="Fields describing DNS queries and answers.",
|
|
147
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-dns.html",
|
|
148
|
+
)
|
|
149
|
+
)
|
|
150
|
+
ecs: ECSVersion = odm.Compound(
|
|
151
|
+
ECSVersion,
|
|
152
|
+
default={},
|
|
153
|
+
description="Meta-information specific to ECS.",
|
|
154
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-ecs.html",
|
|
155
|
+
)
|
|
156
|
+
error: Error = odm.Optional(
|
|
157
|
+
odm.Compound(
|
|
158
|
+
Error,
|
|
159
|
+
description="These fields can represent errors of any kind.",
|
|
160
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-error.html",
|
|
161
|
+
)
|
|
162
|
+
)
|
|
163
|
+
event: Event = odm.Optional(
|
|
164
|
+
odm.Compound(
|
|
165
|
+
Event,
|
|
166
|
+
description="The event fields are used for context information about the log or metric event itself.",
|
|
167
|
+
)
|
|
168
|
+
)
|
|
169
|
+
email: Email = odm.Optional(
|
|
170
|
+
odm.Compound(
|
|
171
|
+
Email,
|
|
172
|
+
description="Event details relating to an email transaction.",
|
|
173
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-event.html",
|
|
174
|
+
)
|
|
175
|
+
)
|
|
176
|
+
faas: FAAS = odm.Optional(
|
|
177
|
+
odm.Compound(
|
|
178
|
+
FAAS,
|
|
179
|
+
description="The user fields describe information about the function as a service "
|
|
180
|
+
"(FaaS) that is relevant to the event.",
|
|
181
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-faas.html",
|
|
182
|
+
)
|
|
183
|
+
)
|
|
184
|
+
file: File = odm.Optional(
|
|
185
|
+
odm.Compound(
|
|
186
|
+
File,
|
|
187
|
+
description="A file is defined as a set of information that has been "
|
|
188
|
+
"created on, or has existed on a filesystem.",
|
|
189
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-file.html",
|
|
190
|
+
)
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
gcp: GCP = odm.Optional(
|
|
194
|
+
odm.Compound(
|
|
195
|
+
GCP,
|
|
196
|
+
description="Fields related to Google Cloud Platform.",
|
|
197
|
+
)
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
group: Group = odm.Optional(
|
|
201
|
+
odm.Compound(
|
|
202
|
+
Group,
|
|
203
|
+
description="The group fields are meant to represent groups that are relevant to the event.",
|
|
204
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-group.html",
|
|
205
|
+
)
|
|
206
|
+
)
|
|
207
|
+
host: Host = odm.Optional(
|
|
208
|
+
odm.Compound(Host),
|
|
209
|
+
description=(
|
|
210
|
+
"A host is defined as a general computing instance. ECS host.* fields should be populated with details "
|
|
211
|
+
"about the host on which the event happened, or from which the measurement was taken. Host types include "
|
|
212
|
+
"hardware, virtual machines, Docker containers, and Kubernetes nodes."
|
|
213
|
+
),
|
|
214
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-host.html",
|
|
215
|
+
)
|
|
216
|
+
http: HTTP = odm.Optional(
|
|
217
|
+
odm.Compound(
|
|
218
|
+
HTTP,
|
|
219
|
+
description="Fields related to HTTP activity. Use the url field set to store the url of the request.",
|
|
220
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-http.html",
|
|
221
|
+
)
|
|
222
|
+
)
|
|
223
|
+
observer: Observer = odm.Optional(
|
|
224
|
+
odm.Compound(
|
|
225
|
+
Observer,
|
|
226
|
+
description=(
|
|
227
|
+
"Observer is defined as a special network, security, or application device used to detect, obs"
|
|
228
|
+
"erve, or create network, sercurity, or application event metrics"
|
|
229
|
+
),
|
|
230
|
+
)
|
|
231
|
+
)
|
|
232
|
+
interface: Interface = odm.Optional(
|
|
233
|
+
odm.Compound(
|
|
234
|
+
Interface,
|
|
235
|
+
description=(
|
|
236
|
+
"The interface fields are used to record ingress and egress interface information when reported "
|
|
237
|
+
"by an observer (e.g. firewall, router, load balancer) in the context of the observer handling a "
|
|
238
|
+
"network connection. "
|
|
239
|
+
),
|
|
240
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-interface.html",
|
|
241
|
+
)
|
|
242
|
+
)
|
|
243
|
+
network: Network = odm.Optional(
|
|
244
|
+
odm.Compound(
|
|
245
|
+
Network,
|
|
246
|
+
description=(
|
|
247
|
+
"The network is defined as the communication path over which a host or network event happens."
|
|
248
|
+
),
|
|
249
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-network.html",
|
|
250
|
+
)
|
|
251
|
+
)
|
|
252
|
+
organization: Organization = odm.Optional(
|
|
253
|
+
odm.Compound(
|
|
254
|
+
Organization,
|
|
255
|
+
description="The organization fields enrich data with information "
|
|
256
|
+
"about the company or entity the data is associated with.",
|
|
257
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-organization.html",
|
|
258
|
+
)
|
|
259
|
+
)
|
|
260
|
+
process: Process = odm.Optional(
|
|
261
|
+
odm.Compound(
|
|
262
|
+
Process,
|
|
263
|
+
description="These fields contain information about a process.",
|
|
264
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-process.html",
|
|
265
|
+
)
|
|
266
|
+
)
|
|
267
|
+
registry: Registry = odm.Optional(
|
|
268
|
+
odm.Compound(
|
|
269
|
+
Registry,
|
|
270
|
+
description="Fields related to Windows Registry operations.",
|
|
271
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-registry.html",
|
|
272
|
+
)
|
|
273
|
+
)
|
|
274
|
+
related: Related = odm.Optional(
|
|
275
|
+
odm.Compound(
|
|
276
|
+
Related,
|
|
277
|
+
description="Fields related to Windows Registry operations.",
|
|
278
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-related.html",
|
|
279
|
+
)
|
|
280
|
+
)
|
|
281
|
+
rule: Rule = odm.Optional(
|
|
282
|
+
odm.Compound(
|
|
283
|
+
Rule,
|
|
284
|
+
description="Capture the specifics of any observer or agent rules",
|
|
285
|
+
)
|
|
286
|
+
)
|
|
287
|
+
server: Server = odm.Optional(
|
|
288
|
+
odm.Compound(Server),
|
|
289
|
+
description=(
|
|
290
|
+
"A Server is defined as the responder in a network connection for events regarding sessions, "
|
|
291
|
+
"connections, or bidirectional flow records."
|
|
292
|
+
),
|
|
293
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-server.html",
|
|
294
|
+
)
|
|
295
|
+
source: Client = odm.Optional(
|
|
296
|
+
odm.Compound(
|
|
297
|
+
Client,
|
|
298
|
+
description="Source fields capture details about the sender of a network exchange/packet.",
|
|
299
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-source.html",
|
|
300
|
+
)
|
|
301
|
+
)
|
|
302
|
+
threat: Threat = odm.Optional(
|
|
303
|
+
odm.Compound(
|
|
304
|
+
Threat,
|
|
305
|
+
description="Fields to classify events and alerts according to a threat taxonomy such as the "
|
|
306
|
+
"MITRE ATT&CK® framework.",
|
|
307
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-threat.html",
|
|
308
|
+
)
|
|
309
|
+
)
|
|
310
|
+
tls: TLS = odm.Optional(
|
|
311
|
+
odm.Compound(
|
|
312
|
+
TLS,
|
|
313
|
+
description=(
|
|
314
|
+
"Fields related to a TLS connection. These fields focus on the TLS protocol itself and "
|
|
315
|
+
"intentionally avoids in-depth analysis of the related x.509 certificate files."
|
|
316
|
+
),
|
|
317
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-tls.html",
|
|
318
|
+
)
|
|
319
|
+
)
|
|
320
|
+
url: URL = odm.Optional(
|
|
321
|
+
odm.Compound(
|
|
322
|
+
URL,
|
|
323
|
+
description="URL fields provide support for complete or partial URLs, and "
|
|
324
|
+
"supports the breaking down into scheme, domain, path, and so on.",
|
|
325
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-url.html",
|
|
326
|
+
)
|
|
327
|
+
)
|
|
328
|
+
user: User = odm.Optional(
|
|
329
|
+
odm.Compound(
|
|
330
|
+
User,
|
|
331
|
+
description="The user fields describe information about the user that is relevant to the event.",
|
|
332
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-user.html",
|
|
333
|
+
)
|
|
334
|
+
)
|
|
335
|
+
user_agent: UserAgent = odm.Optional(
|
|
336
|
+
odm.Compound(
|
|
337
|
+
UserAgent,
|
|
338
|
+
description="The user_agent fields normally come from a browser request.",
|
|
339
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-user_agent.html",
|
|
340
|
+
)
|
|
341
|
+
)
|
|
342
|
+
vulnerability: Vulnerability = odm.Optional(
|
|
343
|
+
odm.Compound(
|
|
344
|
+
Vulnerability,
|
|
345
|
+
description="The vulnerability fields describe information about a vulnerability that "
|
|
346
|
+
"is relevant to an event.",
|
|
347
|
+
reference="https://www.elastic.co/guide/en/ecs/8.5/ecs-vulnerability.html",
|
|
348
|
+
)
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
if __name__ == "__main__":
|
|
353
|
+
from pprint import pprint
|
|
354
|
+
|
|
355
|
+
fields = {k: f"{v.__class__.__name__}{' (array)' if v.multivalued else ''}" for k, v in Hit.flat_fields().items()}
|
|
356
|
+
pprint(fields) # noqa: T203
|