Skip to content

Commit 015498e

Browse files
authored
Merge pull request elastic#396 from elastic/craig-may-2022
Create super-alerts package
2 parents c367f21 + e495529 commit 015498e

File tree

1 file changed

+220
-0
lines changed

1 file changed

+220
-0
lines changed
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
2+
#transforms to create super-alerts correlated by hostname using a non-linar join and preserving key fields from the original alert set
3+
4+
# Index to use for outputing super-alerts - edit/use as needed
5+
PUT /rule_corr_index_host_name
6+
7+
# All transform stuff from here
8+
POST _scripts/init_script_host_name
9+
{
10+
"script": {
11+
"lang": "painless",
12+
"source": """
13+
14+
state.rule_info = new HashMap();
15+
16+
"""
17+
}
18+
}
19+
20+
#create the map script
21+
POST _scripts/map_script_host_name
22+
{
23+
"script": {
24+
"lang": "painless",
25+
"source": """
26+
27+
Map current_info = new HashMap();
28+
29+
if (doc.containsKey("kibana.alert.rule.name") && doc["kibana.alert.rule.name"].size() != 0) {
30+
current_info.put("rule_names", doc["kibana.alert.rule.name"].value);
31+
}
32+
33+
if (doc.containsKey("host.id") && doc["host.id"].size() != 0) {
34+
current_info.put("host_ids", doc["host.id"].value);
35+
}
36+
37+
if (doc.containsKey("host.name") && doc["host.name"].size() != 0) {
38+
current_info.put("host_names", doc["host.name"].value);
39+
}
40+
41+
if (doc.containsKey("host.os.Ext.variant") && doc["host.os.Ext.variant"].size() != 0) {
42+
current_info.put("host_variants", doc["host.os.Ext.variant"].value);
43+
}
44+
45+
if (doc.containsKey("host.os.family") && doc["host.os.family"].size() != 0) {
46+
current_info.put("host_families", doc["host.os.family"].value);
47+
}
48+
49+
if (doc.containsKey("host.os.full") && doc["host.os.full"].size() != 0) {
50+
current_info.put("host_os_full", doc["host.os.full"].value);
51+
}
52+
53+
if (doc.containsKey("kibana.alert.rule.tags") && doc["kibana.alert.rule.tags"].size() != 0) {
54+
current_info.put("rule_tags", doc["kibana.alert.rule.tags"].value);
55+
}
56+
57+
if (doc.containsKey("kibana.alert.original_event.action") && doc["kibana.alert.original_event.action"].size() != 0) {
58+
current_info.put("original_event_actions", doc["kibana.alert.original_event.action"].value);
59+
}
60+
61+
if (doc.containsKey("kibana.alert.original_event.category") && doc["kibana.alert.original_event.category"].size() != 0) {
62+
current_info.put("original_event_categories", doc["kibana.alert.original_event.category"].value);
63+
}
64+
65+
if (doc.containsKey("kibana.alert.original_event.outcome") && doc["kibana.alert.original_event.outcome"].size() != 0) {
66+
current_info.put("original_event_outcomes", doc["kibana.alert.original_event.outcome"].value);
67+
}
68+
69+
if (doc.containsKey("kibana.alert.rule.threat.tactic.name") && doc["kibana.alert.rule.threat.tactic.name"].size() != 0) {
70+
current_info.put("rule_threat_tactic_names", doc["kibana.alert.rule.threat.tactic.name"].value);
71+
}
72+
73+
if (doc.containsKey("kibana.alert.original_event.type") && doc["kibana.alert.original_event.type"].size() != 0) {
74+
current_info.put("original_event_types", doc["kibana.alert.original_event.type"].value);
75+
}
76+
77+
if (doc.containsKey("kibana.alert.rule.threat.technique.name") && doc["kibana.alert.rule.threat.technique.name"].size() != 0) {
78+
current_info.put("rule_threat_technique_names", doc["kibana.alert.rule.threat.technique.name"].value);
79+
}
80+
81+
if (doc.containsKey("kibana.alert.rule.threat.technique.subtechnique.name") && doc["kibana.alert.rule.threat.technique.subtechnique.name"].size() != 0) {
82+
current_info.put("rule_threat_subtechnique_names", doc["kibana.alert.rule.threat.technique.subtechnique.name"].value);
83+
}
84+
85+
if (doc.containsKey("kibana.alert.severity") && doc["kibana.alert.severity"].size() != 0) {
86+
current_info.put("kibana_alert_severities", doc["kibana.alert.severity"].value);
87+
}
88+
89+
if (doc.containsKey("process.name") && doc["process.name"].size() != 0) {
90+
current_info.put("process_names", doc["process.name"].value);
91+
}
92+
93+
if (doc.containsKey("user.name") && doc["user.name"].size() != 0) {
94+
current_info.put("user_names", doc["user.name"].value);
95+
}
96+
97+
if (doc.containsKey("winlog.event_data.User") && doc["winlog.event_data.User"].size() != 0) {
98+
current_info.put("rule_names", doc["winlog.event_data.User"].value);
99+
}
100+
101+
for (key in current_info.keySet()) {
102+
if (state.rule_info.containsKey(key)) {
103+
if (current_info.get(key) != null) {
104+
def updated_info = state.rule_info.get(key);
105+
def current_val = current_info.get(key);
106+
updated_info.add(current_val);
107+
state.rule_info.put(key, updated_info);
108+
}
109+
}
110+
else {
111+
if (current_info.get(key) != null) {
112+
def current_val = current_info.get(key);
113+
def info_list = new HashSet();
114+
info_list.add(current_val);
115+
state.rule_info.put(key, info_list);
116+
}
117+
}
118+
}
119+
120+
121+
122+
"""
123+
}
124+
}
125+
126+
#create the reduce script
127+
POST _scripts/reduce_script_host_name
128+
{
129+
"script": {
130+
"lang": "painless",
131+
"source": """
132+
133+
Map total_rule_info = new HashMap();
134+
135+
for (state in states) {
136+
if (state.rule_info != null) {
137+
for (key in state.rule_info.keySet()) {
138+
if (total_rule_info.containsKey(key)) {
139+
def updated_info = total_rule_info.get(key);
140+
def add_info = state.rule_info.get(key);
141+
updated_info.add(add_info);
142+
total_rule_info.put(key, updated_info);
143+
}
144+
else {
145+
if (state.rule_info.get(key) != null) {
146+
total_rule_info.put(key, state.rule_info.get(key));
147+
}
148+
}
149+
}
150+
}
151+
}
152+
153+
return ["rules": total_rule_info];
154+
155+
"""
156+
}
157+
}
158+
159+
#create the transform
160+
PUT _transform/test_transform_host_name
161+
{
162+
"source": {
163+
"index": [
164+
".siem-signals*"
165+
],
166+
"query": {
167+
"bool": {
168+
"filter": [
169+
{
170+
"range": {
171+
"@timestamp": {
172+
"gte": "now-180d"
173+
}
174+
}
175+
},
176+
{
177+
"match": {
178+
"signal.status": "open"
179+
}
180+
}
181+
]
182+
}
183+
}
184+
},
185+
"dest": {
186+
"index": "rule_corr_index_host_name"
187+
},
188+
"frequency": "1h",
189+
"sync": {
190+
"time": {
191+
"field": "@timestamp",
192+
"delay": "120s"
193+
}
194+
},
195+
"pivot": {
196+
"group_by": {
197+
"host.name": {
198+
"terms": {
199+
"field": "host.name"
200+
}
201+
}
202+
},
203+
"aggregations": {
204+
"@timestamp": {
205+
"max": {
206+
"field": "@timestamp"
207+
}
208+
},
209+
"rule_stats": {
210+
"scripted_metric": {
211+
"params": {},
212+
"init_script": {"id": "init_script_host_name"},
213+
"map_script": {"id": "map_script_host_name"},
214+
"combine_script": "return state",
215+
"reduce_script": {"id": "reduce_script_host_name"}
216+
}
217+
}
218+
}
219+
}
220+
}

0 commit comments

Comments
 (0)