rogue_one 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a8a159994892e276c84f9854aea0d1bb1ed915da4d1441e362cd3df81967a029
4
- data.tar.gz: aeb889e5a15df10f85822fc78fb285a55f86268f7a6287e34f604698172ad0b0
3
+ metadata.gz: da6511f3f76c39a222c7b41458dd08675358923709006f56452e966369f166c9
4
+ data.tar.gz: 99ecea46070225babfb4c2b5f9d51da679a026afb22a443cadb6939e7507b697
5
5
  SHA512:
6
- metadata.gz: 2d49d2e63096010fae8beb77c5b0ff0eadcb83b350663a7f048a5f2402378b65ee99bd91ba83c6659a0cac87250d91c4a377d0c1a1f5e924e74b7aa4af670472
7
- data.tar.gz: 52f2ea2c904088b2f3c817653427e4d92ca04e1584a11754163a5ade8ee6a5075d4350e5fde3468cb87dc865caadcc6acc3de3edd98005d89dd5386214ed9505
6
+ metadata.gz: 7436a460f227a78b52d6bf57d85ac6e1f1b929f3b675aa02423f8cc5dc89a071cf01dc639e9ae20b688cb350bd99ec3cfef54332a07c56007b1364d82f96daab
7
+ data.tar.gz: 053b1f8f9a5c6eb5bf8b10654899bf7a41e106fa7fe412ce4e1fd27ad1917efd822a121464ba873ec698ea7d424d553cde8e85cd2f0ca53d26dd6cf11ac26b63
data/README.md CHANGED
@@ -1,9 +1,22 @@
1
- # Rogue one: a rogue DNS detector
1
+ # Rogue one
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/rogue_one.svg)](https://badge.fury.io/rb/rogue_one)
4
4
  [![Build Status](https://travis-ci.org/ninoseki/rogue_one.svg?branch=master)](https://travis-ci.org/ninoseki/rogue_one)
5
+ [![CodeFactor](https://www.codefactor.io/repository/github/ninoseki/rogue_one/badge)](https://www.codefactor.io/repository/github/ninoseki/rogue_one)
5
6
  [![Coverage Status](https://coveralls.io/repos/github/ninoseki/rogue_one/badge.svg?branch=master)](https://coveralls.io/github/ninoseki/rogue_one?branch=master)
6
7
 
8
+ A tiny tool for detecting a rogue DNS server and extracting landing pages from the rogue DNS server.
9
+
10
+ ## How it works
11
+
12
+ ![image](./images/eyecatch.png)
13
+
14
+ IPv4 space is vast. But an attacker could secure a few numbers of IP addresses for landing pages.
15
+ It means you can (probably) find malicious landing pages by using the following methods.
16
+
17
+ - Resolving a bunch of domains by using a rogue DNS.
18
+ - Finding frequent IPv4s from the resolutions. They might be landing pages.
19
+
7
20
  ## Installation
8
21
 
9
22
  ```bash
@@ -18,6 +31,16 @@ Commands:
18
31
  rogue_one help [COMMAND] # Describe available commands or one specific command
19
32
  rogue_one report [DNS_SERVER] # Show a report of a given DNS server
20
33
 
34
+ $ rogue_one help report
35
+ Usage:
36
+ rogue_one report [DNS_SERVER]
37
+
38
+ Options:
39
+ [--custom-list=CUSTOM_LIST] # A path to a custom list of domains
40
+ [--verbose], [--no-verbose]
41
+
42
+ Show a report of a given DNS server
43
+
21
44
  $ rogue_one report 1.1.1.1
22
45
  {
23
46
  "verdict": "benign one",
@@ -35,12 +58,23 @@ $ rogue_one report 1.53.252.215
35
58
  "61.230.102.66"
36
59
  ]
37
60
  }
61
+
62
+ $ rogue_one report 171.244.3.111 --custom-list tmp/roaming.yml
63
+ {
64
+ "verdict": "rogue one",
65
+ "landing_pages": [
66
+ "154.223.53.53",
67
+ "58.82.243.9"
68
+ ]
69
+ }
70
+ # Note: a custom list should be an array of domains in YAML format.
38
71
  ```
39
72
 
40
- | Key | Desc. |
41
- |---------------|--------------------------------------------------|
42
- | verdict | A detection result (`rogue one` or `benign one`) |
43
- | landing_pages | An array of IP of landing pages |
73
+ | Key | Desc. |
74
+ |---------------|--------------------------------------------------------------------------|
75
+ | verdict | A detection result (`rogue one` or `benign one`) |
76
+ | landing_pages | An array of IP of landing pages |
77
+ | results | DNS resolution results (only available if --verbose option is specified) |
44
78
 
45
79
  ## Notes
46
80
 
Binary file
@@ -2,6 +2,8 @@
2
2
 
3
3
  require "rogue_one/version"
4
4
 
5
+ require "rogue_one/domain_list"
6
+
5
7
  require "rogue_one/resolver"
6
8
  require "rogue_one/detector"
7
9
  require "rogue_one/ping"
@@ -6,11 +6,15 @@ require "json"
6
6
  module RogueOne
7
7
  class CLI < Thor
8
8
  desc "report [DNS_SERVER]", "Show a report of a given DNS server"
9
+ method_option :custom_list, type: :string, desc: "A path to a custom list of domains"
10
+ method_option :verbose, type: :boolean
9
11
  def report(dns_server)
10
12
  with_error_handling do
11
13
  Ping.pong? dns_server
12
14
 
13
- detector = Detector.new(target: dns_server)
15
+ custom_list = options["custom_list"]
16
+ verbose = options["verbose"]
17
+ detector = Detector.new(target: dns_server, custom_list: custom_list, verbose: verbose)
14
18
  puts JSON.pretty_generate(detector.report)
15
19
  end
16
20
  end
@@ -6,18 +6,24 @@ require "parallel"
6
6
  module RogueOne
7
7
  class Detector
8
8
  attr_reader :target
9
+ attr_reader :custom_list
10
+ attr_reader :verbose
9
11
 
10
12
  GOOGLE_PUBLIC_DNS = "8.8.8.8"
11
13
 
12
- def initialize(target:)
14
+ def initialize(target:, custom_list: nil, verbose: false)
13
15
  @target = target
16
+ @custom_list = custom_list
17
+ @verbose = verbose
18
+
14
19
  @memo = {}
20
+ @verbose_memo = nil
15
21
  end
16
22
 
17
23
  def report
18
24
  inspect
19
25
 
20
- { verdict: verdict, landing_pages: landing_pages }
26
+ { verdict: verdict, landing_pages: landing_pages, results: results }.compact
21
27
  end
22
28
 
23
29
  private
@@ -30,27 +36,49 @@ module RogueOne
30
36
  !landing_pages.empty?
31
37
  end
32
38
 
39
+ def threshold
40
+ @threshold ||= (domains.length.to_f / 10.0).ceil
41
+ end
42
+
33
43
  def landing_pages
34
44
  @memo.map do |ip, count|
35
- count > 10 ? ip : nil
45
+ count > threshold ? ip : nil
36
46
  end.compact.sort
37
47
  end
38
48
 
49
+ def results
50
+ @verbose_memo
51
+ end
52
+
39
53
  def inspect
40
54
  return unless @memo.empty?
41
55
 
42
- results = Parallel.map(top_100_domains) do |domain|
56
+ results = Parallel.map(domains) do |domain|
43
57
  normal_result = normal_resolver.dig(domain, "A")
44
58
  target_result = target_resolver.dig(domain, "A")
45
59
 
46
- target_result if target_result && normal_result != target_result
47
- end.compact
60
+ [domain, target_result] if target_result && normal_result != target_result
61
+ end.compact.to_h
48
62
 
49
- @memo = results.group_by(&:itself).map { |k, v| [k, v.length] }.to_h
63
+ @memo = results.values.group_by(&:itself).map { |k, v| [k, v.length] }.to_h
64
+ @verbose_memo = results if verbose
65
+ end
66
+
67
+ def domains
68
+ @domains ||= custom_domains || top_100_domains
69
+ end
70
+
71
+ def custom_domains
72
+ read_domains custom_list
50
73
  end
51
74
 
52
75
  def top_100_domains
53
- @top_100_domains ||= YAML.safe_load(File.read(File.expand_path("./data/top_100.yml", __dir__)))
76
+ read_domains File.expand_path("./data/top_100.yml", __dir__)
77
+ end
78
+
79
+ def read_domains(path)
80
+ list = DomainList.new(path)
81
+ list.valid? ? list.domains : nil
54
82
  end
55
83
 
56
84
  def normal_resolver
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+
5
+ module RogueOne
6
+ class DomainList
7
+ attr_reader :path
8
+
9
+ def initialize(path)
10
+ @path = path.to_s
11
+ end
12
+
13
+ def valid?
14
+ exists? && valid_format?
15
+ end
16
+
17
+ def domains
18
+ @domains ||= exists? ? YAML.safe_load(File.read(path)) : nil
19
+ end
20
+
21
+ private
22
+
23
+ def exists?
24
+ File.exist?(path)
25
+ end
26
+
27
+ def valid_format?
28
+ domains.is_a? Array
29
+ end
30
+ end
31
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RogueOne
4
- VERSION = "0.1.4"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -26,9 +26,9 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  spec.add_development_dependency "bundler", "~> 2.0"
28
28
  spec.add_development_dependency "coveralls", "~> 0.8"
29
- spec.add_development_dependency "rake", "~> 12.3"
30
- spec.add_development_dependency "rspec", "~> 3.8"
29
+ spec.add_development_dependency "rake", "~> 13.0"
30
+ spec.add_development_dependency "rspec", "~> 3.9"
31
31
 
32
- spec.add_dependency "parallel", "~> 1.17"
33
- spec.add_dependency "thor", "~> 0.19"
32
+ spec.add_dependency "parallel", "~> 1.18"
33
+ spec.add_dependency "thor", "~> 0.20"
34
34
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rogue_one
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manabu Niseki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-06-09 00:00:00.000000000 Z
11
+ date: 2019-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,56 +44,56 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '12.3'
47
+ version: '13.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: '12.3'
54
+ version: '13.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '3.8'
61
+ version: '3.9'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '3.8'
68
+ version: '3.9'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: parallel
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '1.17'
75
+ version: '1.18'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '1.17'
82
+ version: '1.18'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: thor
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0.19'
89
+ version: '0.20'
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0.19'
96
+ version: '0.20'
97
97
  description: 'Rogue one: a rogue DNS detector'
98
98
  email:
99
99
  - manabu.niseki@gmail.com
@@ -112,10 +112,12 @@ files:
112
112
  - bin/console
113
113
  - bin/setup
114
114
  - exe/rogue_one
115
+ - images/eyecatch.png
115
116
  - lib/rogue_one.rb
116
117
  - lib/rogue_one/cli.rb
117
118
  - lib/rogue_one/data/top_100.yml
118
119
  - lib/rogue_one/detector.rb
120
+ - lib/rogue_one/domain_list.rb
119
121
  - lib/rogue_one/ping.rb
120
122
  - lib/rogue_one/resolver.rb
121
123
  - lib/rogue_one/version.rb
@@ -139,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
141
  - !ruby/object:Gem::Version
140
142
  version: '0'
141
143
  requirements: []
142
- rubygems_version: 3.0.2
144
+ rubygems_version: 3.0.3
143
145
  signing_key:
144
146
  specification_version: 4
145
147
  summary: 'Rogue one: a rogue DNS detector'