aoandon 0.0.5 → 0.0.6
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 +5 -5
- data/LICENSE.md +17 -18
- data/README.md +47 -21
- data/bin/aoandon +2 -1
- data/lib/aoandon.rb +25 -24
- data/lib/aoandon/analysis.rb +5 -3
- data/lib/aoandon/analysis/semantic.rb +7 -9
- data/lib/aoandon/analysis/syntax.rb +23 -23
- data/lib/aoandon/dynamic_rule/less1024.rb +5 -5
- data/lib/aoandon/log.rb +8 -6
- data/lib/aoandon/static_rule.rb +8 -6
- metadata +91 -34
- data/.gitattributes +0 -10
- data/.gitignore +0 -20
- data/.ruby-version +0 -1
- data/Gemfile +0 -2
- data/Rakefile +0 -7
- data/VERSION.semver +0 -1
- data/aoandon.gemspec +0 -21
- data/config/rules.yml +0 -54
- data/lib/aoandon/error/not_implemented_error.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d60b2d838c6206b56aae170861b9d40aebd5b2c4d5f857b0d53f7ef5fdce5ca9
|
4
|
+
data.tar.gz: 119c1e89887f10c8ec64554357f9e0e74f1c82e6b8c3703450c29fc81da9c3b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 562da47deae49df1c8b8d9ddf41647fc902e67235e4876ea29479d136dafd9d6e303b8280dfca90266365916c37800f768f2371d470571b4f1b8ed9e368fe0c2
|
7
|
+
data.tar.gz: b5b623f88e1af383901b7ae3c85a7d91876076537a9bc09bd82a4471adc51ca390c7b5d68c481d4743a525b95a6ce476bb8182f62d98736d3261ad1e412c6b62
|
data/LICENSE.md
CHANGED
@@ -1,22 +1,21 @@
|
|
1
|
-
|
1
|
+
The MIT License (MIT)
|
2
2
|
|
3
|
-
|
3
|
+
Copyright (c) 2012-2021 Cyril Kato
|
4
4
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
the following conditions:
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
12
11
|
|
13
|
-
The above copyright notice and this permission notice shall be
|
14
|
-
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
15
14
|
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
OF
|
22
|
-
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -2,37 +2,63 @@
|
|
2
2
|
|
3
3
|
<span lang="ja"><ruby>青<rt>ao</rt>行燈<rt>andon</rt></ruby></span> is a minimalist network intrusion detection system (NIDS).
|
4
4
|
|
5
|
-

|
6
6
|
|
7
7
|
## Status
|
8
8
|
|
9
|
-
|
9
|
+
[](https://badge.fury.io/rb/aoandon)
|
10
|
+
[](https://travis-ci.org/cyril/aoandon.rb)
|
11
|
+
[](https://inch-ci.org/github/cyril/aoandon.rb)
|
12
|
+

|
10
13
|
|
11
14
|
## Installation
|
12
15
|
|
13
16
|
Add this line to your application's Gemfile:
|
14
17
|
|
15
|
-
|
18
|
+
```ruby
|
19
|
+
gem "aoandon"
|
20
|
+
```
|
16
21
|
|
17
22
|
And then execute:
|
18
23
|
|
19
|
-
|
24
|
+
```sh
|
25
|
+
bundle
|
26
|
+
```
|
20
27
|
|
21
28
|
Or install it yourself as:
|
22
29
|
|
23
|
-
|
30
|
+
```sh
|
31
|
+
gem install accept_language
|
32
|
+
```
|
24
33
|
|
25
34
|
## Getting started
|
26
35
|
|
27
|
-
|
28
|
-
|
29
|
-
|
36
|
+
To start, let's look at the machine's network interfaces in console:
|
37
|
+
|
38
|
+
```sh
|
39
|
+
ifconfig
|
40
|
+
```
|
41
|
+
|
42
|
+
And let's display the help menu:
|
43
|
+
|
44
|
+
```sh
|
45
|
+
aoandon -h
|
46
|
+
```
|
47
|
+
|
48
|
+
Usage: aoandon [options]
|
30
49
|
-f, --file <path> Load the rules contained in file <path>.
|
31
50
|
-h, --help Help.
|
32
51
|
-i, --interface <if> Sniff on network interface <if>.
|
33
52
|
-v, --verbose Produce more verbose output.
|
34
53
|
-V, --version Show the version number and exit.
|
35
|
-
|
54
|
+
Stopping Aoandon NIDS... done.
|
55
|
+
|
56
|
+
Now, let's start scanning the network traffic on the machine's en0 network interface:
|
57
|
+
|
58
|
+
```sh
|
59
|
+
sudo aoandon -i en0 -v
|
60
|
+
```
|
61
|
+
|
36
62
|
Starting Aoandon NIDS on interface en0...
|
37
63
|
Log file: /var/log/aoandon.yml
|
38
64
|
Ruleset: /Users/bob/code/aoandon.rb/config/rules.yml
|
@@ -189,13 +215,13 @@ Some semantic analysis can also be done through Aoandon NIDS extensions, using m
|
|
189
215
|
module Aoandon
|
190
216
|
module DynamicRule
|
191
217
|
module Less1024
|
192
|
-
MESSAGE =
|
218
|
+
MESSAGE = "Port numbers < 1024"
|
193
219
|
PROTO_TCP = 6
|
194
220
|
PROTO_UDP = 17
|
195
221
|
WELL_KNOWN_PORTS = (0..1023)
|
196
222
|
|
197
223
|
def self.control?(packet)
|
198
|
-
(tcp?(packet) || (udp?(packet) && different_ports?(packet.sport, packet.dport))) &&
|
224
|
+
(tcp?(packet) || (udp?(packet) && different_ports?(packet.sport, packet.dport))) &&
|
199
225
|
less_1024?(packet.sport) && less_1024?(packet.dport)
|
200
226
|
end
|
201
227
|
|
@@ -230,7 +256,7 @@ end
|
|
230
256
|
module Aoandon
|
231
257
|
module DynamicRule
|
232
258
|
module MoreFragments
|
233
|
-
MESSAGE =
|
259
|
+
MESSAGE = "More Fragment bit is set"
|
234
260
|
|
235
261
|
def self.control?(packet)
|
236
262
|
packet.ip_mf?
|
@@ -249,8 +275,8 @@ end
|
|
249
275
|
module Aoandon
|
250
276
|
module DynamicRule
|
251
277
|
module SameIp
|
252
|
-
LOCALHOST =
|
253
|
-
MESSAGE =
|
278
|
+
LOCALHOST = "127.0.0.1"
|
279
|
+
MESSAGE = "Same IP"
|
254
280
|
|
255
281
|
def self.control?(packet)
|
256
282
|
packet.ip_src == packet.ip_dst && !loopback?(packet.ip_src)
|
@@ -276,7 +302,7 @@ module Aoandon
|
|
276
302
|
module DynamicRule
|
277
303
|
module SynFlood
|
278
304
|
BUFFER = 20
|
279
|
-
MESSAGE =
|
305
|
+
MESSAGE = "SYN flood attack"
|
280
306
|
PROTO_TCP = 6
|
281
307
|
|
282
308
|
def self.control?(packet)
|
@@ -310,10 +336,10 @@ module Aoandon
|
|
310
336
|
end
|
311
337
|
```
|
312
338
|
|
313
|
-
##
|
339
|
+
## Versioning
|
340
|
+
|
341
|
+
__Aoandon__ uses [Semantic Versioning 2.0.0](https://semver.org/)
|
342
|
+
|
343
|
+
## License
|
314
344
|
|
315
|
-
|
316
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
317
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
318
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
319
|
-
5. Create a new Pull Request
|
345
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/bin/aoandon
CHANGED
data/lib/aoandon.rb
CHANGED
@@ -1,23 +1,24 @@
|
|
1
|
-
|
2
|
-
require 'optparse'
|
3
|
-
require 'pcap'
|
4
|
-
require 'time'
|
5
|
-
require 'yaml'
|
1
|
+
# frozen_string_literal: false
|
6
2
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
require_relative 'aoandon/static_rule'
|
3
|
+
require "ipaddr"
|
4
|
+
require "optparse"
|
5
|
+
require "pcap"
|
6
|
+
require "time"
|
7
|
+
require "yaml"
|
13
8
|
|
14
|
-
|
9
|
+
require_relative "aoandon/analysis"
|
10
|
+
require_relative "aoandon/analysis/semantic"
|
11
|
+
require_relative "aoandon/analysis/syntax"
|
12
|
+
require_relative "aoandon/log"
|
13
|
+
require_relative "aoandon/static_rule"
|
14
|
+
|
15
|
+
Dir["lib/aoandon/dynamic_rule/*.rb"].each do |src|
|
15
16
|
load src
|
16
17
|
end
|
17
18
|
|
18
19
|
module Aoandon
|
19
20
|
class Nids
|
20
|
-
CONF_PATH =
|
21
|
+
CONF_PATH = "config/rules.yml"
|
21
22
|
|
22
23
|
def initialize
|
23
24
|
options = Nids.parse
|
@@ -25,13 +26,13 @@ module Aoandon
|
|
25
26
|
options[:interface] = Pcap.lookupdev unless options[:interface]
|
26
27
|
puts "Starting Aoandon NIDS on interface #{options[:interface]}..."
|
27
28
|
log = Log.new(options[:verbose])
|
28
|
-
@syntax = Syntax.new(log, {file: options[:file]})
|
29
|
+
@syntax = Syntax.new(log, { file: options[:file] })
|
29
30
|
@semantic = Semantic.new(log)
|
30
31
|
@network_interface = Pcap::Capture.open_live(options[:interface])
|
31
32
|
end
|
32
33
|
|
33
34
|
def run
|
34
|
-
puts
|
35
|
+
puts "You can stop Aoandon NIDS by pressing Ctrl-C."
|
35
36
|
|
36
37
|
@network_interface.each_packet do |packet|
|
37
38
|
if packet.ip?
|
@@ -47,12 +48,12 @@ module Aoandon
|
|
47
48
|
options = {}
|
48
49
|
|
49
50
|
OptionParser.new do |opts|
|
50
|
-
opts.banner = "Usage:
|
51
|
-
opts.on(
|
52
|
-
opts.on(
|
53
|
-
opts.on(
|
54
|
-
opts.on(
|
55
|
-
opts.on(
|
51
|
+
opts.banner = "Usage: #{$0} [options]"
|
52
|
+
opts.on("-f", "--file <path>", "Load the rules contained in file <path>.") { |f| options[:file] = f }
|
53
|
+
opts.on("-h", "--help", "Help.") { puts opts; exit }
|
54
|
+
opts.on("-i", "--interface <if>", "Sniff on network interface <if>.") { |i| options[:interface] = i }
|
55
|
+
opts.on("-v", "--verbose", "Produce more verbose output.") { options[:verbose] = true }
|
56
|
+
opts.on("-V", "--version", "Show the version number and exit.") { version; exit }
|
56
57
|
end.parse!
|
57
58
|
|
58
59
|
options
|
@@ -62,8 +63,8 @@ module Aoandon
|
|
62
63
|
puts "Aoandon #{VERSION}"
|
63
64
|
end
|
64
65
|
|
65
|
-
trap(
|
66
|
-
at_exit { print
|
67
|
-
ObjectSpace.define_finalizer(
|
66
|
+
trap("INT") { exit }
|
67
|
+
at_exit { print "Stopping Aoandon NIDS... " }
|
68
|
+
ObjectSpace.define_finalizer("string", proc { puts "done." })
|
68
69
|
end
|
69
70
|
end
|
data/lib/aoandon/analysis.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Aoandon
|
2
4
|
class Analysis
|
3
|
-
def initialize(logger,
|
5
|
+
def initialize(logger, _options = {})
|
4
6
|
@logger = logger
|
5
7
|
end
|
6
8
|
|
7
|
-
def update(
|
8
|
-
raise NotImplementedError,
|
9
|
+
def update(_packet = "")
|
10
|
+
raise NotImplementedError, "Must subclass me"
|
9
11
|
end
|
10
12
|
end
|
11
13
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Aoandon
|
2
4
|
class Semantic < Analysis
|
3
5
|
def initialize(logger, options = {})
|
@@ -9,16 +11,12 @@ module Aoandon
|
|
9
11
|
def test(packet)
|
10
12
|
if defined? DynamicRule
|
11
13
|
DynamicRule.constants.each do |rule|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
else
|
17
|
-
nil
|
18
|
-
end
|
14
|
+
next unless DynamicRule.const_get(rule).control?(packet)
|
15
|
+
|
16
|
+
dump = DynamicRule.const_get(rule).logging?(packet) ? packet : nil
|
17
|
+
message = (DynamicRule.const_get(rule)::MESSAGE if DynamicRule.const_get(rule).constants.include?(:MESSAGE))
|
19
18
|
|
20
|
-
|
21
|
-
end
|
19
|
+
@logger.message(packet.time.iso8601, "SEMANT", rule.downcase, message, dump)
|
22
20
|
end
|
23
21
|
end
|
24
22
|
end
|
@@ -1,40 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Aoandon
|
2
4
|
class Syntax < Analysis
|
3
5
|
def initialize(logger, options = {})
|
4
6
|
super(logger, options)
|
5
7
|
|
6
8
|
abort("Configuration file not found: #{options[:file]}") unless File.exist?(options[:file])
|
7
|
-
@rules = Array(YAML
|
9
|
+
@rules = Array(YAML.load_file(options[:file])["rules"]).map { |rule| StaticRule.new(*rule) }
|
8
10
|
|
9
11
|
puts "Ruleset: #{File.expand_path(options[:file])}"
|
10
12
|
end
|
11
13
|
|
12
14
|
def test(packet)
|
13
15
|
@rules.each do |rule|
|
14
|
-
if match?(packet, rule.context)
|
15
|
-
break if (@last_rule = rule).options['quick']
|
16
|
-
end
|
16
|
+
break if match?(packet, rule.context) && (@last_rule = rule).options["quick"]
|
17
17
|
end
|
18
18
|
|
19
|
-
if @last_rule && @last_rule.action !=
|
20
|
-
message = @last_rule.options[
|
21
|
-
dump = @last_rule.options[
|
22
|
-
@logger.message(packet.time.iso8601,
|
19
|
+
if @last_rule && @last_rule.action != "pass"
|
20
|
+
message = @last_rule.options["msg"] || "Bad packet detected!"
|
21
|
+
dump = @last_rule.options["log"] ? packet : nil
|
22
|
+
@logger.message(packet.time.iso8601, "SYNTAX", @last_rule.action, message, dump)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
protected
|
27
27
|
|
28
28
|
def match?(packet, network_context)
|
29
|
-
network_context.update({
|
30
|
-
match_proto?(packet, network_context) if packet.ip_ver == af(network_context.fetch(
|
29
|
+
network_context.update({ "af" => af2id(packet.ip_ver) }) unless network_context.has_key?("af")
|
30
|
+
match_proto?(packet, network_context) if packet.ip_ver == af(network_context.fetch("af"))
|
31
31
|
end
|
32
32
|
|
33
33
|
def af2id(af)
|
34
34
|
if af == 4
|
35
|
-
|
35
|
+
"inet"
|
36
36
|
elsif af == 6
|
37
|
-
|
37
|
+
"inet6"
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -47,8 +47,8 @@ module Aoandon
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def match_proto?(packet, network_context)
|
50
|
-
if network_context[
|
51
|
-
if packet.ip_proto == proto(network_context[
|
50
|
+
if network_context["proto"]
|
51
|
+
if packet.ip_proto == proto(network_context["proto"])
|
52
52
|
if packet.ip_proto == 1
|
53
53
|
match_proto_icmp?(packet, network_context)
|
54
54
|
elsif packet.ip_proto == 6
|
@@ -89,9 +89,9 @@ module Aoandon
|
|
89
89
|
def match_addr?(packet, network_context)
|
90
90
|
result = true
|
91
91
|
|
92
|
-
[[
|
93
|
-
unless network_context[way].fetch(
|
94
|
-
result
|
92
|
+
[%w[from src], %w[to dst]].each do |way, obj|
|
93
|
+
unless network_context[way].fetch("addr") == "any"
|
94
|
+
result &&= refer2addr?(packet.send(obj), network_context[way].fetch("addr"))
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
@@ -101,9 +101,9 @@ module Aoandon
|
|
101
101
|
def match_port?(packet, network_context)
|
102
102
|
result = true
|
103
103
|
|
104
|
-
[[
|
105
|
-
if network_context[way].has_key?(
|
106
|
-
result
|
104
|
+
[%w[from sport], %w[to dport]].each do |way, obj|
|
105
|
+
if network_context[way].has_key?("port")
|
106
|
+
result &&= refer2port?(packet.send(obj).to_i, network_context[way].fetch("port"))
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
@@ -111,9 +111,9 @@ module Aoandon
|
|
111
111
|
end
|
112
112
|
|
113
113
|
def match_flag?(packet, network_context)
|
114
|
-
return true unless network_context[
|
114
|
+
return true unless network_context["flags"]
|
115
115
|
|
116
|
-
network_context[
|
116
|
+
network_context["flags"].each do |flag|
|
117
117
|
return true if packet.send("tcp_#{flag}?")
|
118
118
|
end
|
119
119
|
|
@@ -145,7 +145,7 @@ module Aoandon
|
|
145
145
|
pattern.include?(number)
|
146
146
|
elsif pattern.is_a? Hash
|
147
147
|
pattern.has_key?(number)
|
148
|
-
elsif pattern.is_a?
|
148
|
+
elsif pattern.is_a? Integer
|
149
149
|
number == pattern
|
150
150
|
else
|
151
151
|
false
|
@@ -1,22 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Aoandon
|
2
4
|
module DynamicRule
|
3
5
|
module Less1024
|
4
|
-
MESSAGE =
|
6
|
+
MESSAGE = "Port numbers < 1024"
|
5
7
|
PROTO_TCP = 6
|
6
8
|
PROTO_UDP = 17
|
7
9
|
WELL_KNOWN_PORTS = (0..1023)
|
8
10
|
|
9
11
|
def self.control?(packet)
|
10
|
-
(tcp?(packet) || (udp?(packet) && different_ports?(packet.sport, packet.dport))) &&
|
12
|
+
(tcp?(packet) || (udp?(packet) && different_ports?(packet.sport, packet.dport))) &&
|
11
13
|
less_1024?(packet.sport) && less_1024?(packet.dport)
|
12
14
|
end
|
13
15
|
|
14
|
-
def self.logging?(
|
16
|
+
def self.logging?(_packet)
|
15
17
|
true
|
16
18
|
end
|
17
19
|
|
18
|
-
private
|
19
|
-
|
20
20
|
def self.different_ports?(src_port, dst_port)
|
21
21
|
src_port != dst_port
|
22
22
|
end
|
data/lib/aoandon/log.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Aoandon
|
2
4
|
class Log
|
3
5
|
def initialize(verbose = false)
|
4
|
-
@file = if File.exist?(
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
@file = if File.exist?("log/aoandon.yml")
|
7
|
+
File.open("log/aoandon.yml", "a")
|
8
|
+
else
|
9
|
+
File.open("/var/log/aoandon.yml", "a")
|
10
|
+
end
|
9
11
|
|
10
12
|
@verbose = verbose
|
11
13
|
|
@@ -13,7 +15,7 @@ module Aoandon
|
|
13
15
|
end
|
14
16
|
|
15
17
|
def message(*args)
|
16
|
-
puts args.compact.map(&:to_s).join(
|
18
|
+
puts args.compact.map(&:to_s).join(" | ") if @verbose
|
17
19
|
@file.puts "- #{args.compact.map(&:to_s)}"
|
18
20
|
@file.flush
|
19
21
|
end
|
data/lib/aoandon/static_rule.rb
CHANGED
@@ -1,16 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Aoandon
|
2
|
-
|
4
|
+
StaticRule = Struct.new(:action, :context, :options) do
|
3
5
|
def initialize(*args)
|
4
6
|
super(*args)
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
+
context["from"] ||= { "addr" => "any" }
|
9
|
+
context["to"] ||= { "addr" => "any" }
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
+
context["from"].update("addr" => "any") unless context["from"]["addr"]
|
12
|
+
context["to"].update("addr" => "any") unless context["to"]["addr"]
|
11
13
|
|
12
14
|
self.options ||= {}
|
13
|
-
self.options.update(
|
15
|
+
self.options.update("log" => false) unless self.options.has_key?("log")
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aoandon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Cyril
|
7
|
+
- Cyril Kato
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-pcap
|
@@ -28,70 +28,128 @@ dependencies:
|
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rubocop-md
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop-performance
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop-thread_safety
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
67
109
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: simplecov
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: yard
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
69
139
|
description: Aoandon (青行燈) is a minimalist network intrusion detection system (NIDS).
|
70
|
-
email:
|
71
|
-
|
72
|
-
executables:
|
73
|
-
- aoandon
|
140
|
+
email: contact@cyril.email
|
141
|
+
executables: []
|
74
142
|
extensions: []
|
75
143
|
extra_rdoc_files: []
|
76
144
|
files:
|
77
|
-
- ".gitattributes"
|
78
|
-
- ".gitignore"
|
79
|
-
- ".ruby-version"
|
80
|
-
- Gemfile
|
81
145
|
- LICENSE.md
|
82
146
|
- README.md
|
83
|
-
- Rakefile
|
84
|
-
- VERSION.semver
|
85
|
-
- aoandon.gemspec
|
86
147
|
- bin/aoandon
|
87
|
-
- blue-andon-creature.jpg
|
88
|
-
- config/rules.yml
|
89
148
|
- lib/aoandon.rb
|
90
149
|
- lib/aoandon/analysis.rb
|
91
150
|
- lib/aoandon/analysis/semantic.rb
|
92
151
|
- lib/aoandon/analysis/syntax.rb
|
93
152
|
- lib/aoandon/dynamic_rule/less1024.rb
|
94
|
-
- lib/aoandon/error/not_implemented_error.rb
|
95
153
|
- lib/aoandon/log.rb
|
96
154
|
- lib/aoandon/static_rule.rb
|
97
155
|
homepage: https://github.com/cyril/aoandon.rb
|
@@ -106,15 +164,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
106
164
|
requirements:
|
107
165
|
- - ">="
|
108
166
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
167
|
+
version: 2.7.0
|
110
168
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
169
|
requirements:
|
112
170
|
- - ">="
|
113
171
|
- !ruby/object:Gem::Version
|
114
172
|
version: '0'
|
115
173
|
requirements: []
|
116
|
-
|
117
|
-
rubygems_version: 2.2.2
|
174
|
+
rubygems_version: 3.1.6
|
118
175
|
signing_key:
|
119
176
|
specification_version: 4
|
120
177
|
summary: Minimalist network intrusion detection system (NIDS).
|
data/.gitattributes
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
# Set default behaviour, in case users don't have core.autocrlf set.
|
2
|
-
* text=auto
|
3
|
-
|
4
|
-
# Explicitly declare text files we want to always be normalized and converted
|
5
|
-
# to native line endings on checkout.
|
6
|
-
*.rb text
|
7
|
-
|
8
|
-
# Denote all files that are truly binary and should not be modified.
|
9
|
-
*.png binary
|
10
|
-
*.jpg binary
|
data/.gitignore
DELETED
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.1.2
|
data/Gemfile
DELETED
data/Rakefile
DELETED
data/VERSION.semver
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.0.5
|
data/aoandon.gemspec
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
Gem::Specification.new do |spec|
|
2
|
-
spec.name = 'aoandon'
|
3
|
-
spec.version = File.read('VERSION.semver')
|
4
|
-
spec.authors = ['Cyril Wack']
|
5
|
-
spec.email = ['contact@cyril.io']
|
6
|
-
spec.homepage = 'https://github.com/cyril/aoandon.rb'
|
7
|
-
spec.summary = %q{Minimalist network intrusion detection system (NIDS).}
|
8
|
-
spec.description = %q{Aoandon (青行燈) is a minimalist network intrusion detection system (NIDS).}
|
9
|
-
spec.license = 'MIT'
|
10
|
-
|
11
|
-
spec.files = `git ls-files -z`.split("\x0")
|
12
|
-
spec.executables = spec.files.grep(%r{^bin/}) {|f| File.basename(f) }
|
13
|
-
spec.test_files = spec.files.grep(%r{^test/})
|
14
|
-
spec.require_paths = ['lib']
|
15
|
-
|
16
|
-
spec.add_dependency 'ruby-pcap', '~> 0.7'
|
17
|
-
|
18
|
-
spec.add_development_dependency 'bundler', '~> 1.6'
|
19
|
-
spec.add_development_dependency 'minitest', '~> 5'
|
20
|
-
spec.add_development_dependency 'rake', '~> 10'
|
21
|
-
end
|
data/config/rules.yml
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
# Aoandon NIDS configuration file
|
2
|
-
---
|
3
|
-
#macros:
|
4
|
-
# web_server: &web_server
|
5
|
-
# 114.21.70.71
|
6
|
-
# gateway: &gw
|
7
|
-
# 192.168.0.1
|
8
|
-
|
9
|
-
#tables:
|
10
|
-
# redzone: &redzone
|
11
|
-
# - "81.15.142.23"
|
12
|
-
# hacker: &id001
|
13
|
-
# - 81.15.142.23
|
14
|
-
# - 42.154.25.213
|
15
|
-
# blacklist: &blacklist
|
16
|
-
# - *id001
|
17
|
-
# - *gw
|
18
|
-
# - 81.15.142.23
|
19
|
-
# - "64.81.240.57"
|
20
|
-
# unknown:
|
21
|
-
# - any
|
22
|
-
# mz: &mz
|
23
|
-
# 192.168.0.201
|
24
|
-
# dmz: &dmz
|
25
|
-
# sql_server: &sql_server
|
26
|
-
# 10.0.0.2
|
27
|
-
|
28
|
-
#ports:
|
29
|
-
# web: &www
|
30
|
-
# - 80
|
31
|
-
# - 443
|
32
|
-
# p2p:
|
33
|
-
# - 63192
|
34
|
-
|
35
|
-
#messages:
|
36
|
-
# - &msg001 "ICMP packet from Google to MZ"
|
37
|
-
# - &msg002 "MZ intrusion detected!"
|
38
|
-
|
39
|
-
rules:
|
40
|
-
# # "default alert" approach
|
41
|
-
# - [ info, {}, {quick: true, log: true, msg: "Suspected packet!"} ]
|
42
|
-
#
|
43
|
-
# # then, selectively ignore certain traffic
|
44
|
-
# - [ pass, {af: inet, from: {addr: any}, to: {addr: any}} ]
|
45
|
-
# - [ warn, {proto: tcp, from: {addr: *blacklist}, to: {addr: any, port: *www}, flags: syn} ]
|
46
|
-
# - [ warn, {proto: tcp, from: {addr: any, port: 123}, to: {addr: *dmz}} ]
|
47
|
-
# - [ crit, {af: inet6, from: {addr: any}, to: {addr: any}}, {log: true} ]
|
48
|
-
# - [ pass, {af: inet, proto: tcp, from: {addr: *mz}, to: {addr: *web_server, port: *www}, {quick: true}} ]
|
49
|
-
# - [ warn, {proto: udp, from: {addr: *redzone}, to: {addr: 10.1.0.32, port: 21}} ]
|
50
|
-
# - [ info, {proto: tcp, from: {addr: 172.16.0.6}, to: {addr: 192.168.0.14, port: 22}} ]
|
51
|
-
# - [ crit, {proto: tcp, from: {addr: *blacklist}, to: {addr: *mz}}, {log: true, msg: *msg002} ]
|
52
|
-
# - [ info, {proto: tcp, to: {addr: 192.168.0.14, port: 22}} ]
|
53
|
-
# - [ pass, {proto: tcp, from: {addr: *id001}, to: {addr: *sql_server, port: 3306}} ]
|
54
|
-
# - [ info, {af: inet, proto: icmp, from: {addr: google.com}, to: {addr: *mz}}, {log: true, msg: *msg001} ]
|