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.

Files changed (198) hide show
  1. howler/__init__.py +0 -0
  2. howler/actions/__init__.py +168 -0
  3. howler/actions/add_label.py +111 -0
  4. howler/actions/add_to_bundle.py +159 -0
  5. howler/actions/change_field.py +76 -0
  6. howler/actions/demote.py +160 -0
  7. howler/actions/example_plugin.py +104 -0
  8. howler/actions/prioritization.py +93 -0
  9. howler/actions/promote.py +147 -0
  10. howler/actions/remove_from_bundle.py +133 -0
  11. howler/actions/remove_label.py +111 -0
  12. howler/actions/transition.py +200 -0
  13. howler/api/__init__.py +249 -0
  14. howler/api/base.py +88 -0
  15. howler/api/socket.py +114 -0
  16. howler/api/v1/__init__.py +97 -0
  17. howler/api/v1/action.py +372 -0
  18. howler/api/v1/analytic.py +748 -0
  19. howler/api/v1/auth.py +382 -0
  20. howler/api/v1/clue.py +99 -0
  21. howler/api/v1/configs.py +58 -0
  22. howler/api/v1/dossier.py +222 -0
  23. howler/api/v1/help.py +28 -0
  24. howler/api/v1/hit.py +1181 -0
  25. howler/api/v1/notebook.py +82 -0
  26. howler/api/v1/overview.py +191 -0
  27. howler/api/v1/search.py +788 -0
  28. howler/api/v1/template.py +206 -0
  29. howler/api/v1/tool.py +183 -0
  30. howler/api/v1/user.py +416 -0
  31. howler/api/v1/utils/__init__.py +0 -0
  32. howler/api/v1/utils/etag.py +84 -0
  33. howler/api/v1/view.py +288 -0
  34. howler/app.py +235 -0
  35. howler/common/README.md +125 -0
  36. howler/common/__init__.py +0 -0
  37. howler/common/classification.py +979 -0
  38. howler/common/classification.yml +107 -0
  39. howler/common/exceptions.py +167 -0
  40. howler/common/loader.py +154 -0
  41. howler/common/logging/__init__.py +241 -0
  42. howler/common/logging/audit.py +138 -0
  43. howler/common/logging/format.py +38 -0
  44. howler/common/net.py +79 -0
  45. howler/common/net_static.py +1494 -0
  46. howler/common/random_user.py +316 -0
  47. howler/common/swagger.py +117 -0
  48. howler/config.py +64 -0
  49. howler/cronjobs/__init__.py +29 -0
  50. howler/cronjobs/retention.py +61 -0
  51. howler/cronjobs/rules.py +274 -0
  52. howler/cronjobs/view_cleanup.py +88 -0
  53. howler/datastore/README.md +112 -0
  54. howler/datastore/__init__.py +0 -0
  55. howler/datastore/bulk.py +72 -0
  56. howler/datastore/collection.py +2342 -0
  57. howler/datastore/constants.py +119 -0
  58. howler/datastore/exceptions.py +41 -0
  59. howler/datastore/howler_store.py +105 -0
  60. howler/datastore/migrations/fix_process.py +41 -0
  61. howler/datastore/operations.py +130 -0
  62. howler/datastore/schemas.py +90 -0
  63. howler/datastore/store.py +231 -0
  64. howler/datastore/support/__init__.py +0 -0
  65. howler/datastore/support/build.py +215 -0
  66. howler/datastore/support/schemas.py +90 -0
  67. howler/datastore/types.py +22 -0
  68. howler/error.py +91 -0
  69. howler/external/__init__.py +0 -0
  70. howler/external/generate_mitre.py +96 -0
  71. howler/external/generate_sigma_rules.py +31 -0
  72. howler/external/generate_tlds.py +47 -0
  73. howler/external/reindex_data.py +66 -0
  74. howler/external/wipe_databases.py +58 -0
  75. howler/gunicorn_config.py +25 -0
  76. howler/healthz.py +47 -0
  77. howler/helper/__init__.py +0 -0
  78. howler/helper/azure.py +50 -0
  79. howler/helper/discover.py +59 -0
  80. howler/helper/hit.py +236 -0
  81. howler/helper/oauth.py +247 -0
  82. howler/helper/search.py +92 -0
  83. howler/helper/workflow.py +110 -0
  84. howler/helper/ws.py +378 -0
  85. howler/odm/README.md +102 -0
  86. howler/odm/__init__.py +1 -0
  87. howler/odm/base.py +1543 -0
  88. howler/odm/charter.txt +146 -0
  89. howler/odm/helper.py +416 -0
  90. howler/odm/howler_enum.py +25 -0
  91. howler/odm/models/__init__.py +0 -0
  92. howler/odm/models/action.py +33 -0
  93. howler/odm/models/analytic.py +90 -0
  94. howler/odm/models/assemblyline.py +48 -0
  95. howler/odm/models/aws.py +23 -0
  96. howler/odm/models/azure.py +16 -0
  97. howler/odm/models/cbs.py +44 -0
  98. howler/odm/models/config.py +558 -0
  99. howler/odm/models/dossier.py +33 -0
  100. howler/odm/models/ecs/__init__.py +0 -0
  101. howler/odm/models/ecs/agent.py +17 -0
  102. howler/odm/models/ecs/autonomous_system.py +16 -0
  103. howler/odm/models/ecs/client.py +149 -0
  104. howler/odm/models/ecs/cloud.py +141 -0
  105. howler/odm/models/ecs/code_signature.py +27 -0
  106. howler/odm/models/ecs/container.py +32 -0
  107. howler/odm/models/ecs/dns.py +62 -0
  108. howler/odm/models/ecs/egress.py +10 -0
  109. howler/odm/models/ecs/elf.py +74 -0
  110. howler/odm/models/ecs/email.py +122 -0
  111. howler/odm/models/ecs/error.py +14 -0
  112. howler/odm/models/ecs/event.py +140 -0
  113. howler/odm/models/ecs/faas.py +24 -0
  114. howler/odm/models/ecs/file.py +84 -0
  115. howler/odm/models/ecs/geo.py +30 -0
  116. howler/odm/models/ecs/group.py +18 -0
  117. howler/odm/models/ecs/hash.py +16 -0
  118. howler/odm/models/ecs/host.py +17 -0
  119. howler/odm/models/ecs/http.py +37 -0
  120. howler/odm/models/ecs/ingress.py +12 -0
  121. howler/odm/models/ecs/interface.py +21 -0
  122. howler/odm/models/ecs/network.py +30 -0
  123. howler/odm/models/ecs/observer.py +45 -0
  124. howler/odm/models/ecs/organization.py +12 -0
  125. howler/odm/models/ecs/os.py +21 -0
  126. howler/odm/models/ecs/pe.py +17 -0
  127. howler/odm/models/ecs/process.py +216 -0
  128. howler/odm/models/ecs/registry.py +26 -0
  129. howler/odm/models/ecs/related.py +45 -0
  130. howler/odm/models/ecs/rule.py +51 -0
  131. howler/odm/models/ecs/server.py +24 -0
  132. howler/odm/models/ecs/threat.py +247 -0
  133. howler/odm/models/ecs/tls.py +58 -0
  134. howler/odm/models/ecs/url.py +51 -0
  135. howler/odm/models/ecs/user.py +57 -0
  136. howler/odm/models/ecs/user_agent.py +20 -0
  137. howler/odm/models/ecs/vulnerability.py +41 -0
  138. howler/odm/models/gcp.py +16 -0
  139. howler/odm/models/hit.py +356 -0
  140. howler/odm/models/howler_data.py +328 -0
  141. howler/odm/models/lead.py +24 -0
  142. howler/odm/models/localized_label.py +13 -0
  143. howler/odm/models/overview.py +16 -0
  144. howler/odm/models/pivot.py +40 -0
  145. howler/odm/models/template.py +24 -0
  146. howler/odm/models/user.py +83 -0
  147. howler/odm/models/view.py +34 -0
  148. howler/odm/random_data.py +888 -0
  149. howler/odm/randomizer.py +609 -0
  150. howler/patched.py +5 -0
  151. howler/plugins/__init__.py +25 -0
  152. howler/plugins/config.py +123 -0
  153. howler/remote/__init__.py +0 -0
  154. howler/remote/datatypes/README.md +355 -0
  155. howler/remote/datatypes/__init__.py +98 -0
  156. howler/remote/datatypes/counters.py +63 -0
  157. howler/remote/datatypes/events.py +66 -0
  158. howler/remote/datatypes/hash.py +206 -0
  159. howler/remote/datatypes/lock.py +42 -0
  160. howler/remote/datatypes/queues/__init__.py +0 -0
  161. howler/remote/datatypes/queues/comms.py +59 -0
  162. howler/remote/datatypes/queues/multi.py +32 -0
  163. howler/remote/datatypes/queues/named.py +93 -0
  164. howler/remote/datatypes/queues/priority.py +215 -0
  165. howler/remote/datatypes/set.py +118 -0
  166. howler/remote/datatypes/user_quota_tracker.py +54 -0
  167. howler/security/__init__.py +253 -0
  168. howler/security/socket.py +108 -0
  169. howler/security/utils.py +185 -0
  170. howler/services/__init__.py +0 -0
  171. howler/services/action_service.py +111 -0
  172. howler/services/analytic_service.py +128 -0
  173. howler/services/auth_service.py +323 -0
  174. howler/services/config_service.py +128 -0
  175. howler/services/dossier_service.py +252 -0
  176. howler/services/event_service.py +93 -0
  177. howler/services/hit_service.py +893 -0
  178. howler/services/jwt_service.py +158 -0
  179. howler/services/lucene_service.py +286 -0
  180. howler/services/notebook_service.py +119 -0
  181. howler/services/overview_service.py +44 -0
  182. howler/services/template_service.py +45 -0
  183. howler/services/user_service.py +331 -0
  184. howler/utils/__init__.py +0 -0
  185. howler/utils/annotations.py +28 -0
  186. howler/utils/chunk.py +38 -0
  187. howler/utils/dict_utils.py +200 -0
  188. howler/utils/isotime.py +17 -0
  189. howler/utils/list_utils.py +11 -0
  190. howler/utils/lucene.py +77 -0
  191. howler/utils/path.py +27 -0
  192. howler/utils/socket_utils.py +61 -0
  193. howler/utils/str_utils.py +256 -0
  194. howler/utils/uid.py +47 -0
  195. howler_api-3.0.0.dev374.dist-info/METADATA +71 -0
  196. howler_api-3.0.0.dev374.dist-info/RECORD +198 -0
  197. howler_api-3.0.0.dev374.dist-info/WHEEL +4 -0
  198. howler_api-3.0.0.dev374.dist-info/entry_points.txt +8 -0
@@ -0,0 +1,149 @@
1
+ # mypy: ignore-errors
2
+ from typing import Optional
3
+
4
+ from howler import odm
5
+ from howler.odm.models.ecs.autonomous_system import AS
6
+ from howler.odm.models.ecs.geo import Geo
7
+ from howler.odm.models.ecs.user import User
8
+
9
+
10
+ @odm.model(
11
+ index=True,
12
+ store=True,
13
+ description="Translated NAT sessions (e.g. internal client to internet).",
14
+ )
15
+ class Nat(odm.Model):
16
+ ip = odm.Optional(odm.IP(description="Translated IP of source based NAT sessions."))
17
+ port = odm.Optional(odm.Integer(description="Translated port of source based NAT sessions."))
18
+
19
+
20
+ @odm.model(
21
+ index=True,
22
+ store=True,
23
+ description="A client is defined as the initiator of a network connection "
24
+ "for events regarding sessions, connections, or bidirectional flow records.",
25
+ )
26
+ class OriginalClient(odm.Model):
27
+ address: Optional[str] = odm.Optional(
28
+ odm.Keyword(
29
+ description=(
30
+ "The original client in a session that has changed clients. Some event client addresses "
31
+ "are defined ambiguously. The event will sometimes list an IP, a domain or a unix socket. You should"
32
+ " always store the raw address in the .address field."
33
+ )
34
+ )
35
+ )
36
+ autonomous_systems: AS = odm.Optional(
37
+ odm.Compound(
38
+ AS,
39
+ description=(
40
+ "The original client in a session that has changed clients. "
41
+ "Collection of connected Internal Protocol routing prefixes"
42
+ ),
43
+ )
44
+ )
45
+ bytes: Optional[int] = odm.Optional(
46
+ odm.Integer(
47
+ description=(
48
+ "The original client in a session that has changed clients. "
49
+ "Bytes sent from the client to the server."
50
+ )
51
+ )
52
+ )
53
+ domain: Optional[str] = odm.Optional(
54
+ odm.Domain(
55
+ description=(
56
+ "The original client in a session that has changed clients. " "The domain name of the client system."
57
+ )
58
+ )
59
+ )
60
+ geo: Geo = odm.Optional(
61
+ odm.Compound(
62
+ Geo,
63
+ description=(
64
+ "The original client in a session that has changed clients. Geo fields can carry "
65
+ "data about a specific location related to an event."
66
+ ),
67
+ )
68
+ )
69
+ ip: Optional[str] = odm.Optional(
70
+ odm.IP(
71
+ description=(
72
+ "The original client in a session that has changed clients. IP address of the " "client (IPv4 or IPv6)."
73
+ )
74
+ )
75
+ )
76
+ mac: Optional[str] = odm.Optional(
77
+ odm.MAC(description=("The original client in a session that has changed clients. MAC address of the client."))
78
+ )
79
+ nat: Nat = odm.Optional(
80
+ odm.Compound(
81
+ Nat,
82
+ description=(
83
+ "The original client in a session that has changed clients. Translated NAT sessions (e.g. "
84
+ "internal client to internet)."
85
+ ),
86
+ )
87
+ )
88
+ packets: Optional[int] = odm.Optional(
89
+ odm.Integer(
90
+ description=(
91
+ "The original client in a session that has changed clients. Packets sent from the "
92
+ "destination to the source."
93
+ )
94
+ )
95
+ )
96
+ port: Optional[int] = odm.Optional(
97
+ odm.Integer(description="The original client in a session that has changed clients. Port of the client.")
98
+ )
99
+
100
+
101
+ @odm.model(
102
+ index=True,
103
+ store=True,
104
+ description="A client is defined as the initiator of a network connection "
105
+ "for events regarding sessions, connections, or bidirectional flow records.",
106
+ )
107
+ class Client(odm.Model):
108
+ address: Optional[str] = odm.Optional(
109
+ odm.Keyword(
110
+ description="Some event client addresses are defined ambiguously. The event will sometimes list an IP, "
111
+ "a domain or a unix socket. You should always store the raw address in the .address field."
112
+ )
113
+ )
114
+ autonomous_systems: AS = odm.Optional(
115
+ odm.Compound(
116
+ AS,
117
+ description="Collection of connected Internal Protocol routing prefixes",
118
+ )
119
+ )
120
+ bytes: Optional[int] = odm.Optional(odm.Long(description="Bytes sent from the client to the server."))
121
+ domain: Optional[str] = odm.Optional(odm.Keyword(description="The domain name of the client system."))
122
+ geo: Geo = odm.Optional(
123
+ odm.Compound(
124
+ Geo,
125
+ description="Geo fields can carry data about a specific location related to an event.",
126
+ )
127
+ )
128
+ ip: Optional[str] = odm.Optional(odm.IP(description="IP address of the client (IPv4 or IPv6)."))
129
+ mac: Optional[str] = odm.Optional(odm.MAC(description="MAC address of the client."))
130
+ nat: Nat = odm.Optional(
131
+ odm.Compound(
132
+ Nat,
133
+ description="Translated NAT sessions (e.g. internal client to internet).",
134
+ )
135
+ )
136
+ packets: Optional[int] = odm.Optional(odm.Integer(description="Packets sent from the destination to the source."))
137
+ port: Optional[int] = odm.Optional(odm.Integer(description="Port of the client."))
138
+ user: User = odm.Optional(
139
+ odm.Compound(
140
+ User,
141
+ description="The user fields describe information about the user that is relevant to the event.",
142
+ )
143
+ )
144
+ original: OriginalClient = odm.Optional(
145
+ odm.Compound(
146
+ OriginalClient,
147
+ description="Original Client Data.",
148
+ )
149
+ )
@@ -0,0 +1,141 @@
1
+ from typing import Optional
2
+
3
+ from howler import odm
4
+
5
+
6
+ @odm.model(index=True, store=True, description="Cloud account information.")
7
+ class Account(odm.Model):
8
+ id: Optional[str] = odm.Optional(
9
+ odm.Keyword(
10
+ description="The cloud account or organization id used to identify different entities in a "
11
+ "multi-tenant environment.",
12
+ deprecated=True,
13
+ deprecated_description=(
14
+ "Instead of using this more general field, use a platform-specific field. "
15
+ "For more information, see [Disambiguated Cloud Ontology]"
16
+ "(https://confluence.devtools.cse-cst.gc.ca/display/DASI2/Disambiguated+Cloud+Ontology)"
17
+ ),
18
+ ),
19
+ )
20
+ name: Optional[str] = odm.Optional(
21
+ odm.Keyword(
22
+ description="The cloud account name or alias used to identify different entities in a "
23
+ "multi-tenant environment.",
24
+ deprecated=True,
25
+ deprecated_description=(
26
+ "Instead of using this more general field, use a platform-specific field. "
27
+ "For more information, see [Disambiguated Cloud Ontology]"
28
+ "(https://confluence.devtools.cse-cst.gc.ca/display/DASI2/Disambiguated+Cloud+Ontology)"
29
+ ),
30
+ ),
31
+ )
32
+
33
+
34
+ @odm.model(index=True, store=True, description="Instance information.")
35
+ class Instance(odm.Model):
36
+ id = odm.Optional(odm.Keyword(description="Instance ID of the host machine."))
37
+ name = odm.Optional(odm.Keyword(description="Instance name of the host machine."))
38
+
39
+
40
+ @odm.model(index=True, store=True, description="Project information.")
41
+ class Project(odm.Model):
42
+ id = odm.Optional(
43
+ odm.Keyword(
44
+ description="The cloud project identifier.",
45
+ deprecated=True,
46
+ deprecated_description=(
47
+ "Instead of using this more general field, use a platform-specific field. "
48
+ "For more information, see [Disambiguated Cloud Ontology]"
49
+ "(https://confluence.devtools.cse-cst.gc.ca/display/DASI2/Disambiguated+Cloud+Ontology)"
50
+ ),
51
+ )
52
+ )
53
+ name = odm.Optional(
54
+ odm.Keyword(
55
+ description="The cloud project name.",
56
+ deprecated=True,
57
+ deprecated_description=(
58
+ "Instead of using this more general field, use a platform-specific field. "
59
+ "For more information, see [Disambiguated Cloud Ontology]"
60
+ "(https://confluence.devtools.cse-cst.gc.ca/display/DASI2/Disambiguated+Cloud+Ontology)"
61
+ ),
62
+ )
63
+ )
64
+
65
+
66
+ @odm.model(index=True, store=True, description="Machine information.")
67
+ class Machine(odm.Model):
68
+ type = odm.Optional(odm.Keyword(description="Machine type of the host machine."))
69
+
70
+
71
+ @odm.model(index=True, store=True, description="Service information.")
72
+ class Service(odm.Model):
73
+ name = odm.Optional(
74
+ odm.Keyword(
75
+ description="The cloud service name is intended to distinguish services running on different platforms "
76
+ "within a provider, eg AWS EC2 vs Lambda, GCP GCE vs App Engine, Azure VM vs App Server."
77
+ )
78
+ )
79
+
80
+
81
+ @odm.model(
82
+ index=True,
83
+ store=True,
84
+ description="Fields related to the cloud or infrastructure the events are coming from.",
85
+ )
86
+ class Cloud(odm.Model):
87
+ account = odm.Optional(
88
+ odm.Compound(
89
+ Account,
90
+ description="Cloud account information.",
91
+ deprecated=True,
92
+ deprecated_description=(
93
+ "Instead of using this more general field, use a platform-specific field. "
94
+ "For more information, see [Disambiguated Cloud Ontology]"
95
+ "(https://confluence.devtools.cse-cst.gc.ca/display/DASI2/Disambiguated+Cloud+Ontology)"
96
+ ),
97
+ )
98
+ )
99
+ availability_zone = odm.Optional(
100
+ odm.Keyword(
101
+ description="Availability zone in which this host, resource, or service is located.",
102
+ deprecated=True,
103
+ deprecated_description=(
104
+ "Instead of using this more general field, use a platform-specific field. "
105
+ "For more information, see [Disambiguated Cloud Ontology]"
106
+ "(https://confluence.devtools.cse-cst.gc.ca/display/DASI2/Disambiguated+Cloud+Ontology)"
107
+ ),
108
+ )
109
+ )
110
+ instance = odm.Optional(odm.Compound(Instance, description="Instance information."))
111
+ machine = odm.Optional(odm.Compound(Machine, description="Machine information."))
112
+ project = odm.Optional(
113
+ odm.Compound(
114
+ Project,
115
+ description="Project information.",
116
+ deprecated=True,
117
+ deprecated_description=(
118
+ "Instead of using this more general field, use a platform-specific field. "
119
+ "For more information, see [Disambiguated Cloud Ontology]"
120
+ "(https://confluence.devtools.cse-cst.gc.ca/display/DASI2/Disambiguated+Cloud+Ontology)"
121
+ ),
122
+ )
123
+ )
124
+ provider = odm.Optional(
125
+ odm.Keyword(description="Name of the cloud provider. Example values are aws, azure, gcp, or digitalocean.")
126
+ )
127
+ region = odm.Optional(odm.Keyword(description="Region in which this host, resource, or service is located."))
128
+ service = odm.Optional(odm.Compound(Service, description="Service information."))
129
+
130
+ # Extra fields not defined in ECS but added for outline purposes
131
+ tenant_id = odm.Optional(
132
+ odm.Keyword(
133
+ description="The tenant id associated with this alert.",
134
+ deprecated=True,
135
+ deprecated_description=(
136
+ "Instead of using this more general field, use a platform-specific field. "
137
+ "For more information, see [Disambiguated Cloud Ontology]"
138
+ "(https://confluence.devtools.cse-cst.gc.ca/display/DASI2/Disambiguated+Cloud+Ontology)"
139
+ ),
140
+ )
141
+ )
@@ -0,0 +1,27 @@
1
+ from howler import odm
2
+
3
+
4
+ @odm.model(
5
+ index=True,
6
+ store=True,
7
+ description="These fields contain information about binary code signatures.",
8
+ )
9
+ class CodeSignature(odm.Model):
10
+ digest_algorithm = odm.Optional(
11
+ odm.Enum(
12
+ values=["md5", "sha1", "sha256", "sha384", "sha512"],
13
+ description="The hashing algorithm used to sign the process.",
14
+ )
15
+ )
16
+ exists = odm.Optional(odm.Boolean(description="Boolean to capture if a signature is present."))
17
+ signing_id = odm.Optional(odm.Keyword(description="The identifier used to sign the process."))
18
+ status = odm.Optional(odm.Keyword(description="Additional information about the certificate status."))
19
+ subject_name = odm.Optional(odm.Keyword(description="Subject name of the code signer."))
20
+ team_id = odm.Optional(odm.Keyword(description="The team identifier used to sign the process."))
21
+ timestamp = odm.Optional(odm.Date(description="Date and time when the code signature was generated and signed."))
22
+ trusted = odm.Optional(odm.Boolean(description="Stores the trust status of the certificate chain."))
23
+ valid = odm.Optional(
24
+ odm.Boolean(
25
+ description="Boolean to capture if the digital signature" " is verified against the binary content."
26
+ )
27
+ )
@@ -0,0 +1,32 @@
1
+ from typing import Optional
2
+
3
+ from howler import odm
4
+
5
+
6
+ @odm.model(index=True, store=True, description="Container hashes information.")
7
+ class Hash(odm.Model):
8
+ all: list[str] = odm.List(
9
+ odm.Keyword(),
10
+ description="An array of digests of the image the container was built on.",
11
+ default=[],
12
+ )
13
+
14
+
15
+ @odm.model(index=True, store=True, description="Information about the container Image.")
16
+ class Image(odm.Model):
17
+ hash: Optional[Hash] = odm.Optional(odm.Compound(Hash, description="Container hashes information."))
18
+ name: Optional[str] = odm.Optional(odm.Keyword(description="Name of the image the container was built on."))
19
+ tag: list[str] = odm.List(odm.Keyword(), description="Container image tags.", default=[])
20
+
21
+
22
+ @odm.model(
23
+ index=True,
24
+ store=True,
25
+ description="Fields related to the cloud or infrastructure the events are coming from.",
26
+ )
27
+ class Container(odm.Model):
28
+ id = odm.Optional(odm.Keyword(description="Unique container id."))
29
+ image = odm.Optional(odm.Compound(Image, description="Cloud account information."))
30
+ labels = odm.Optional(odm.Mapping(odm.Keyword(), description="Image labels."))
31
+ name = odm.Optional(odm.Keyword(description="Container name."))
32
+ runtime = odm.Optional(odm.Keyword(description="Runtime managing this container."))
@@ -0,0 +1,62 @@
1
+ from howler import odm
2
+
3
+
4
+ @odm.model(index=True, store=True, description="An answer section returned by the server.")
5
+ class DNSAnswer(odm.Model):
6
+ class_ = odm.Optional(odm.Keyword(description="The class of DNS data contained in this resource record."))
7
+ data = odm.Optional(odm.Keyword(description="The data describing the resource."))
8
+ name = odm.Optional(odm.Keyword(description="The domain name to which this resource record pertains."))
9
+ ttl = odm.Optional(
10
+ odm.Integer(
11
+ description="The time interval in seconds that this "
12
+ "resource record may be cached before it should be discarded."
13
+ )
14
+ )
15
+ type = odm.Optional(odm.Keyword(description="The type of data contained in this resource record."))
16
+
17
+
18
+ @odm.model(
19
+ index=True,
20
+ store=True,
21
+ description="An object encapsulating the question asked to the server.",
22
+ )
23
+ class DNSQuestion(odm.Model):
24
+ class_ = odm.Optional(odm.Keyword(description="The class of records being queried."))
25
+ name = odm.Optional(odm.Keyword(description="The name being queried."))
26
+ registered_domain = odm.Optional(
27
+ odm.Domain(description="The highest registered domain, stripped of the subdomain.")
28
+ )
29
+ subdomain = odm.Optional(odm.Keyword(description="The subdomain is all of the labels under the registered_domain."))
30
+ top_level_domain = odm.Optional(
31
+ odm.Keyword(
32
+ description="The effective top level domain (eTLD), also known as the "
33
+ "domain suffix, is the last part of the domain name."
34
+ )
35
+ )
36
+ type = odm.Optional(odm.Keyword(description="The type of record being queried."))
37
+
38
+
39
+ @odm.model(index=True, store=True, description="Fields describing DNS queries and answers.")
40
+ class DNS(odm.Model):
41
+ answers = odm.Optional(
42
+ odm.List(
43
+ odm.Compound(DNSAnswer),
44
+ description="An array containing an object for each answer section returned by the server.",
45
+ )
46
+ )
47
+ header_flags = odm.Optional(odm.List(odm.Keyword(), description="Array of 2 letter DNS header flags."))
48
+ id = odm.Optional(
49
+ odm.Keyword(description="The DNS packet identifier assigned by the program that generated the query.")
50
+ )
51
+ op_code = odm.Optional(
52
+ odm.Keyword(description="The DNS operation code that specifies the kind of query in the message.")
53
+ )
54
+ question = odm.Optional(
55
+ odm.Compound(
56
+ DNSQuestion,
57
+ description="An object encapsulating the question asked to the server.",
58
+ )
59
+ )
60
+ resolved_ip = odm.Optional(odm.List(odm.IP(), description="Array containing all IPs seen in answers.data."))
61
+ response_code = odm.Optional(odm.Keyword(description="The DNS response code."))
62
+ type = odm.Optional(odm.Keyword(description="The type of DNS event captured, query or answer."))
@@ -0,0 +1,10 @@
1
+ from howler import odm
2
+
3
+
4
+ @odm.model(
5
+ index=True,
6
+ store=True,
7
+ description="Holds information like interface number, name, vlan, and zone to classify egress traffic",
8
+ )
9
+ class Egress(odm.Model):
10
+ zone = odm.Optional(odm.Keyword(description="Network zone of outbound traffic"))
@@ -0,0 +1,74 @@
1
+ from howler import odm
2
+
3
+
4
+ @odm.model(index=True, store=True, description="Definition of an ELF file segment.")
5
+ class Segment(odm.Model):
6
+ sections = odm.Optional(odm.Keyword(description="ELF object segment sections."))
7
+ type = odm.Optional(odm.Keyword(description="ELF object segment type."))
8
+
9
+
10
+ @odm.model(index=True, store=True, description="Definition of an ELF file section.")
11
+ class Section(odm.Model):
12
+ chi2 = odm.Optional(odm.Integer(description="Chi-square probability distribution of the section."))
13
+ entropy = odm.Optional(odm.Integer(description="Shannon entropy calculation from the section."))
14
+ flags = odm.Optional(odm.Keyword(description="ELF Section List flags."))
15
+ name = odm.Optional(odm.Keyword(description="ELF Section List name."))
16
+ physical_offset = odm.Optional(odm.Keyword(description="ELF Section List offset."))
17
+ physical_size = odm.Optional(odm.Integer(description="ELF Section List physical size."))
18
+ type = odm.Optional(odm.Keyword(description="ELF Section List type."))
19
+ virtual_address = odm.Optional(odm.Integer(description="ELF Section List virtual address."))
20
+ virtual_size = odm.Optional(odm.Integer(description="ELF Section List virtual size."))
21
+
22
+
23
+ @odm.model(index=True, store=True, description="Header information about the ELF file.")
24
+ class Header(odm.Model):
25
+ abi_version = odm.Optional(odm.Keyword(description="Version of the ELF Application Binary Interface (ABI)."))
26
+ class_ = odm.Optional(odm.Keyword(description="Header class of the ELF file."))
27
+ data = odm.Optional(odm.Keyword(description="Data table of the ELF header."))
28
+ entrypoint = odm.Optional(odm.Integer(description="Header entrypoint of the ELF file."))
29
+ object_version = odm.Optional(odm.Keyword(description="'0x1' for original ELF files."))
30
+ os_abi = odm.Optional(odm.Keyword(description="Application Binary Interface (ABI) of the Linux OS."))
31
+ type = odm.Optional(odm.Keyword(description="Header type of the ELF file."))
32
+ version = odm.Optional(odm.Keyword(description="Version of the ELF header."))
33
+
34
+
35
+ @odm.model(
36
+ index=True,
37
+ store=True,
38
+ description="These fields contain Linux Executable Linkable Format (ELF) metadata.",
39
+ )
40
+ class ELF(odm.Model):
41
+ architecture = odm.Optional(odm.Keyword(description="Machine architecture of the ELF file."))
42
+ byte_order = odm.Optional(odm.Keyword(description="Byte sequence of ELF file."))
43
+ cpu_type = odm.Optional(odm.Keyword(description="CPU type of the ELF file."))
44
+ creation_date = odm.Optional(odm.Keyword(description="Extracted when possible from the file’s metadata."))
45
+ exports = odm.List(
46
+ odm.Keyword(),
47
+ default=[],
48
+ description="List of exported element names and types.",
49
+ )
50
+ header = odm.Optional(odm.Compound(Header, description="Header information about the ELF file."))
51
+ imports = odm.Optional(odm.List(odm.Keyword(), description="List of imported element names and types."))
52
+ sections = odm.Optional(
53
+ odm.List(
54
+ odm.Compound(
55
+ Section,
56
+ description="An array containing an object for each section of the ELF file.",
57
+ )
58
+ )
59
+ )
60
+ segments = odm.Optional(
61
+ odm.List(
62
+ odm.Compound(
63
+ Section,
64
+ description="An array containing an object for each segment of the ELF file.",
65
+ )
66
+ )
67
+ )
68
+ shared_libraries = odm.Optional(
69
+ odm.List(
70
+ odm.Keyword(),
71
+ description="List of shared libraries used by this ELF object.",
72
+ )
73
+ )
74
+ telfhash = odm.Optional(odm.Keyword(description="telfhash symbol hash for ELF file."))
@@ -0,0 +1,122 @@
1
+ from howler import odm
2
+ from howler.odm.models.ecs.hash import Hashes
3
+
4
+
5
+ @odm.model(index=True, store=True, description="The email Address")
6
+ class Address(odm.Model):
7
+ address = odm.Email(description="The email address.")
8
+
9
+
10
+ @odm.model(index=True, store=True, description="Information about the file sent.")
11
+ class File(odm.Model):
12
+ extension = odm.Optional(odm.Keyword(description="Attachment file extension, excluding the leading dot."))
13
+ hash = odm.Optional(odm.Compound(Hashes, description="Hashes, usually file hashes."))
14
+ mime_type = odm.Optional(odm.Keyword(description="The MIME media type of the attachment."))
15
+ name = odm.Optional(odm.Keyword(description="Name of the attachment file including the file extension."))
16
+ size = odm.Optional(odm.Integer(description="Attachment file size in bytes."))
17
+
18
+
19
+ @odm.model(
20
+ index=True,
21
+ store=True,
22
+ description="An attachment file sent along with an email message.",
23
+ )
24
+ class Attachment(odm.Model):
25
+ file = odm.Optional(odm.Compound(File, description="Information about the file sent."))
26
+
27
+
28
+ @odm.model(
29
+ index=True,
30
+ store=True,
31
+ description="Metadata about the parent email.",
32
+ )
33
+ class ParentEmail(odm.Model):
34
+ bcc = odm.Optional(odm.Compound(Address, description="The email address of BCC recipient."))
35
+ cc = odm.Optional(odm.Compound(Address, description="The email address of CC recipient."))
36
+ from_ = odm.Optional(
37
+ odm.Compound(
38
+ Address,
39
+ description="The email address of the sender, typically " "from the RFC 5322 From: header field.",
40
+ )
41
+ )
42
+ message_id = odm.Optional(
43
+ odm.Keyword(
44
+ description="Identifier from the RFC 5322 Message-ID: email header "
45
+ "that refers to a particular email message."
46
+ )
47
+ )
48
+ origination_timestamp = odm.Optional(odm.Date(description="The date and time the email message was composed."))
49
+ subject = odm.Optional(odm.Keyword(description="A brief summary of the topic of the message."))
50
+ to = odm.Optional(odm.Compound(Address, description="The email address of recipient."))
51
+ source = odm.Optional(odm.IP(description="The ip the email originated from."))
52
+ destination = odm.Optional(odm.IP(description="The ip the email was sent to."))
53
+
54
+
55
+ @odm.model(
56
+ index=True,
57
+ store=True,
58
+ description="Event details relating to an email transaction.",
59
+ )
60
+ class Email(odm.Model):
61
+ attachments = odm.Optional(
62
+ odm.List(
63
+ odm.Compound(
64
+ Attachment,
65
+ description="A list of objects describing the attachment files sent along with an email message.",
66
+ )
67
+ )
68
+ )
69
+ bcc = odm.Optional(odm.Compound(Address, description="The email address of BCC recipient."))
70
+ cc = odm.Optional(odm.Compound(Address, description="The email address of CC recipient."))
71
+ content_type = odm.Optional(odm.Keyword(description="Information about how the message is to be displayed."))
72
+ delivery_timestamp = odm.Optional(
73
+ odm.Date(description="The date and time when the email message " "was received by the service or client.")
74
+ )
75
+ direction = odm.Optional(
76
+ odm.Keyword(description="The direction of the message based on the " "sending and receiving domains.")
77
+ )
78
+ from_ = odm.Optional(
79
+ odm.Compound(
80
+ Address,
81
+ description="The email address of the sender, typically " "from the RFC 5322 From: header field.",
82
+ )
83
+ )
84
+ local_id = odm.Optional(
85
+ odm.Keyword(description="Unique identifier given to the email by the source " "that created the event.")
86
+ )
87
+ message_id = odm.Optional(
88
+ odm.Keyword(
89
+ description="Identifier from the RFC 5322 Message-ID: email header "
90
+ "that refers to a particular email message."
91
+ )
92
+ )
93
+ origination_timestamp = odm.Optional(odm.Date(description="The date and time the email message was composed."))
94
+ reply_to = odm.Optional(
95
+ odm.Compound(
96
+ Address,
97
+ description="The address that replies should be delivered to "
98
+ "based on the value in the RFC 5322 Reply-To: header.",
99
+ )
100
+ )
101
+ sender = odm.Optional(
102
+ odm.Compound(
103
+ Address,
104
+ description="Per RFC 5322, specifies the address responsible for "
105
+ "the actual transmission of the message.",
106
+ )
107
+ )
108
+ subject = odm.Optional(odm.Keyword(description="A brief summary of the topic of the message."))
109
+ to = odm.Optional(odm.Compound(Address, description="The email address of recipient."))
110
+ x_mailer = odm.Optional(
111
+ odm.Keyword(
112
+ description="The name of the application that was used to draft " "and send the original email message."
113
+ )
114
+ )
115
+
116
+ # Extra fields not defined in ECS but added for outline purposes
117
+ parent = odm.Optional(
118
+ odm.Compound(
119
+ ParentEmail,
120
+ description="Metadata about the parent email.",
121
+ )
122
+ )
@@ -0,0 +1,14 @@
1
+ from howler import odm
2
+
3
+
4
+ @odm.model(
5
+ index=True,
6
+ store=True,
7
+ description=(
8
+ "These fields can represent errors of any kind. Use them for errors that happen while "
9
+ "fetching events or in cases where the event itself contains an error."
10
+ ),
11
+ )
12
+ class Error(odm.Model):
13
+ code = odm.Optional(odm.Keyword(description="Identifier specific to the error."))
14
+ message = odm.Optional(odm.Keyword(description="Error message provided."))