logstash-filter-decrypt 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1ffee5f64ee92e1cf2bff9126ec72e8029776015
4
+ data.tar.gz: d79a89fba3b9bc3a1f0c2c5915301d99418fc0ba
5
+ SHA512:
6
+ metadata.gz: fdfa04c5a811f139240bfe854e927085a5675b24c4d2f31fb19b2dfd7b1db4591f59c9c1827556a90d56830d101eddc6efe1458204dceac9e4e0c7ac179c8904
7
+ data.tar.gz: 49a860b321c74b53199d7e1cdb527844106b1777d67525d74695585ca8b4c4d83d6e8f6533393396ae3e3fc06cd541bf2d84696ce7ed293d7c6393e74640b8b8
@@ -0,0 +1,5 @@
1
+ ## 2.0.0
2
+ - Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
3
+ instead of using Thread.raise on the plugins' threads. Ref: https://github.com/elastic/logstash/pull/3895
4
+ - Dependency on logstash-core update to 2.0
5
+
@@ -0,0 +1,11 @@
1
+ The following is a list of people who have contributed ideas, code, bug
2
+ reports, or in general have helped logstash along its way.
3
+
4
+ Contributors:
5
+ * Aaron Mildenstein (untergeek)
6
+ * Pier-Hugues Pellerin (ph)
7
+
8
+ Note: If you've sent us patches, bug reports, or otherwise contributed to
9
+ Logstash, and you aren't on the list above and want to be, please let us know
10
+ and we'll make sure you're here. Contributions from folks like you are what make
11
+ open source awesome.
@@ -0,0 +1,2 @@
1
+ # logstash-filter-example
2
+ Example filter plugin. This should help bootstrap your effort to write your own filter plugin!
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2012–2016 Elasticsearch <http://www.elastic.co>
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,5 @@
1
+ Elasticsearch
2
+ Copyright 2012-2015 Elasticsearch
3
+
4
+ This product includes software developed by The Apache Software
5
+ Foundation (http://www.apache.org/).
@@ -0,0 +1,3 @@
1
+ # Logstash Decrypt Filter
2
+
3
+ Simple Filter to Decrypt XOR and AES Payloads.
@@ -0,0 +1,16 @@
1
+ require 'openssl'
2
+ class Aes < Cipher
3
+
4
+ def decrypt(data,key)
5
+ aes = OpenSSL::Cipher.new('AES-128-CBC')
6
+ aes.decrypt
7
+ aes.key = key
8
+ return aes.update(data)
9
+ end
10
+
11
+ def aesdecrypt
12
+ return match(@payload,@prefix,@keys,@keywords)
13
+
14
+
15
+ end
16
+ end
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+ require 'base64'
3
+ require 'uri'
4
+ class Cipher
5
+ def initialize(prefix,payload,keys,keywords)
6
+ @prefix=prefix
7
+ @payload=payload
8
+ @keys=keys
9
+ @keywords=keywords
10
+ end
11
+
12
+ #Extract according to prefix
13
+ def extract(payload)
14
+ return payload[@prefix.length..@payload.length]
15
+ end
16
+
17
+ #Decode Payload and unescape Characters
18
+ def decode(payload)
19
+ return Base64.decode64(URI.unescape(payload))
20
+ end
21
+
22
+ def match(payload,prefix,keys,keywords)
23
+ #Match, Payload
24
+ result = [false,'']
25
+ payload = decode(extract(payload))
26
+ keys.each do |key|
27
+ begin
28
+ payload = decrypt(payload, Base64.decode64(key))
29
+ keywords.each do |keyword|
30
+ if payload.include? keyword
31
+ result[0] = true
32
+ result[1] = payload.to_s
33
+ break
34
+ end
35
+ end
36
+ rescue
37
+ return result
38
+ end
39
+ end
40
+
41
+ return result
42
+ end
43
+
44
+ end
@@ -0,0 +1,116 @@
1
+ # encoding: utf-8
2
+ require "logstash/filters/base"
3
+ require "logstash/namespace"
4
+ require "logstash/json"
5
+ require "logstash/timestamp"
6
+ require "logstash/filters/cipher"
7
+ require "logstash/filters/xor"
8
+ require "logstash/filters/aes"
9
+ require 'thread'
10
+
11
+
12
+ class LogStash::Filters::Decrypt < LogStash::Filters::Base
13
+
14
+ # The field to perform filter
15
+ #
16
+ # Example, to use the @message field (default) :
17
+ # [source,ruby]
18
+ # filter { decrypt { source => "message" } }
19
+
20
+ #Config_name for the Logstash Config
21
+ config_name "decrypt"
22
+
23
+ # Replace the message with this value.
24
+ config :source, :validate => :string, :required => true
25
+
26
+
27
+ public
28
+ def register
29
+ # Add instance variables
30
+ @campaigns = Dir.glob("campaigns/*.json")
31
+ end # def register
32
+
33
+ public
34
+ def filter(event)
35
+
36
+ if @source
37
+ source = event.get(@source)
38
+ # Replace the event message with our message as configured in the
39
+ # config file.
40
+ parsed = LogStash::Json.load(source)
41
+
42
+ parsed_timestamp = parsed.delete(LogStash::Event::TIMESTAMP)
43
+ begin
44
+ timestamp = parsed_timestamp ? LogStash::Timestamp.coerce(parsed_timestamp) : nil
45
+ rescue LogStash::TimestampParserError => e
46
+ timestamp = nil
47
+ end
48
+
49
+ threads = []
50
+
51
+ @campaigns.each do |file|
52
+ file = File.read(file)
53
+ campaign = LogStash::Json.load(file)
54
+ @keywordstrategy = nil
55
+ @strategies = campaign['SearchStrategies']
56
+ @strategies.each do |strategy|
57
+ if strategy["type"].eql? "KeywordStrategy"
58
+ @logger.info("Found Keyword Strategy")
59
+ @keywordstrategy = strategy
60
+ end
61
+ end
62
+ if parsed["body"].nil? || parsed["body"].empty?
63
+ @logger.info("Empty Body -> Skip")
64
+ elsif @keywordstrategy.nil?
65
+ @logger.info("No Keyword Strategy found -> Skip")
66
+ elsif parsed["body"].include? @keywordstrategy["prefix"]
67
+ @logger.info("Decrypt Body")
68
+ threads << Thread.new {
69
+
70
+ if campaign["encryption"]["xor"].any?
71
+ xor=Xor.new(@keywordstrategy["prefix"],parsed["body"],campaign["encryption"]["xor"],@keywordstrategy["keywords"])
72
+ result = xor.xordecrypt
73
+ if result[0]
74
+ parsed["decrypted"] = result[1]
75
+ parsed["tags"] = [campaign["name"],"XOR"]
76
+ end
77
+ end
78
+
79
+ if campaign["encryption"]["aes"].any?
80
+ aes=Aes.new(@keywordstrategy["prefix"],parsed["body"],campaign["encryption"]["aes"],@keywordstrategy["keywords"])
81
+ result = aes.aesdecrypt
82
+ if result[0]
83
+ parsed["decrypted"] = result[1]
84
+ parsed["tags"] = [campaign["name"],"AES"]
85
+ end
86
+ end
87
+ }
88
+ else
89
+ @logger.info("Prefix not in Payload -> Skip")
90
+ end
91
+ end
92
+
93
+ threads.each { |thr| thr.join }
94
+
95
+ # using the event.set API
96
+ parsed.each{|k, v| event.set(k, v)}
97
+
98
+ if parsed_timestamp
99
+ if timestamp
100
+ event.timestamp = timestamp
101
+ else
102
+ event.timestamp = LogStash::Timestamp.new
103
+ @logger.warn("Unrecognized #{LogStash::Event::TIMESTAMP} value, setting current time to #{LogStash::Event::TIMESTAMP}, original in #{LogStash::Event::TIMESTAMP_FAILURE_FIELD} field", :value => parsed_timestamp.inspect)
104
+ event.tag(LogStash::Event::TIMESTAMP_FAILURE_TAG)
105
+ event.set(LogStash::Event::TIMESTAMP_FAILURE_FIELD, parsed_timestamp.to_s)
106
+ end
107
+ end
108
+ # correct debugging log statement for reference
109
+ # using the event.get API
110
+ @logger.info("Event after filter", :event => event)
111
+ end
112
+
113
+ # filter_matched should go in the last line of our successful code
114
+ filter_matched(event)
115
+ end # def filter
116
+ end # class LogStash::Filters::Example
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ class Xor < Cipher
3
+
4
+ def decrypt(data, key)
5
+ data.length.times { |e|
6
+ data[e] = (key[e % key.length].ord ^ data[e].ord).chr;
7
+ }
8
+ return data
9
+ end
10
+
11
+ #Decrypt Payload and match it against Keywords
12
+ def xordecrypt
13
+ return match(@payload,@prefix,@keys,@keywords)
14
+ end
15
+
16
+ end
@@ -0,0 +1,23 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'logstash-filter-decrypt'
3
+ s.version = '0.0.2'
4
+ s.licenses = ['Apache License (2.0)']
5
+ s.summary = "Decrypt Filter for XOR Trojan"
6
+ s.description = "This is a Logstash Filter to be installed on a logstash instance"
7
+ s.authors = ["Silvan Adrian, Fabian Binna"]
8
+ s.email = 'silvan.adrian@gmail.com'
9
+ s.homepage = ""
10
+ s.require_paths = ["lib"]
11
+
12
+ # Files
13
+ s.files = Dir['lib/**/*','spec/**/*','vendor/**/*','*.gemspec','*.md','CONTRIBUTORS','Gemfile','LICENSE','NOTICE.TXT']
14
+ # Tests
15
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
16
+
17
+ # Special flag to let us know this is actually a logstash plugin
18
+ s.metadata = { "logstash_plugin" => "true", "logstash_group" => "filter" }
19
+
20
+ # Gem dependencies
21
+ s.add_runtime_dependency "logstash-core-plugin-api", "~> 2.0"
22
+ s.add_development_dependency 'logstash-devutils' , '~> 0'
23
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require "logstash/filters/decrypt"
4
+
5
+ describe LogStash::Filters::Decrypt do
6
+ describe "Set to Hello World" do
7
+ let(:config) do <<-CONFIG
8
+ filter {
9
+ decrypt {
10
+ message => "Hello World"
11
+ }
12
+ }
13
+ CONFIG
14
+ end
15
+
16
+ sample("message" => "some text") do
17
+ expect(subject.get("message")).to eq('Hello World')
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logstash-filter-decrypt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Silvan Adrian, Fabian Binna
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-03-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: logstash-core-plugin-api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: logstash-devutils
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: This is a Logstash Filter to be installed on a logstash instance
42
+ email: silvan.adrian@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - CHANGELOG.md
48
+ - CONTRIBUTORS
49
+ - DEVELOPER.md
50
+ - Gemfile
51
+ - LICENSE
52
+ - NOTICE.TXT
53
+ - README.md
54
+ - lib/logstash/filters/aes.rb
55
+ - lib/logstash/filters/cipher.rb
56
+ - lib/logstash/filters/decrypt.rb
57
+ - lib/logstash/filters/xor.rb
58
+ - logstash-filter-decrypt.gemspec
59
+ - spec/filters/decrypt_spec.rb
60
+ - spec/spec_helper.rb
61
+ homepage: ''
62
+ licenses:
63
+ - Apache License (2.0)
64
+ metadata:
65
+ logstash_plugin: 'true'
66
+ logstash_group: filter
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 2.6.4
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: Decrypt Filter for XOR Trojan
87
+ test_files:
88
+ - spec/filters/decrypt_spec.rb
89
+ - spec/spec_helper.rb