-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathautomation-CEFParser.yml
101 lines (99 loc) · 3.52 KB
/
automation-CEFParser.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
args:
- default: true
description: The data that contains the CEF rows
name: data
required: true
comment: Parse CEF data into the context. Please notice that outputs will display
only the 7 mandatory fields even if the CEF event includes many other custom or
extended fields.
commonfields:
id: CEFParser
version: -1
enabled: true
name: CEFParser
outputs:
- contextPath: CEFEvent.cefVersion
description: The CEF version
- contextPath: CEFEvent.vendor
description: The product vendor
- contextPath: CEFEvent.product
description: The product name
- contextPath: CEFEvent.version
description: The product version
- contextPath: CEFEvent.signatureID
description: The signature ID for the alert, if relevant
- contextPath: CEFEvent.name
description: The alert name
- contextPath: CEFEvent.severity
description: The alert severity
runonce: false
script: |-
// Consts
var mandatoryLabels = ['cefVersion', 'vendor', 'product', 'version', 'signatureID', 'name', 'severity'];
// first, split the lines for multiple CEF rows
var rows = args.data.split('\nCEF:');
var data = [];
for (var i=0; i<rows.length; i++) {
var o = {};
// First, read the mandatory fields
var start = 0;
for (var j=0; j<mandatoryLabels.length; j++) {
var end = rows[i].indexOf('|', start);
if (end < 0) {
throw 'Invalid format in row ' + i + '. Missing mandatory field ' + j + '.';
}
// Ignore escaped separators
while (rows[i][end-1] === '\\') {
end = rows[i].indexOf('|', end + 1);
if (end < 0) {
throw 'Invalid format in row ' + i + '. Missing mandatory field ' + j + '.';
}
}
o[mandatoryLabels[j]] = (i === 0 && j === 0) ? rows[i].substring(4, end) : rows[i].substring(start, end);
start = end + 1;
}
// Now, handle extensions which should be separated by '='
var currLabel = '';
var eq = rows[i].indexOf('=', start);
while (eq > 0) {
if (rows[i][eq-1] === '\\') {
eq = rows[i].indexOf('=', eq + 1);
continue;
}
// We found a good '=', now need to go back and find the beginning of the label
for (var b=eq-1; b>start; b--) {
if (rows[i][b] === ' ') {
b++;
break;
}
}
if (currLabel === '') {
currLabel = rows[i].substring(b, eq);
start = eq + 1;
} else {
o[currLabel] = rows[i].substring(start, b).trim();
currLabel = rows[i].substring(b, eq);
start = eq + 1;
}
eq = rows[i].indexOf('=', start);
}
if (currLabel !== '' && start < rows[i].length - 1) {
o[currLabel] = rows[i].substring(start);
}
// Convert labels of custom fields to actual attributes (cs1Label, cn1Label, cs1, cn1)
var keys = Object.keys(o);
for (var k=0; k<keys.length; k++) {
if (keys[k].match(/c[ns]\d+Label/i) && keys.indexOf(keys[k].substring(0, keys[k].length-5)) >= 0) {
o[o[keys[k]]] = o[keys[k].substring(0, keys[k].length-5)];
delete o[keys[k]];
delete o[keys[k].substring(0, keys[k].length-5)];
}
}
data.push(o);
}
return {Type: entryTypes.note, Contents: data, ContentsFormat: formats.json, HumanReadable: tableToMarkdown('CEF Events', data), EntryContext: {CEFEvent: data}};
scripttarget: 0
system: true
tags:
- Utility
type: javascript