logstash-codec-cef 4.1.0-java → 4.1.2-java
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -1
- data/lib/logstash/codecs/cef.rb +10 -9
- data/logstash-codec-cef.gemspec +1 -2
- data/spec/codecs/cef_spec.rb +36 -17
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4970c9754e3a998c7768dfd91127908d00754c2d
|
4
|
+
data.tar.gz: c89d21a60488b04b8f305346b35715bf398b22b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ddba453c75fec89baf0c374663721f20df6edfa054f1ff8b904e75cd95da4db92d1d6bd20771de5d1f6ba8d4bae1e7a5f15068cc250568a718265129a5b9802
|
7
|
+
data.tar.gz: e1132893ea01846719b888fe1f83c0d79bd1f7c6a1600ccbd6c6f6aa996915069b8eeb6f4bfae90aeb66d7f3f7281fef031bba8df4d161a98685eb6dab143923
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,15 @@
|
|
1
|
+
## 4.1.2
|
2
|
+
- added mapping for outcome = eventOutcome from CEF whitepaper (ref:p26/39)
|
3
|
+
|
4
|
+
## 4.1.1
|
5
|
+
- changed rt from receiptTime to deviceReceiptTime (ref:p27/39)
|
6
|
+
- changed tokenizer to include additional fields (ad.fieldname)
|
7
|
+
|
1
8
|
## 4.1.0
|
2
9
|
- Add `delimiter` setting. This allows the decoder to be used with inputs like the TCP input where event delimiters are used.
|
3
10
|
|
4
11
|
## 4.0.0
|
5
|
-
- Implements the dictionary translation for abbreviated CEF field names from chapter Chapter 2: ArcSight Extension Dictionary
|
12
|
+
- Implements the dictionary translation for abbreviated CEF field names from chapter Chapter 2: ArcSight Extension Dictionary page 3 of 39 [CEF specification](https://protect724.hp.com/docs/DOC-1072).
|
6
13
|
- add `_cefparsefailure` tag on failed decode
|
7
14
|
|
8
15
|
## 3.0.0
|
data/lib/logstash/codecs/cef.rb
CHANGED
@@ -53,7 +53,7 @@ class LogStash::Codecs::CEF < LogStash::Codecs::Base
|
|
53
53
|
# Fields to be included in CEV extension part as key/value pairs
|
54
54
|
config :fields, :validate => :array, :default => []
|
55
55
|
|
56
|
-
# Set this flag if you want to have both v1 and v2 fields indexed at the same time. Note that this option will increase
|
56
|
+
# Set this flag if you want to have both v1 and v2 fields indexed at the same time. Note that this option will increase
|
57
57
|
# the index size and data stored in outputs like Elasticsearch
|
58
58
|
# This option is available to ease transition to new schema
|
59
59
|
config :deprecated_v1_fields, :validate => :boolean, :deprecated => "This setting is being deprecated"
|
@@ -66,7 +66,7 @@ class LogStash::Codecs::CEF < LogStash::Codecs::Base
|
|
66
66
|
# input {
|
67
67
|
# tcp {
|
68
68
|
# codec => cef { delimiter => "\r\n" }
|
69
|
-
# # ...
|
69
|
+
# # ...
|
70
70
|
# }
|
71
71
|
# }
|
72
72
|
#
|
@@ -79,7 +79,7 @@ class LogStash::Codecs::CEF < LogStash::Codecs::Base
|
|
79
79
|
HEADER_FIELDS = ['cefVersion','deviceVendor','deviceProduct','deviceVersion','deviceEventClassId','name','severity']
|
80
80
|
|
81
81
|
# Translating and flattening the CEF extensions with known field names as documented in the Common Event Format whitepaper
|
82
|
-
MAPPINGS = { "act" => "deviceAction", "app" => "applicationProtocol", "c6a1" => "deviceCustomIPv6Address1", "c6a1Label" => "deviceCustomIPv6Address1Label", "c6a2" => "deviceCustomIPv6Address2", "c6a2Label" => "deviceCustomIPv6Address2Label", "c6a3" => "deviceCustomIPv6Address3", "c6a3Label" => "deviceCustomIPv6Address3Label", "c6a4" => "deviceCustomIPv6Address4", "c6a4Label" => "deviceCustomIPv6Address4Label", "cat" => "deviceEventCategory", "cfp1" => "deviceCustomFloatingPoint1", "cfp1Label" => "deviceCustomFloatingPoint1Label", "cfp2" => "deviceCustomFloatingPoint2", "cfp2Label" => "deviceCustomFloatingPoint2", "cfp3" => "deviceCustomFloatingPoint3", "cfp3Label" => "deviceCustomFloatingPoint4Label", "cfp4" => "deviceCustomFloatingPoint4", "cfp4Label" => "deviceCustomFloatingPoint4Label", "cn1" => "deviceCustomNumber1", "cn1Label" => "deviceCustomNumber1Label", "cn2" => "deviceCustomNumber2", "cn2Label" => "deviceCustomNumber2Label", "cn3" => "deviceCustomNumber3", "cn3Label" => "deviceCustomNumber3Label", "cnt" => "baseEventCount", "cs1" => "deviceCustomString1", "cs1Label" => "deviceCustomString1Label", "cs2" => "deviceCustomString2", "cs2Label" => "deviceCustomString2Label", "cs3" => "deviceCustomString3", "cs3Label" => "deviceCustomString3Label", "cs4" => "deviceCustomString4", "cs4Label" => "deviceCustomString4Label", "cs5" => "deviceCustomString5", "cs5Label" => "deviceCustomString5Label", "cs6" => "deviceCustomString6", "cs6Label" => "deviceCustomString6Label", "dhost" => "destinationHostName", "dmac" => "destinationMacAddress", "dntdom" => "destinationNTDomain", "dpid" => "destinationProcessId", "dpriv" => "destinationUserPrivileges", "dproc" => "destinationProcessName", "dpt" => "destinationPort", "dst" => "destinationAddress", "duid" => "destinationUserId", "duser" => "destinationUserName", "dvc" => "deviceAddress", "dvchost" => "deviceHostName", "dvcpid" => "deviceProcessId", "end" => "endTime", "fname" => "fileName", "fsize" => "fileSize", "in" => "bytesIn", "msg" => "message", "out" => "bytesOut", "proto" => "transportProtocol", "request" => "requestUrl", "rt" => "
|
82
|
+
MAPPINGS = { "act" => "deviceAction", "app" => "applicationProtocol", "c6a1" => "deviceCustomIPv6Address1", "c6a1Label" => "deviceCustomIPv6Address1Label", "c6a2" => "deviceCustomIPv6Address2", "c6a2Label" => "deviceCustomIPv6Address2Label", "c6a3" => "deviceCustomIPv6Address3", "c6a3Label" => "deviceCustomIPv6Address3Label", "c6a4" => "deviceCustomIPv6Address4", "c6a4Label" => "deviceCustomIPv6Address4Label", "cat" => "deviceEventCategory", "cfp1" => "deviceCustomFloatingPoint1", "cfp1Label" => "deviceCustomFloatingPoint1Label", "cfp2" => "deviceCustomFloatingPoint2", "cfp2Label" => "deviceCustomFloatingPoint2", "cfp3" => "deviceCustomFloatingPoint3", "cfp3Label" => "deviceCustomFloatingPoint4Label", "cfp4" => "deviceCustomFloatingPoint4", "cfp4Label" => "deviceCustomFloatingPoint4Label", "cn1" => "deviceCustomNumber1", "cn1Label" => "deviceCustomNumber1Label", "cn2" => "deviceCustomNumber2", "cn2Label" => "deviceCustomNumber2Label", "cn3" => "deviceCustomNumber3", "cn3Label" => "deviceCustomNumber3Label", "cnt" => "baseEventCount", "cs1" => "deviceCustomString1", "cs1Label" => "deviceCustomString1Label", "cs2" => "deviceCustomString2", "cs2Label" => "deviceCustomString2Label", "cs3" => "deviceCustomString3", "cs3Label" => "deviceCustomString3Label", "cs4" => "deviceCustomString4", "cs4Label" => "deviceCustomString4Label", "cs5" => "deviceCustomString5", "cs5Label" => "deviceCustomString5Label", "cs6" => "deviceCustomString6", "cs6Label" => "deviceCustomString6Label", "dhost" => "destinationHostName", "dmac" => "destinationMacAddress", "dntdom" => "destinationNTDomain", "dpid" => "destinationProcessId", "dpriv" => "destinationUserPrivileges", "dproc" => "destinationProcessName", "dpt" => "destinationPort", "dst" => "destinationAddress", "duid" => "destinationUserId", "duser" => "destinationUserName", "dvc" => "deviceAddress", "dvchost" => "deviceHostName", "dvcpid" => "deviceProcessId", "end" => "endTime", "fname" => "fileName", "fsize" => "fileSize", "in" => "bytesIn", "msg" => "message", "out" => "bytesOut", "outcome" => "eventOutcome", "proto" => "transportProtocol", "request" => "requestUrl", "rt" => "deviceReceiptTime", "shost" => "sourceHostName", "smac" => "sourceMacAddress", "sntdom" => "sourceNtDomain", "spid" => "sourceProcessId", "spriv" => "sourceUserPrivileges", "sproc" => "sourceProcessName", "spt" => "sourcePort", "src" => "sourceAddress", "start" => "startTime", "suid" => "sourceUserId", "suser" => "sourceUserName", "ahost" => "agentHost", "art" => "agentReceiptTime", "at" => "agentType", "aid" => "agentId", "_cefVer" => "cefVersion", "agt" => "agentAddress", "av" => "agentVersion", "atz" => "agentTimeZone", "dtz" => "destinationTimeZone", "slong" => "sourceLongitude", "slat" => "sourceLatitude", "dlong" => "destinationLongitude", "dlat" => "destinationLatitude", "catdt" => "categoryDeviceType", "mrt" => "managerReceiptTime" }
|
83
83
|
|
84
84
|
DEPRECATED_HEADER_FIELDS = ['cef_version','cef_vendor','cef_product','cef_device_version','cef_sigid','cef_name','cef_severity']
|
85
85
|
|
@@ -160,11 +160,12 @@ class LogStash::Codecs::CEF < LogStash::Codecs::Base
|
|
160
160
|
|
161
161
|
# Insert custom delimiter to separate key-value pairs, to which some values will contain special characters
|
162
162
|
# This separator '|^^^' os tested to be unique
|
163
|
-
message = message.gsub((
|
163
|
+
message = message.gsub((/(?:(\s+(\w+\=)))/),'|^^^\2')
|
164
164
|
|
165
|
-
#
|
166
|
-
#
|
167
|
-
|
165
|
+
# Appropriately tokenizing the additional fields when ArcSight connectors are sending events using "COMPLETE" mode processing.
|
166
|
+
# If these fields are NOT needed, then set the ArcSight processing mode for this destination to "FASTER" or "FASTEST"
|
167
|
+
# Refer to ArcSight's SmartConnector user configuration guide
|
168
|
+
message = message.gsub((/(\s+(\w+\.[^\s]\w+[^\|\s\.\=]+\=))/),'|^^^\2')
|
168
169
|
message = message.split('|^^^')
|
169
170
|
|
170
171
|
# Replaces the '=' with '***' to avoid conflict with strings with HTML content namely key-value pairs where the values contain HTML strings
|
@@ -301,7 +302,7 @@ class LogStash::Codecs::CEF < LogStash::Codecs::Base
|
|
301
302
|
rescue TypeError, ArgumentError
|
302
303
|
false
|
303
304
|
end
|
304
|
-
|
305
|
+
|
305
306
|
def handle_v1_fields(event, split_data)
|
306
307
|
# Store header fields
|
307
308
|
DEPRECATED_HEADER_FIELDS.each_with_index do |field_name, index|
|
@@ -339,6 +340,6 @@ class LogStash::Codecs::CEF < LogStash::Codecs::Base
|
|
339
340
|
event.set('cef_ext', extensions)
|
340
341
|
end
|
341
342
|
|
342
|
-
end
|
343
|
+
end
|
343
344
|
|
344
345
|
end
|
data/logstash-codec-cef.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-codec-cef'
|
4
|
-
s.version = '4.1.
|
4
|
+
s.version = '4.1.2'
|
5
5
|
s.platform = 'java'
|
6
6
|
s.licenses = ['Apache License (2.0)']
|
7
7
|
s.summary = "CEF codec to parse and encode CEF formated logs"
|
@@ -25,4 +25,3 @@ Gem::Specification.new do |s|
|
|
25
25
|
|
26
26
|
s.add_development_dependency 'logstash-devutils'
|
27
27
|
end
|
28
|
-
|
data/spec/codecs/cef_spec.rb
CHANGED
@@ -14,7 +14,7 @@ describe LogStash::Codecs::CEF do
|
|
14
14
|
|
15
15
|
let(:results) { [] }
|
16
16
|
|
17
|
-
context "with delimiter set" do
|
17
|
+
context "with delimiter set" do
|
18
18
|
# '\r\n' in single quotes to simulate the real input from a config
|
19
19
|
# containing \r\n as 4-character sequence in the config:
|
20
20
|
#
|
@@ -344,7 +344,7 @@ describe LogStash::Codecs::CEF do
|
|
344
344
|
insist { e.get('severity') } == "10"
|
345
345
|
end
|
346
346
|
|
347
|
-
context "with delimiter set" do
|
347
|
+
context "with delimiter set" do
|
348
348
|
# '\r\n' in single quotes to simulate the real input from a config
|
349
349
|
# containing \r\n as 4-character sequence in the config:
|
350
350
|
#
|
@@ -494,19 +494,37 @@ describe LogStash::Codecs::CEF do
|
|
494
494
|
end
|
495
495
|
end
|
496
496
|
|
497
|
-
let (:
|
498
|
-
it "should
|
499
|
-
subject.decode(
|
497
|
+
let (:preserve_additional_fields_with_dot_notations) {'CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10|src=10.0.0.192 additional.dotfieldName=new_value ad.Authentification=MICROSOFT_AUTHENTICATION_PACKAGE_V1_0 ad.Error_,Code=3221225578 dst=12.121.122.82 ad.field[0]=field0 ad.name[1]=new_name'}
|
498
|
+
it "should keep ad.fields" do
|
499
|
+
subject.decode(preserve_additional_fields_with_dot_notations) do |e|
|
500
500
|
validate(e)
|
501
501
|
insist { e.get("sourceAddress") } == "10.0.0.192"
|
502
502
|
insist { e.get("destinationAddress") } == "12.121.122.82"
|
503
|
-
insist { e.get("ad.field[0]") } ==
|
504
|
-
insist { e.get("ad.name[1]") } ==
|
503
|
+
insist { e.get("ad.field[0]") } == "field0"
|
504
|
+
insist { e.get("ad.name[1]") } == "new_name"
|
505
|
+
insist { e.get("ad.Authentification") } == "MICROSOFT_AUTHENTICATION_PACKAGE_V1_0"
|
506
|
+
insist { e.get("ad.Error_,Code") } == "3221225578"
|
507
|
+
insist { e.get("additional.dotfieldName") } == "new_value"
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
511
|
+
let (:preserve_random_values_key_value_pairs_alongside_with_additional_fields) {'CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10|src=10.0.0.192 cs4=401 random.user Admin 0 23041A10181C0000 23041810181C0000 /CN\=random.user/OU\=User Login End-Entity /CN\=TEST/OU\=Login CA TEST 34 additional.dotfieldName=new_value ad.Authentification=MICROSOFT_AUTHENTICATION_PACKAGE_V1_0 ad.Error_,Code=3221225578 dst=12.121.122.82 ad.field[0]=field0 ad.name[1]=new_name'}
|
512
|
+
it "should correctly parse random values even with additional fields in message" do
|
513
|
+
subject.decode(preserve_random_values_key_value_pairs_alongside_with_additional_fields) do |e|
|
514
|
+
validate(e)
|
515
|
+
insist { e.get("sourceAddress") } == "10.0.0.192"
|
516
|
+
insist { e.get("destinationAddress") } == "12.121.122.82"
|
517
|
+
insist { e.get("ad.field[0]") } == "field0"
|
518
|
+
insist { e.get("ad.name[1]") } == "new_name"
|
519
|
+
insist { e.get("ad.Authentification") } == "MICROSOFT_AUTHENTICATION_PACKAGE_V1_0"
|
520
|
+
insist { e.get("ad.Error_,Code") } == "3221225578"
|
521
|
+
insist { e.get("additional.dotfieldName") } == "new_value"
|
522
|
+
insist { e.get("deviceCustomString4") } == "401 random.user Admin 0 23041A10181C0000 23041810181C0000 /CN\=random.user/OU\=User Login End-Entity /CN\=TEST/OU\=Login CA TEST 34"
|
505
523
|
end
|
506
524
|
end
|
507
525
|
|
508
526
|
let (:preserve_unmatched_key_mappings) {'CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10|src=10.0.0.192 dst=12.121.122.82 new_key_by_device=new_values here'}
|
509
|
-
it "should
|
527
|
+
it "should preserve unmatched key mappings" do
|
510
528
|
subject.decode(preserve_unmatched_key_mappings) do |e|
|
511
529
|
validate(e)
|
512
530
|
insist { e.get("sourceAddress") } == "10.0.0.192"
|
@@ -515,7 +533,7 @@ describe LogStash::Codecs::CEF do
|
|
515
533
|
end
|
516
534
|
end
|
517
535
|
|
518
|
-
let (:translate_abbreviated_cef_fields) {'CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10|src=10.0.0.192 dst=12.121.122.82 proto=TCP shost=source.host.name dhost=destination.host.name spt=11024 dpt=9200'}
|
536
|
+
let (:translate_abbreviated_cef_fields) {'CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10|src=10.0.0.192 dst=12.121.122.82 proto=TCP shost=source.host.name dhost=destination.host.name spt=11024 dpt=9200 outcome=Success'}
|
519
537
|
it "should translate most known abbreviated CEF field names" do
|
520
538
|
subject.decode(translate_abbreviated_cef_fields) do |e|
|
521
539
|
validate(e)
|
@@ -526,6 +544,7 @@ describe LogStash::Codecs::CEF do
|
|
526
544
|
insist { e.get("destinationHostName") } == "destination.host.name"
|
527
545
|
insist { e.get("sourcePort") } == "11024"
|
528
546
|
insist { e.get("destinationPort") } == "9200"
|
547
|
+
insist { e.get("eventOutcome") } == "Success"
|
529
548
|
end
|
530
549
|
end
|
531
550
|
|
@@ -537,7 +556,7 @@ describe LogStash::Codecs::CEF do
|
|
537
556
|
end
|
538
557
|
end
|
539
558
|
end
|
540
|
-
|
559
|
+
|
541
560
|
context "decode with deprecated version option" do
|
542
561
|
let (:message) { "CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10|src=10.0.0.192 dst=12.121.122.82 spt=1232" }
|
543
562
|
let(:options) {
|
@@ -545,10 +564,10 @@ describe LogStash::Codecs::CEF do
|
|
545
564
|
"deprecated_v1_fields" => true
|
546
565
|
}
|
547
566
|
}
|
548
|
-
|
567
|
+
|
549
568
|
subject(:codec) { LogStash::Codecs::CEF.new(options) }
|
550
|
-
|
551
|
-
def validate(e)
|
569
|
+
|
570
|
+
def validate(e)
|
552
571
|
insist { e.is_a?(LogStash::Event) }
|
553
572
|
insist { e.get('cef_version') } == "0"
|
554
573
|
insist { e.get('cef_device_version') } == "1.0"
|
@@ -590,7 +609,7 @@ describe LogStash::Codecs::CEF do
|
|
590
609
|
subject.decode(no_ext) do |e|
|
591
610
|
validate(e)
|
592
611
|
insist { e.get("cef_ext") } == nil
|
593
|
-
end
|
612
|
+
end
|
594
613
|
end
|
595
614
|
|
596
615
|
let (:missing_headers) { "CEF:0|||1.0|100|trojan successfully stopped|10|src=10.0.0.192 dst=12.121.122.82 spt=1232" }
|
@@ -601,14 +620,14 @@ describe LogStash::Codecs::CEF do
|
|
601
620
|
insist { e.get("cef_product") } == ""
|
602
621
|
insist { e.get("deviceVendor") } == ""
|
603
622
|
insist { e.get("deviceProduct") } == ""
|
604
|
-
end
|
623
|
+
end
|
605
624
|
end
|
606
625
|
|
607
626
|
let (:leading_whitespace) { "CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10| src=10.0.0.192 dst=12.121.122.82 spt=1232" }
|
608
627
|
it "should strip leading whitespace from the message" do
|
609
628
|
subject.decode(leading_whitespace) do |e|
|
610
629
|
validate(e)
|
611
|
-
end
|
630
|
+
end
|
612
631
|
end
|
613
632
|
|
614
633
|
let (:escaped_pipes) { 'CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10|moo=this\|has an escaped pipe' }
|
@@ -616,7 +635,7 @@ describe LogStash::Codecs::CEF do
|
|
616
635
|
subject.decode(escaped_pipes) do |e|
|
617
636
|
ext = e.get('cef_ext')
|
618
637
|
insist { ext['moo'] } == 'this\|has an escaped pipe'
|
619
|
-
end
|
638
|
+
end
|
620
639
|
end
|
621
640
|
|
622
641
|
let (:pipes_in_message) {'CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10|moo=this|has an pipe'}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-codec-cef
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.1.
|
4
|
+
version: 4.1.2
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|