howler-api 2.13.0.dev329__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.
- howler/__init__.py +0 -0
- howler/actions/__init__.py +167 -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/borealis.py +101 -0
- howler/api/v1/configs.py +55 -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 +715 -0
- howler/api/v1/template.py +206 -0
- howler/api/v1/tool.py +183 -0
- howler/api/v1/user.py +414 -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 +144 -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/hexdump.py +48 -0
- howler/common/iprange.py +171 -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 +2327 -0
- howler/datastore/constants.py +117 -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 +214 -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 +46 -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 +1504 -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 +33 -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 +606 -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 +330 -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-2.13.0.dev329.dist-info/METADATA +71 -0
- howler_api-2.13.0.dev329.dist-info/RECORD +200 -0
- howler_api-2.13.0.dev329.dist-info/WHEEL +4 -0
- howler_api-2.13.0.dev329.dist-info/entry_points.txt +8 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# mypy: ignore-errors
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from howler import odm
|
|
5
|
+
from howler.odm.models.howler_data import Assessment
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@odm.model(index=True, store=True, description="Comment definition.")
|
|
9
|
+
class Comment(odm.Model):
|
|
10
|
+
id = odm.UUID(description="A unique ID for the comment")
|
|
11
|
+
timestamp = odm.Date(description="Timestamp at which the comment took place.", default="NOW")
|
|
12
|
+
modified = odm.Date(description="Timestamp at which the comment was last edited.", default="NOW")
|
|
13
|
+
detection: Optional[str] = odm.Keyword(
|
|
14
|
+
description="The detection the comment applies to, if it applies to a particular detection",
|
|
15
|
+
optional=True,
|
|
16
|
+
)
|
|
17
|
+
value = odm.Text(description="The comment itself.")
|
|
18
|
+
user = odm.Keyword(description="User ID who created the comment.")
|
|
19
|
+
reactions: dict[str, str] = odm.Mapping(
|
|
20
|
+
odm.Keyword(),
|
|
21
|
+
default={},
|
|
22
|
+
description="A list of reactions to the comment",
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
DEFAULT_TRIAGE = {"skip_rationale": False, "valid_assessments": Assessment.list()}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@odm.model(index=True, store=True, description="Settings for triaging this analytic.")
|
|
30
|
+
class TriageOptions(odm.Model):
|
|
31
|
+
valid_assessments: list[str] = odm.List(
|
|
32
|
+
odm.Keyword(),
|
|
33
|
+
default=DEFAULT_TRIAGE["valid_assessments"],
|
|
34
|
+
description="What list of assessments is valid for this analytic?",
|
|
35
|
+
)
|
|
36
|
+
skip_rationale: bool = odm.Boolean(
|
|
37
|
+
description="Should traiging alerts under this analytic skip the rationale field?",
|
|
38
|
+
default=DEFAULT_TRIAGE["skip_rationale"],
|
|
39
|
+
)
|
|
40
|
+
dossiers: list[str] = odm.List(
|
|
41
|
+
odm.Keyword(), description="A list of dossiers to present to the user when triaging alerts.", default=[]
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@odm.model(index=True, store=True, description="Notebook data")
|
|
46
|
+
class Notebook(odm.Model):
|
|
47
|
+
id = odm.UUID(description="A unique ID for the notebook")
|
|
48
|
+
detection: Optional[str] = odm.Keyword(
|
|
49
|
+
description="The detection the notebook applies to, if it applies to a particular detection",
|
|
50
|
+
optional=True,
|
|
51
|
+
)
|
|
52
|
+
value = odm.Text(description="The link to the notebook")
|
|
53
|
+
name = odm.Text(description="Name for the analytic")
|
|
54
|
+
user = odm.Keyword(description="User ID who added the notebook.")
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@odm.model(index=True, store=True, description="Metadata concerning a howler analytic, including configuration.")
|
|
58
|
+
class Analytic(odm.Model):
|
|
59
|
+
analytic_id: str = odm.UUID(description="A UUID for this analytic")
|
|
60
|
+
notebooks: list[Notebook] = odm.List(
|
|
61
|
+
odm.Compound(Notebook),
|
|
62
|
+
default=[],
|
|
63
|
+
description="A list of useful notebooks for the analytic",
|
|
64
|
+
)
|
|
65
|
+
name: str = odm.Keyword(description="The name of the analytic.")
|
|
66
|
+
owner: Optional[str] = odm.Keyword(description="The username of the user who owns this analytic.", optional=True)
|
|
67
|
+
contributors: list[str] = odm.List(
|
|
68
|
+
odm.Keyword(),
|
|
69
|
+
description="A list of users who have contributed to this analytic.",
|
|
70
|
+
default=[],
|
|
71
|
+
)
|
|
72
|
+
description: Optional[str] = odm.Text(description="A markdown description of the analytic", optional=True)
|
|
73
|
+
detections: list[str] = odm.List(
|
|
74
|
+
odm.Keyword(),
|
|
75
|
+
description="The detections which this analytic contains.",
|
|
76
|
+
default=[],
|
|
77
|
+
)
|
|
78
|
+
comment: list[Comment] = odm.List(
|
|
79
|
+
odm.Compound(Comment),
|
|
80
|
+
default=[],
|
|
81
|
+
description="A list of comments with timestamps and attribution.",
|
|
82
|
+
)
|
|
83
|
+
rule: Optional[str] = odm.Keyword(description="A rule query", optional=True)
|
|
84
|
+
rule_type: Optional[str] = odm.Optional(odm.Enum(values=["lucene", "eql", "sigma"], description="Type of rule"))
|
|
85
|
+
rule_crontab: Optional[str] = odm.Keyword(description="The interval for the rule to run at", optional=True)
|
|
86
|
+
triage_settings: Optional[TriageOptions] = odm.Compound(
|
|
87
|
+
TriageOptions,
|
|
88
|
+
description="Settings for triaging this analytic.",
|
|
89
|
+
default=DEFAULT_TRIAGE,
|
|
90
|
+
)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from howler import odm
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@odm.model(
|
|
5
|
+
index=True,
|
|
6
|
+
store=True,
|
|
7
|
+
)
|
|
8
|
+
class ALRecord(odm.Model):
|
|
9
|
+
type: str = odm.Optional(odm.Keyword())
|
|
10
|
+
subtype: str = odm.Optional(odm.Keyword())
|
|
11
|
+
value: str = odm.Optional(odm.Keyword())
|
|
12
|
+
verdict: str = odm.Optional(odm.Keyword())
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@odm.model(
|
|
16
|
+
index=True,
|
|
17
|
+
store=True,
|
|
18
|
+
)
|
|
19
|
+
class Mitre(odm.Model):
|
|
20
|
+
tactic: list[ALRecord] = odm.List(odm.Compound(ALRecord), default=[])
|
|
21
|
+
technique: list[ALRecord] = odm.List(odm.Compound(ALRecord), default=[])
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
DEFAULT_MITRE: dict[str, list[ALRecord]] = {"tactic": [], "technique": []}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@odm.model(
|
|
28
|
+
index=True,
|
|
29
|
+
store=True,
|
|
30
|
+
description="The AssemblyLine fields contain any data obtained from AssemblyLine relating to the alert.",
|
|
31
|
+
)
|
|
32
|
+
class AssemblyLine(odm.Model):
|
|
33
|
+
# al.detailed.av
|
|
34
|
+
antivirus: list[ALRecord] = odm.List(odm.Compound(ALRecord), default=[])
|
|
35
|
+
# al.detailed.attrib
|
|
36
|
+
attribution: list[ALRecord] = odm.List(odm.Compound(ALRecord), default=[])
|
|
37
|
+
# al.detailed.behavior
|
|
38
|
+
behaviour: list[ALRecord] = odm.List(odm.Compound(ALRecord), default=[])
|
|
39
|
+
# al.detailed.domain
|
|
40
|
+
domain: list[ALRecord] = odm.List(odm.Compound(ALRecord), default=[])
|
|
41
|
+
# al detailed.heuristic
|
|
42
|
+
heuristic: list[ALRecord] = odm.List(odm.Compound(ALRecord), default=[])
|
|
43
|
+
# al.detailed.[attack_category, attack_pattern]
|
|
44
|
+
mitre: Mitre = odm.Optional(odm.Compound(Mitre), default=DEFAULT_MITRE)
|
|
45
|
+
# al.detailed.uri
|
|
46
|
+
uri: list[ALRecord] = odm.List(odm.Compound(ALRecord), default=[])
|
|
47
|
+
# al.detailed.yara
|
|
48
|
+
yara: list[ALRecord] = odm.List(odm.Compound(ALRecord), default=[])
|
howler/odm/models/aws.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from howler import odm
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@odm.model(index=True, store=True, description="Cloud account information.")
|
|
5
|
+
class Account(odm.Model):
|
|
6
|
+
id = odm.Optional(odm.Keyword(description="The ID of the AWS Account."))
|
|
7
|
+
name = odm.Optional(odm.Keyword(description="The name of the AWS Account."))
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@odm.model(index=True, store=True, description="Organization information.")
|
|
11
|
+
class Organization(odm.Model):
|
|
12
|
+
id = odm.Optional(odm.Keyword(description="The ID of the AWS Organization."))
|
|
13
|
+
organizational_unit = odm.Optional(odm.Keyword(description="The Organizational Unit the Account belongs to."))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@odm.model(
|
|
17
|
+
index=True,
|
|
18
|
+
store=True,
|
|
19
|
+
description="Fields related to AWS.",
|
|
20
|
+
)
|
|
21
|
+
class AWS(odm.Model):
|
|
22
|
+
account = odm.Optional(odm.Compound(Account, description="AWS account information."))
|
|
23
|
+
organization = odm.Optional(odm.Compound(Organization, description="Organization information."))
|
|
@@ -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 Azure.",
|
|
8
|
+
)
|
|
9
|
+
class Azure(odm.Model):
|
|
10
|
+
subscription_id = odm.Optional(odm.Keyword(description="The unique identifier for the Azure subscription."))
|
|
11
|
+
tenant_id = odm.Optional(odm.Keyword(description="The unique identifier for the Azure tenant."))
|
|
12
|
+
resource_group = odm.Optional(odm.Keyword(description="The name of the Azure resource group."))
|
|
13
|
+
upn = odm.Optional(
|
|
14
|
+
odm.Keyword(description="The user principal name (UPN) in Azure, used for authentication. Alias of user.name.")
|
|
15
|
+
)
|
|
16
|
+
resource_id = odm.Optional(odm.Keyword(description="The unique Azure Resource Identifier (AzureRI)."))
|
howler/odm/models/cbs.py
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from howler import odm
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@odm.model(
|
|
5
|
+
index=True,
|
|
6
|
+
store=True,
|
|
7
|
+
)
|
|
8
|
+
class SharepointUser(odm.Model):
|
|
9
|
+
email: str = odm.Optional(odm.Email(description="The email of the sharepoint user associated with this item."))
|
|
10
|
+
full_name: str = odm.Optional(
|
|
11
|
+
odm.Keyword(description="The full name of the sharepoint user associated with this item.")
|
|
12
|
+
)
|
|
13
|
+
id: str = odm.Optional(odm.Keyword(description="The id of the sharepoint user associated with this item."))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@odm.model(
|
|
17
|
+
index=True,
|
|
18
|
+
store=True,
|
|
19
|
+
)
|
|
20
|
+
class SharepointData(odm.Model):
|
|
21
|
+
application: str = odm.Optional(odm.Keyword(description="The associated application."))
|
|
22
|
+
user: str = odm.Optional(odm.Keyword(description="The associated application."))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@odm.model(
|
|
26
|
+
index=True,
|
|
27
|
+
store=True,
|
|
28
|
+
)
|
|
29
|
+
class Sharepoint(odm.Model):
|
|
30
|
+
created: SharepointData = odm.Optional(
|
|
31
|
+
odm.Compound(SharepointData, description="Information about how the item was created.")
|
|
32
|
+
)
|
|
33
|
+
modified: SharepointData = odm.Optional(
|
|
34
|
+
odm.Compound(SharepointData, description="Information about how the item was modified.")
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@odm.model(
|
|
39
|
+
index=True,
|
|
40
|
+
store=True,
|
|
41
|
+
description="The cbs fields contain any data obtained from CBS relating to the alert.",
|
|
42
|
+
)
|
|
43
|
+
class CBS(odm.Model):
|
|
44
|
+
sharepoint: Sharepoint = odm.Optional(odm.Compound(Sharepoint, description="Sharepoint metadata"))
|