@@ -13,7 +13,7 @@ processors:
1313 field : event.original
1414 target_field : json
1515 - drop :
16- if : ' ctx? .json? .offset != null'
16+ if : ctx.json.offset != null
1717 - set :
1818 field : observer.vendor
1919 value : akamai
@@ -26,9 +26,12 @@ processors:
2626 - UNIX
2727 timezone : UTC
2828 target_field : " @timestamp"
29+ # 500s do not include a timestamp.
30+ if : ctx.json.httpMessage?.start != null
2931 - set :
3032 field : " event.start"
3133 copy_from : " @timestamp"
34+ ignore_empty_value : true
3235 - rename :
3336 field : json.httpMessage.status
3437 target_field : http.response.status_code
@@ -71,11 +74,22 @@ processors:
7174 field : json.httpMessage.path
7275 target_field : url.path
7376 ignore_missing : true
77+ on_failure :
78+ # We see some illegal character, if we can't decode, at least give the data that exists.
79+ - set :
80+ field : url.path
81+ copy_from : json.httpMessage.path
7482 - urldecode :
7583 tag : urldecode_httpMessage_query
7684 field : json.httpMessage.query
7785 target_field : url.query
7886 ignore_missing : true
87+ on_failure :
88+ # Assume a failure is due to the query already being decoded.
89+ - rename :
90+ field : json.httpMessage.query
91+ target_field : url.query
92+ ignore_failure : true
7993 - rename :
8094 field : json.httpMessage.port
8195 target_field : url.port
@@ -89,7 +103,7 @@ processors:
89103 field : json.httpMessage.responseHeaders
90104 ignore_missing : true
91105 - kv :
92- if : ctx.json? .httpMessage?.responseHeaders != ""
106+ if : ctx.json.httpMessage?.responseHeaders != ""
93107 tag : kv_httpMessage_responseHeaders
94108 field : json.httpMessage.responseHeaders
95109 target_field : akamai.siem.response.headers
@@ -101,7 +115,7 @@ processors:
101115 field : json.httpMessage.requestHeaders
102116 ignore_missing : true
103117 - kv :
104- if : ctx.json? .httpMessage?.requestHeaders != ""
118+ if : ctx.json.httpMessage?.requestHeaders != ""
105119 tag : kv_httpMessage_requestHeaders
106120 field : json.httpMessage.requestHeaders
107121 target_field : akamai.siem.request.headers
@@ -112,21 +126,24 @@ processors:
112126 lang : painless
113127 description : This script builds the `url.full` field out of the available `url.*` parts.
114128 source : |
115- def full = "" ;
116- if(ctx.url.scheme != null && ctx.url.scheme != "") {
117- full += ctx.url.scheme+"://";
129+ String full = '' ;
130+ if (ctx.url? .scheme != null && ctx.url.scheme != "") {
131+ full += ctx.url.scheme+"://";
118132 }
119- if(ctx.url.domain != null && ctx.url.domain != "") {
120- full += ctx.url.domain;
133+ if (ctx.url? .domain != null && ctx.url.domain != "") {
134+ full += ctx.url.domain;
121135 }
122- if(ctx.json.httpMessage.path != null && ctx.json.httpMessage.path != "") {
123- full += ctx.json.httpMessage.path;
136+ if (ctx.json.httpMessage? .path != null && ctx.json.httpMessage.path != "") {
137+ full += ctx.json.httpMessage.path;
124138 }
125- if(ctx.json.httpMessage.query != null && ctx.json.httpMessage.query != "") {
126- full += "?"+ctx.json.httpMessage.query;
139+ if (ctx.json.httpMessage? .query != null && ctx.json.httpMessage.query != "") {
140+ full += "?"+ctx.json.httpMessage.query;
127141 }
128- if(full != "") {
129- ctx.url.full = full
142+ if (full != "") {
143+ if (ctx.url == null) {
144+ ctx.url = [:];
145+ }
146+ ctx.url.full = full
130147 }
131148 - dissect :
132149 field : json.httpMessage.protocol
@@ -138,7 +155,7 @@ processors:
138155 - set :
139156 field : network.transport
140157 value : tcp
141- if : ctx? .network?.protocol != null && ctx? .network? .protocol == 'http'
158+ if : ctx.network?.protocol != null && ctx.network.protocol == 'http'
142159 - dissect :
143160 field : json.httpMessage.tls
144161 pattern : " %{tls.version_protocol}v%{tls.version}"
@@ -165,17 +182,17 @@ processors:
165182 field : json.geo.country
166183 target_field : source.geo.country_iso_code
167184 ignore_missing : true
168- if : ctx? .source?.geo?.country_iso_code == null
185+ if : ctx.source?.geo?.country_iso_code == null
169186 - set :
170187 field : source.geo.region_iso_code
171188 value : " {{{json.geo.country}}}-{{{json.geo.regionCode}}}"
172189 ignore_empty_value : true
173- if : ctx? .source?.geo?.region_iso_code == null
190+ if : ctx.source?.geo?.region_iso_code == null
174191 - rename :
175192 field : json.geo.city
176193 target_field : source.geo.city_name
177194 ignore_missing : true
178- if : ctx? .source?.geo?.city_name == null
195+ if : ctx.source?.geo?.city_name == null
179196 - geoip :
180197 database_file : GeoLite2-ASN.mmdb
181198 field : source.ip
@@ -193,7 +210,7 @@ processors:
193210 target_field : source.as.number
194211 type : long
195212 ignore_missing : true
196- if : ctx? .source?.as?.number == null
213+ if : ctx.source?.as?.number == null
197214 - rename :
198215 field : source.as.organization_name
199216 target_field : source.as.organization.name
@@ -209,6 +226,7 @@ processors:
209226 target_field : json.attackData.ruleActions
210227 separator : ' ;'
211228 preserve_trailing : true
229+ ignore_missing : true
212230 - urldecode :
213231 tag : urldecode_attackData_ruleData
214232 field : json.attackData.ruleData
@@ -219,6 +237,7 @@ processors:
219237 target_field : json.attackData.ruleData
220238 separator : ' ;'
221239 preserve_trailing : true
240+ ignore_missing : true
222241 - urldecode :
223242 tag : urldecode_attackData_ruleMessages
224243 field : json.attackData.ruleMessages
@@ -229,6 +248,7 @@ processors:
229248 target_field : json.attackData.ruleMessages
230249 separator : ' ;'
231250 preserve_trailing : true
251+ ignore_missing : true
232252 - urldecode :
233253 tag : urldecode_attackData_ruleSelectors
234254 field : json.attackData.ruleSelectors
@@ -239,6 +259,7 @@ processors:
239259 target_field : json.attackData.ruleSelectors
240260 separator : ' ;'
241261 preserve_trailing : true
262+ ignore_missing : true
242263 - urldecode :
243264 tag : urldecode_attackData_ruleTags
244265 field : json.attackData.ruleTags
@@ -249,6 +270,7 @@ processors:
249270 target_field : json.attackData.ruleTags
250271 separator : ' ;'
251272 preserve_trailing : true
273+ ignore_missing : true
252274 - urldecode :
253275 tag : urldecode_attackData_ruleVersions
254276 field : json.attackData.ruleVersions
@@ -259,6 +281,7 @@ processors:
259281 target_field : json.attackData.ruleVersions
260282 separator : ' ;'
261283 preserve_trailing : true
284+ ignore_missing : true
262285 - urldecode :
263286 tag : urldecode_attackData_rules
264287 field : json.attackData.rules
@@ -269,30 +292,53 @@ processors:
269292 target_field : json.attackData.rules
270293 separator : ' ;'
271294 preserve_trailing : true
295+ ignore_missing : true
272296 - script :
273297 lang : painless
274298 description : Base64 Decode the json.attackData.rule* fields
275299 tag : script_base64_decode_attackData_rule
300+ params :
301+ items :
302+ - rules
303+ - ruleActions
304+ - ruleData
305+ - ruleMessages
306+ - ruleTags
307+ - ruleSelectors
308+ - ruleVersions
309+ if : ctx.json.attackData?.rules instanceof List
276310 source : |
277- ArrayList items = new ArrayList(["rules", "ruleActions", "ruleData", "ruleMessages", "ruleTags", "ruleSelectors", "ruleVersions"]);
278311 ArrayList rules_array = new ArrayList();
279312 ArrayList rule_actions = new ArrayList();
280313 ArrayList rule_tags = new ArrayList();
281314 for (def i = 0; i < ctx.json.attackData.rules.length; i++) {
282- HashMap map = new HashMap();
283- for (def j = 0; j < items.length; j++) {
284- String key = items[j];
285- if (i < ctx.json.attackData[key].length ) {
286- String value = ctx.json.attackData[key][i].replace(" ", "").decodeBase64();
287- map.put(key, value);
288- if (key == "ruleTags") {
289- rule_tags.add(value.toLowerCase());
290- } else if (key == "ruleActions") {
291- rule_actions.add(value.toLowerCase());
292- }
315+ HashMap map = new HashMap();
316+ for (String key: params.items) {
317+ if (i < ctx.json.attackData[key].length) {
318+ String data = ctx.json.attackData[key][i].replace(" ", "");
319+ try {
320+ String value = data.decodeBase64();
321+ map.put(key, value);
322+ if (key == "ruleTags") {
323+ rule_tags.add(value.toLowerCase());
324+ } else if (key == "ruleActions") {
325+ rule_actions.add(value.toLowerCase());
326+ }
327+ }
328+ catch (Exception e) {
329+ if (data.length() > 10) {
330+ data = data.substring(0,10)+"..."
331+ }
332+ String error = e.toString();
333+ if (error.startsWith("java.lang.IllegalArgumentException: ")) {
334+ error = error.substring("java.lang.IllegalArgumentException: ".length());
293335 }
336+ String warning = "failed to decode base64 data: " + error + ": " + data;
337+ map.put(key, warning);
338+ }
294339 }
295- rules_array.add(map);
340+ }
341+ rules_array.add(map);
296342 }
297343 ctx.akamai.siem.rules = rules_array;
298344 ctx._rule_actions = rule_actions;
@@ -393,36 +439,64 @@ processors:
393439 field : json.userRiskData.score
394440 target_field : akamai.siem.user_risk.score
395441 type : long
442+ if : ctx.json.userRiskData?.score != null && ctx.json.userRiskData.score != ''
396443 ignore_missing : true
397444 - convert :
398445 field : json.userRiskData.allow
399446 target_field : akamai.siem.user_risk.allow
400447 type : long
401448 ignore_missing : true
402449 - kv :
403- if : ctx.json? .userRiskData?.risk != ""
450+ if : ctx.json.userRiskData?.risk != ""
404451 tag : kv_userRiskData_risk
405452 field : json.userRiskData.risk
406453 target_field : akamai.siem.user_risk.risk
407454 field_split : ' \|'
408455 value_split : ' :'
409456 ignore_missing : true
410457 - kv :
411- if : ctx.json? .userRiskData?.trust != ""
458+ if : ctx.json.userRiskData?.trust != ""
412459 tag : kv_userRiskData_trust
413460 field : json.userRiskData.trust
414461 target_field : akamai.siem.user_risk.trust
415462 field_split : ' \|'
416463 value_split : ' :'
417464 ignore_missing : true
418- - kv :
419- if : ctx.json?.userRiskData?.general != ""
420- tag : kv_userRiskData_general
421- field : json.userRiskData.general
422- target_field : akamai.siem.user_risk.general
423- field_split : ' \|'
424- value_split : ' :'
425- ignore_missing : true
465+ - script :
466+ description : Process key-value pairs, preserving keys without values.
467+ lang : painless
468+ tag : script_userRiskData_general
469+ if : ctx.json.userRiskData?.general instanceof String && ctx.json.userRiskData.general != ""
470+ source : |
471+ String text = ctx.json.userRiskData.general.trim();
472+ if (text != "") {
473+ def m = new HashMap();
474+ for (String f: /\|/.split(text)) {
475+ if (f == "") {
476+ continue;
477+ }
478+ int idx = f.indexOf(':');
479+ if (idx == -1) {
480+ m.put(f, "-"); // Include a non-empty string to prevent the field being removed.
481+ continue;
482+ }
483+ String k = f.substring(0, idx);
484+ String v = f.substring(idx+1);
485+ m.put(k, v);
486+ }
487+ if (m.size() > 0) {
488+ if (ctx.akamai == null) {
489+ ctx.akamai = new HashMap();
490+ }
491+ if (ctx.akamai.siem == null) {
492+ ctx.akamai.siem = new HashMap();
493+ }
494+ if (ctx.akamai.siem.user_risk == null) {
495+ ctx.akamai.siem.user_risk = new HashMap();
496+ }
497+ ctx.akamai.siem.user_risk.general = m;
498+ }
499+ }
426500 # #
427501 - append :
428502 field : related.ip
0 commit comments