fluent-plugin-parser-winevt_xml 0.1.1 → 0.2.3.rc1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,34 +1,56 @@
1
- # fluent-plugin-parser-winevt_xml
2
-
3
- [![Build status](https://ci.appveyor.com/api/projects/status/eb0capv0q70u381f/branch/master?svg=true)](https://ci.appveyor.com/project/fluent/fluent-plugin-parser-winevt-xml/branch/master)
4
- [![Build Status](https://travis-ci.org/fluent/fluent-plugin-parser-winevt_xml.svg?branch=master)](https://travis-ci.org/fluent/fluent-plugin-parser-winevt_xml)
5
-
6
- ## Component
7
-
8
- ### Fluentd Parser plugin for XML rendered Windows EventLogs
9
-
10
- [Fluentd](https://www.fluentd.org/) plugin to parse XML rendered Windows Event Logs.
11
-
12
- ### Installation
13
-
14
- ```
15
- gem install fluent-plugin-parser-winevt_xml
16
- ```
17
-
18
- ## Configuration
19
-
20
- ```aconf
21
- <parse>
22
- @type winevt_xml
23
- </parse>
24
- ```
25
-
26
- ## Copyright
27
-
28
- ### Copyright
29
-
30
- Copyright(C) 2019- Hiroshi Hatake, Masahiro Nakagawa
31
-
32
- ### License
33
-
34
- Apache License, Version 2.0
1
+ # fluent-plugin-parser-winevt_xml
2
+
3
+ [![Build status](https://ci.appveyor.com/api/projects/status/eb0capv0q70u381f/branch/master?svg=true)](https://ci.appveyor.com/project/fluent/fluent-plugin-parser-winevt-xml/branch/master)
4
+ [![Build Status](https://travis-ci.org/fluent/fluent-plugin-parser-winevt_xml.svg?branch=master)](https://travis-ci.org/fluent/fluent-plugin-parser-winevt_xml)
5
+
6
+ ## Component
7
+
8
+ ### Fluentd Parser plugin for XML rendered Windows EventLogs
9
+
10
+ [Fluentd](https://www.fluentd.org/) plugin to parse XML rendered Windows Event Logs.
11
+
12
+ ### Installation
13
+
14
+ ```
15
+ gem install fluent-plugin-parser-winevt_xml
16
+ ```
17
+
18
+ ## Configuration
19
+
20
+ ### parser_winevt_xml
21
+
22
+ ```aconf
23
+ <parse>
24
+ @type winevt_xml
25
+ preserve_qualifiers true
26
+ </parse>
27
+ ```
28
+
29
+ #### preserve_qualifiers
30
+
31
+ Preserve Qualifiers key instead of calculating actual EventID with Qualifiers. Default is `true`.
32
+
33
+ ### parser_winevt_sax
34
+
35
+ This plugin is a bit faster than `winevt_xml`.
36
+
37
+ ```aconf
38
+ <parse>
39
+ @type winevt_sax
40
+ preserve_qualifiers true
41
+ </parse>
42
+ ```
43
+
44
+ #### preserve_qualifiers
45
+
46
+ Preserve Qualifiers key instead of calculating actual EventID with Qualifiers. Default is `true`.
47
+
48
+ ## Copyright
49
+
50
+ ### Copyright
51
+
52
+ Copyright(C) 2019- Hiroshi Hatake, Masahiro Nakagawa
53
+
54
+ ### License
55
+
56
+ Apache License, Version 2.0
data/Rakefile CHANGED
@@ -1,10 +1,10 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
3
-
4
- Rake::TestTask.new(:test) do |test|
5
- test.libs << 'lib' << 'test'
6
- test.pattern = 'test/**/test_*.rb'
7
- test.verbose = true
8
- end
9
-
10
- task default: :test
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs << 'lib' << 'test'
6
+ test.pattern = 'test/**/test_*.rb'
7
+ test.verbose = true
8
+ end
9
+
10
+ task default: :test
@@ -1,24 +1,24 @@
1
- version: '{build}'
2
-
3
- # init:
4
- # - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
5
-
6
- install:
7
- - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
8
- - ruby --version
9
- - gem --version
10
- - ridk.cmd exec bundle install
11
- build: off
12
- test_script:
13
- - bundle exec rake test
14
- # - bundle exec rake test TESTOPTS=-v
15
-
16
- branches:
17
- only:
18
- - master
19
-
20
- # https://www.appveyor.com/docs/installed-software/#ruby
21
- environment:
22
- matrix:
23
- - ruby_version: "24-x64"
24
- - ruby_version: "24"
1
+ version: '{build}'
2
+
3
+ # init:
4
+ # - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
5
+
6
+ install:
7
+ - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
8
+ - ruby --version
9
+ - gem --version
10
+ - ridk.cmd exec bundle install
11
+ build: off
12
+ test_script:
13
+ - bundle exec rake test
14
+ # - bundle exec rake test TESTOPTS=-v
15
+
16
+ branches:
17
+ only:
18
+ - master
19
+
20
+ # https://www.appveyor.com/docs/installed-software/#ruby
21
+ environment:
22
+ matrix:
23
+ - ruby_version: "24-x64"
24
+ - ruby_version: "24"
@@ -1,25 +1,25 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "fluent-plugin-parser-winevt_xml"
7
- spec.version = "0.1.1"
8
- spec.authors = ["Hiroshi Hatake", "Masahiro Nakagawa"]
9
- spec.email = ["cosmo0920.oucc@gmail.com", "repeatedly@gmail.com"]
10
- spec.summary = %q{Fluentd Parser plugin to parse XML rendered windows event log.}
11
- spec.description = %q{Fluentd Parser plugin to parse XML rendered windows event log.}
12
- spec.homepage = "https://github.com/fluent/fluent-plugin-parser-winevt_xml"
13
- spec.license = "Apache-2.0"
14
-
15
- spec.files = `git ls-files -z`.split("\x0")
16
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
- spec.require_paths = ["lib"]
19
-
20
- spec.add_development_dependency "bundler"
21
- spec.add_development_dependency "rake"
22
- spec.add_development_dependency "test-unit", "~> 3.2.0"
23
- spec.add_runtime_dependency "fluentd", [">= 0.14.12", "< 2"]
24
- spec.add_runtime_dependency "nokogiri", "~> 1.10"
25
- end
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "fluent-plugin-parser-winevt_xml"
7
+ spec.version = "0.2.3.rc1"
8
+ spec.authors = ["Hiroshi Hatake", "Masahiro Nakagawa"]
9
+ spec.email = ["cosmo0920.oucc@gmail.com", "repeatedly@gmail.com"]
10
+ spec.summary = %q{Fluentd Parser plugin to parse XML rendered windows event log.}
11
+ spec.description = %q{Fluentd Parser plugin to parse XML rendered windows event log.}
12
+ spec.homepage = "https://github.com/fluent/fluent-plugin-parser-winevt_xml"
13
+ spec.license = "Apache-2.0"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler"
21
+ spec.add_development_dependency "rake"
22
+ spec.add_development_dependency "test-unit", "~> 3.2.0"
23
+ spec.add_runtime_dependency "fluentd", [">= 0.14.12", "< 2"]
24
+ spec.add_runtime_dependency "nokogiri", [">= 1.11.pre", "< 1.12"]
25
+ end
@@ -0,0 +1,27 @@
1
+ require 'fluent/plugin/parser'
2
+ require 'fluent/plugin/winevt_sax_document'
3
+ require 'nokogiri'
4
+
5
+ module Fluent::Plugin
6
+ class WinevtSAXparser < Parser
7
+ Fluent::Plugin.register_parser('winevt_sax', self)
8
+
9
+ config_param :preserve_qualifiers, :bool, default: true
10
+
11
+ def winevt_xml?
12
+ true
13
+ end
14
+
15
+ def preserve_qualifiers?
16
+ @preserve_qualifiers
17
+ end
18
+
19
+ def parse(text)
20
+ evtxml = WinevtXMLDocument.new(@preserve_qualifiers)
21
+ parser = Nokogiri::XML::SAX::Parser.new(evtxml)
22
+ parser.parse(text)
23
+ time = @estimate_current_event ? Fluent::EventTime.now : nil
24
+ yield time, evtxml.result
25
+ end
26
+ end
27
+ end
@@ -1,34 +1,63 @@
1
- require 'fluent/plugin/parser'
2
- require 'nokogiri'
3
-
4
- module Fluent::Plugin
5
- class WinevtXMLparser < Parser
6
- Fluent::Plugin.register_parser('winevt_xml', self)
7
-
8
- def parse(text)
9
- record = {}
10
- doc = Nokogiri::XML(text)
11
- system_elem = doc/'Event'/'System'
12
- record["ProviderName"] = (system_elem/"Provider").attribute("Name").text rescue nil
13
- record["ProviderGUID"] = (system_elem/"Provider").attribute("Guid").text rescue nil
14
- record["EventID"] = (system_elem/'EventID').text rescue nil
15
- record["Qualifiers"] = (system_elem/'EventID').attribute("Qualifiers").text rescue nil
16
- record["Level"] = (system_elem/'Level').text rescue nil
17
- record["Task"] = (system_elem/'Task').text rescue nil
18
- record["Opcode"] = (system_elem/'Opcode').text rescue nil
19
- record["Keywords"] = (system_elem/'Keywords').text rescue nil
20
- record["TimeCreated"] = (system_elem/'TimeCreated').attribute("SystemTime").text rescue nil
21
- record["EventRecordID"] = (system_elem/'EventRecordID').text rescue nil
22
- record["ActivityID"] = (system_elem/'ActivityID').text rescue nil
23
- record["RelatedActivityID"] = (system_elem/'Correlation').attribute("ActivityID").text rescue nil
24
- record["ThreadID"] = (system_elem/'Execution').attribute("ThreadID").text rescue nil
25
- record["Channel"] = (system_elem/'Channel').text rescue nil
26
- record["Computer"] = (system_elem/"Computer").text rescue nil
27
- record["UserID"] = (system_elem/'Security').attribute("UserID").text rescue nil
28
- record["Version"] = (system_elem/'Version').text rescue nil
29
- record["InsertStrings"] = [] # These parameters are processed in winevt_c.
30
- time = @estimate_current_event ? Fluent::EventTime.now : nil
31
- yield time, record
32
- end
33
- end
34
- end
1
+ require 'fluent/plugin/parser'
2
+ require 'nokogiri'
3
+
4
+ module Fluent::Plugin
5
+ class WinevtXMLparser < Parser
6
+ Fluent::Plugin.register_parser('winevt_xml', self)
7
+
8
+ config_param :preserve_qualifiers, :bool, default: true
9
+
10
+ def winevt_xml?
11
+ true
12
+ end
13
+
14
+ def preserve_qualifiers?
15
+ @preserve_qualifiers
16
+ end
17
+
18
+ def MAKELONG(low, high)
19
+ (low & 0xffff) | (high & 0xffff) << 16
20
+ end
21
+
22
+ def event_id(system_elem)
23
+ return (system_elem/'EventID').text rescue nil if @preserve_qualifiers
24
+
25
+ qualifiers = (system_elem/'EventID').attribute("Qualifiers").text rescue nil
26
+ if qualifiers
27
+ event_id = (system_elem/'EventID').text
28
+ event_id = MAKELONG(event_id.to_i, qualifiers.to_i)
29
+ event_id.to_s
30
+ else
31
+ (system_elem/'EventID').text rescue nil
32
+ end
33
+ end
34
+
35
+ def parse(text)
36
+ record = {}
37
+ doc = Nokogiri::XML(text)
38
+ system_elem = doc/'Event'/'System'
39
+ record["ProviderName"] = (system_elem/"Provider").attribute("Name").text rescue nil
40
+ record["ProviderGUID"] = (system_elem/"Provider").attribute("Guid").text rescue nil
41
+ if @preserve_qualifiers
42
+ record["Qualifiers"] = (system_elem/'EventID').attribute("Qualifiers").text rescue nil
43
+ end
44
+ record["EventID"] = event_id(system_elem)
45
+ record["Level"] = (system_elem/'Level').text rescue nil
46
+ record["Task"] = (system_elem/'Task').text rescue nil
47
+ record["Opcode"] = (system_elem/'Opcode').text rescue nil
48
+ record["Keywords"] = (system_elem/'Keywords').text rescue nil
49
+ record["TimeCreated"] = (system_elem/'TimeCreated').attribute("SystemTime").text rescue nil
50
+ record["EventRecordID"] = (system_elem/'EventRecordID').text rescue nil
51
+ record["ActivityID"] = (system_elem/'Correlation').attribute('ActivityID').text rescue nil
52
+ record["RelatedActivityID"] = (system_elem/'Correlation').attribute("RelatedActivityID").text rescue nil
53
+ record["ThreadID"] = (system_elem/'Execution').attribute("ThreadID").text rescue nil
54
+ record["ProcessID"] = (system_elem/'Execution').attribute("ProcessID").text rescue nil
55
+ record["Channel"] = (system_elem/'Channel').text rescue nil
56
+ record["Computer"] = (system_elem/"Computer").text rescue nil
57
+ record["UserID"] = (system_elem/'Security').attribute("UserID").text rescue nil
58
+ record["Version"] = (system_elem/'Version').text rescue nil
59
+ time = @estimate_current_event ? Fluent::EventTime.now : nil
60
+ yield time, record
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,73 @@
1
+ require 'nokogiri'
2
+
3
+ class WinevtXMLDocument < Nokogiri::XML::SAX::Document
4
+ def initialize(preserve_qualifiers)
5
+ @stack = []
6
+ @result = {}
7
+ @preserve_qualifiers = preserve_qualifiers
8
+ super()
9
+ end
10
+
11
+ def MAKELONG(low, high)
12
+ (low & 0xffff) | (high & 0xffff) << 16
13
+ end
14
+
15
+ def event_id
16
+ if @result.has_key?("Qualifiers")
17
+ qualifiers = @result.delete("Qualifiers")
18
+ event_id = @result['EventID']
19
+ event_id = MAKELONG(event_id.to_i, qualifiers.to_i)
20
+ @result['EventID'] = event_id.to_s
21
+ else
22
+ @result['EventID']
23
+ end
24
+ end
25
+
26
+ def result
27
+ return @result if @preserve_qualifiers
28
+
29
+ if @result
30
+ @result['EventID'] = event_id
31
+ end
32
+ @result
33
+ end
34
+
35
+ def start_document
36
+ end
37
+
38
+ def start_element(name, attributes = [])
39
+ @stack << name
40
+
41
+ if name == "Provider"
42
+ @result["ProviderName"] = attributes[0][1] rescue nil
43
+ @result["ProviderGUID"] = attributes[1][1] rescue nil
44
+ elsif name == "EventID"
45
+ @result["Qualifiers"] = attributes[0][1] rescue nil
46
+ elsif name == "TimeCreated"
47
+ @result["TimeCreated"] = attributes[0][1] rescue nil
48
+ elsif name == "Correlation"
49
+ @result["ActivityID"] = attributes[0][1] rescue nil
50
+ @result["RelatedActivityID"] = attributes[1][1] rescue nil
51
+ elsif name == "Execution"
52
+ @result["ProcessID"] = attributes[0][1] rescue nil
53
+ @result["ThreadID"] = attributes[1][1] rescue nil
54
+ elsif name == "Security"
55
+ @result["UserID"] = attributes[0][1] rescue nil
56
+ end
57
+ end
58
+
59
+ def characters(string)
60
+ element = @stack.last
61
+
62
+ if /^EventID|Level|Task|Opcode|Keywords|EventRecordID|
63
+ ActivityID|Channel|Computer|Security|Version$/ === element
64
+ @result[element] = string
65
+ end
66
+ end
67
+
68
+ def end_element(name, attributes = [])
69
+ end
70
+
71
+ def end_document
72
+ end
73
+ end
@@ -0,0 +1 @@
1
+ <Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'><System><Provider Name='Microsoft-Windows-Security-SPP' Guid='{E23B33B0-C8C9-472C-A5F9-F2BDFEA0F156}' EventSourceName='Software Protection Platform Service'/><EventID Qualifiers='49152'>16394</EventID><Version>0</Version><Level>4</Level><Task>0</Task><Opcode>0</Opcode><Keywords>0x80000000000000</Keywords><TimeCreated SystemTime='2020-01-16T09:57:18.013693700Z'/><EventRecordID>150731</EventRecordID><Correlation/><Execution ProcessID='0' ThreadID='0'/><Channel>Application</Channel><Computer>DESKTOP-G457RDR</Computer><Security/></System><EventData></EventData></Event>
@@ -1 +1 @@
1
- <Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'><System><Provider Name='Microsoft-Windows-Security-Auditing' Guid='{54849625-5478-4994-A5BA-3E3B0328C30D}'/><EventID>4624</EventID><Version>2</Version><Level>0</Level><Task>12544</Task><Opcode>0</Opcode><Keywords>0x8020000000000000</Keywords><TimeCreated SystemTime='2019-06-13T09:21:23.345889600Z'/><EventRecordID>80688</EventRecordID><Correlation ActivityID='{587F0743-1F71-0006-5007-7F58711FD501}'/><Execution ProcessID='912' ThreadID='24708'/><Channel>Security</Channel><Computer>Fluentd-Developing-Windows</Computer><Security/></System><EventData><Data Name='SubjectUserSid'>S-1-5-18</Data><Data Name='SubjectUserName'>Fluentd-Developing-Windows$</Data><Data Name='SubjectDomainName'>WORKGROUP</Data><Data Name='SubjectLogonId'>0x3e7</Data><Data Name='TargetUserSid'>S-1-5-18</Data><Data Name='TargetUserName'>SYSTEM</Data><Data Name='TargetDomainName'>NT AUTHORITY</Data><Data Name='TargetLogonId'>0x3e7</Data><Data Name='LogonType'>5</Data><Data Name='LogonProcessName'>Advapi </Data><Data Name='AuthenticationPackageName'>Negotiate</Data><Data Name='WorkstationName'>-</Data><Data Name='LogonGuid'>{00000000-0000-0000-0000-000000000000}</Data><Data Name='TransmittedServices'>-</Data><Data Name='LmPackageName'>-</Data><Data Name='KeyLength'>0</Data><Data Name='ProcessId'>0x344</Data><Data Name='ProcessName'>C:\Windows\System32\services.exe</Data><Data Name='IpAddress'>-</Data><Data Name='IpPort'>-</Data><Data Name='ImpersonationLevel'>%%1833</Data><Data Name='RestrictedAdminMode'>-</Data><Data Name='TargetOutboundUserName'>-</Data><Data Name='TargetOutboundDomainName'>-</Data><Data Name='VirtualAccount'>%%1843</Data><Data Name='TargetLinkedLogonId'>0x0</Data><Data Name='ElevatedToken'>%%1842</Data></EventData></Event>
1
+ <Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'><System><Provider Name='Microsoft-Windows-Security-Auditing' Guid='{54849625-5478-4994-A5BA-3E3B0328C30D}'/><EventID>4624</EventID><Version>2</Version><Level>0</Level><Task>12544</Task><Opcode>0</Opcode><Keywords>0x8020000000000000</Keywords><TimeCreated SystemTime='2019-06-13T09:21:23.345889600Z'/><EventRecordID>80688</EventRecordID><Correlation ActivityID='{587F0743-1F71-0006-5007-7F58711FD501}'/><Execution ProcessID='912' ThreadID='24708'/><Channel>Security</Channel><Computer>Fluentd-Developing-Windows</Computer><Security/></System><EventData><Data Name='SubjectUserSid'>S-1-5-18</Data><Data Name='SubjectUserName'>Fluentd-Developing-Windows$</Data><Data Name='SubjectDomainName'>WORKGROUP</Data><Data Name='SubjectLogonId'>0x3e7</Data><Data Name='TargetUserSid'>S-1-5-18</Data><Data Name='TargetUserName'>SYSTEM</Data><Data Name='TargetDomainName'>NT AUTHORITY</Data><Data Name='TargetLogonId'>0x3e7</Data><Data Name='LogonType'>5</Data><Data Name='LogonProcessName'>Advapi </Data><Data Name='AuthenticationPackageName'>Negotiate</Data><Data Name='WorkstationName'>-</Data><Data Name='LogonGuid'>{00000000-0000-0000-0000-000000000000}</Data><Data Name='TransmittedServices'>-</Data><Data Name='LmPackageName'>-</Data><Data Name='KeyLength'>0</Data><Data Name='ProcessId'>0x344</Data><Data Name='ProcessName'>C:\Windows\System32\services.exe</Data><Data Name='IpAddress'>-</Data><Data Name='IpPort'>-</Data><Data Name='ImpersonationLevel'>%%1833</Data><Data Name='RestrictedAdminMode'>-</Data><Data Name='TargetOutboundUserName'>-</Data><Data Name='TargetOutboundDomainName'>-</Data><Data Name='VirtualAccount'>%%1843</Data><Data Name='TargetLinkedLogonId'>0x0</Data><Data Name='ElevatedToken'>%%1842</Data></EventData></Event>
@@ -1,23 +1,24 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'test/unit'
11
-
12
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
- $LOAD_PATH.unshift(File.dirname(__FILE__))
14
- require 'fluent/test'
15
-
16
- require 'fluent/test/driver/parser'
17
- require 'fluent/plugin/parser_winevt_xml'
18
-
19
- class Test::Unit::TestCase
20
- end
21
- require 'fluent/test/helpers'
22
-
23
- include Fluent::Test::Helpers
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+
12
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
14
+ require 'fluent/test'
15
+
16
+ require 'fluent/test/driver/parser'
17
+ require 'fluent/plugin/parser_winevt_xml'
18
+ require 'fluent/plugin/parser_winevt_sax'
19
+
20
+ class Test::Unit::TestCase
21
+ end
22
+ require 'fluent/test/helpers'
23
+
24
+ include Fluent::Test::Helpers