rogue_one 0.1.4 → 0.4.2

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: 36b1d9ea6171500c42fd1930ba0807e74d8df4908fdec5eb47f1b88b0262caf6
4
+ data.tar.gz: 3836ad7bc6a13b68e1fa07d5d584ccbe0da64c8a4c1ee31e16d8f6e5037ada7f
5
5
  SHA512:
6
- metadata.gz: 2d49d2e63096010fae8beb77c5b0ff0eadcb83b350663a7f048a5f2402378b65ee99bd91ba83c6659a0cac87250d91c4a377d0c1a1f5e924e74b7aa4af670472
7
- data.tar.gz: 52f2ea2c904088b2f3c817653427e4d92ca04e1584a11754163a5ade8ee6a5075d4350e5fde3468cb87dc865caadcc6acc3de3edd98005d89dd5386214ed9505
6
+ metadata.gz: 8659b118ceaf22a6ec4756d4f883f8bda633ddf1230aab126c2666ad967df887dd7b1fed576b2f3608ed0adefea695067030ed079b3a915af8c06b1398bd2bd0
7
+ data.tar.gz: 3c6debab123e645b9765627dda48bc5c2674ee9101f53da0c8bb967a72d54cea411213cc6b6d2354263f1034b73d75282058872779f75a1ac07ec3e5bb77a63d
@@ -4,4 +4,5 @@ language: ruby
4
4
  cache: bundler
5
5
  rvm:
6
6
  - 2.6
7
- before_install: gem install bundler -v 2.0.1
7
+ - 2.7
8
+ before_install: gem install bundler -v 2.1
data/README.md CHANGED
@@ -1,9 +1,25 @@
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
- [![Build Status](https://travis-ci.org/ninoseki/rogue_one.svg?branch=master)](https://travis-ci.org/ninoseki/rogue_one)
4
+ [![Build Status](https://travis-ci.com/ninoseki/rogue_one.svg?branch=master)](https://travis-ci.com/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 PoC tool for analyzing a rogue DNS server.
9
+
10
+ This tool could be used for checking maliciousness of a DNS server and extracting landing pages.
11
+
12
+ ## How it works
13
+
14
+ ![image](./images/eyecatch.png)
15
+
16
+ IPv4 space is vast. But an attacker could secure a few numbers of IP addresses for landing pages.
17
+ It means you can (probably) find malicious landing pages by using the following methods.
18
+
19
+ - Resolving a bunch of domains by using a DNS server.
20
+ - Finding frequent IPv4s from the resolutions. They might be landing pages.
21
+ - If a DNS server has landing pages, it might be a rogue one.
22
+
7
23
  ## Installation
8
24
 
9
25
  ```bash
@@ -18,6 +34,21 @@ Commands:
18
34
  rogue_one help [COMMAND] # Describe available commands or one specific command
19
35
  rogue_one report [DNS_SERVER] # Show a report of a given DNS server
20
36
 
37
+ $ rogue_one help report
38
+ Usage:
39
+ rogue_one report [DNS_SERVER]
40
+
41
+ Options:
42
+ [--custom-list=CUSTOM_LIST] # A path to a custom list of domains
43
+ [--default-list=DEFAULT_LIST] # A default list of top 100 domains (Alexa or Fortune)
44
+ # Default: alexa
45
+ [--record-type=RECORD_TYPE] # A type of the DNS resource to check
46
+ # Default: A
47
+ [--threshold=N] # Threshold value for determining malicious or not
48
+ [--verbose], [--no-verbose]
49
+
50
+ Show a report of a given DNS server
51
+
21
52
  $ rogue_one report 1.1.1.1
22
53
  {
23
54
  "verdict": "benign one",
@@ -35,12 +66,23 @@ $ rogue_one report 1.53.252.215
35
66
  "61.230.102.66"
36
67
  ]
37
68
  }
69
+
70
+ $ rogue_one report 171.244.3.111 --custom-list tmp/roaming.yml
71
+ {
72
+ "verdict": "rogue one",
73
+ "landing_pages": [
74
+ "154.223.53.53",
75
+ "58.82.243.9"
76
+ ]
77
+ }
78
+ # Note: a custom list should be an array of domains in YAML format.
38
79
  ```
39
80
 
40
- | Key | Desc. |
41
- |---------------|--------------------------------------------------|
42
- | verdict | A detection result (`rogue one` or `benign one`) |
43
- | landing_pages | An array of IP of landing pages |
81
+ | Key | Desc. |
82
+ |---------------|--------------------------------------------------------------------------|
83
+ | verdict | A detection result (`rogue one` or `benign one`) |
84
+ | landing_pages | An array of IP of landing pages |
85
+ | results | DNS resolution results (only available if --verbose option is specified) |
44
86
 
45
87
  ## Notes
46
88
 
Binary file
@@ -2,7 +2,8 @@
2
2
 
3
3
  require "rogue_one/version"
4
4
 
5
- require "rogue_one/resolver"
5
+ require "rogue_one/domain_list"
6
+
6
7
  require "rogue_one/detector"
7
8
  require "rogue_one/ping"
8
9
  require "rogue_one/cli"
@@ -5,12 +5,36 @@ require "json"
5
5
 
6
6
  module RogueOne
7
7
  class CLI < Thor
8
+ class << self
9
+ def exit_on_failure?
10
+ true
11
+ end
12
+ end
13
+
8
14
  desc "report [DNS_SERVER]", "Show a report of a given DNS server"
15
+ method_option :custom_list, type: :string, desc: "A path to a custom list of domains"
16
+ method_option :default_list, type: :string, default: "alexa", desc: "A default list of top 100 domains (Alexa or Fortune)"
17
+ method_option :record_type, type: :string, default: "A", desc: "A type of the DNS resource to check"
18
+ method_option :threshold, type: :numeric, desc: "Threshold value for determining malicious or not"
19
+ method_option :verbose, type: :boolean
9
20
  def report(dns_server)
10
21
  with_error_handling do
11
22
  Ping.pong? dns_server
12
23
 
13
- detector = Detector.new(target: dns_server)
24
+ custom_list = options["custom_list"]
25
+ default_list = options["default_list"].downcase
26
+ record_type = options["record_type"].upcase
27
+ threshold = options["threshold"]
28
+ verbose = options["verbose"]
29
+
30
+ detector = Detector.new(
31
+ custom_list: custom_list,
32
+ default_list: default_list,
33
+ record_type: record_type,
34
+ target: dns_server,
35
+ threshold: threshold,
36
+ verbose: verbose,
37
+ )
14
38
  puts JSON.pretty_generate(detector.report)
15
39
  end
16
40
  end
@@ -0,0 +1,101 @@
1
+ ---
2
+ - google.com
3
+ - youtube.com
4
+ - tmall.com
5
+ - baidu.com
6
+ - qq.com
7
+ - sohu.com
8
+ - facebook.com
9
+ - login.tmall.com
10
+ - wikipedia.org
11
+ - taobao.com
12
+ - yahoo.com
13
+ - jd.com
14
+ - 360.cn
15
+ - amazon.com
16
+ - sina.com.cn
17
+ - weibo.com
18
+ - pages.tmall.com
19
+ - reddit.com
20
+ - live.com
21
+ - vk.com
22
+ - okezone.com
23
+ - netflix.com
24
+ - blogspot.com
25
+ - office.com
26
+ - csdn.net
27
+ - alipay.com
28
+ - xinhuanet.com
29
+ - stackoverflow.com
30
+ - yahoo.co.jp
31
+ - instagram.com
32
+ - google.com.hk
33
+ - aliexpress.com
34
+ - microsoft.com
35
+ - babytree.com
36
+ - naver.com
37
+ - twitter.com
38
+ - bing.com
39
+ - livejasmin.com
40
+ - amazon.co.jp
41
+ - tribunnews.com
42
+ - ebay.com
43
+ - salesforce.com
44
+ - twitch.tv
45
+ - google.co.in
46
+ - force.com
47
+ - microsoftonline.com
48
+ - apple.com
49
+ - tianya.cn
50
+ - adobe.com
51
+ - pornhub.com
52
+ - msn.com
53
+ - zhanqi.tv
54
+ - dropbox.com
55
+ - linkedin.com
56
+ - yandex.ru
57
+ - wordpress.com
58
+ - myshopify.com
59
+ - amazon.in
60
+ - mail.ru
61
+ - panda.tv
62
+ - imdb.com
63
+ - caijing.com.cn
64
+ - china.com.cn
65
+ - mama.cn
66
+ - amazonaws.com
67
+ - google.com.br
68
+ - trello.com
69
+ - bongacams.com
70
+ - google.de
71
+ - medium.com
72
+ - google.co.jp
73
+ - soso.com
74
+ - booking.com
75
+ - w3schools.com
76
+ - amazon.co.uk
77
+ - spotify.com
78
+ - amazon.de
79
+ - rednet.cn
80
+ - bbc.com
81
+ - detail.tmall.com
82
+ - xvideos.com
83
+ - espn.com
84
+ - detik.com
85
+ - github.com
86
+ - cnn.com
87
+ - instructure.com
88
+ - ok.ru
89
+ - indeed.com
90
+ - yy.com
91
+ - tumblr.com
92
+ - huanqiu.com
93
+ - stackexchange.com
94
+ - nytimes.com
95
+ - imgur.com
96
+ - soundcloud.com
97
+ - whatsapp.com
98
+ - rakuten.co.jp
99
+ - nih.gov
100
+ - sogou.com
101
+ - google.cn
@@ -0,0 +1,101 @@
1
+ ---
2
+ - walmart.com
3
+ - exxonmobil.com
4
+ - berkshirehathaway.com
5
+ - apple.com
6
+ - unitedhealthgroup.com
7
+ - mckesson.com
8
+ - cvshealth.com
9
+ - amazon.com
10
+ - att.com
11
+ - gm.com
12
+ - ford.com
13
+ - amerisourcebergen.com
14
+ - chevron.com
15
+ - cardinalhealth.com
16
+ - costco.com
17
+ - verizon.com
18
+ - kroger.com
19
+ - ge.com
20
+ - walgreensbootsalliance.com
21
+ - jpmorganchase.com
22
+ - fanniemae.com
23
+ - abc.xyz
24
+ - homedepot.com
25
+ - bankofamerica.com
26
+ - express-scripts.com
27
+ - wellsfargo.com
28
+ - boeing.com
29
+ - phillips66.com
30
+ - antheminc.com
31
+ - microsoft.com
32
+ - valero.com
33
+ - citigroup.com
34
+ - comcastcorporation.com
35
+ - ibm.com
36
+ - delltechnologies.com
37
+ - statefarm.com
38
+ - jnj.com
39
+ - freddiemac.com
40
+ - target.com
41
+ - lowes.com
42
+ - marathonpetroleum.com
43
+ - pg.com
44
+ - metlife.com
45
+ - ups.com
46
+ - pepsico.com
47
+ - intel.com
48
+ - dow-dupont.com
49
+ - adm.com
50
+ - aetna.com
51
+ - fedex.com
52
+ - utc.com
53
+ - prudential.com
54
+ - albertsons.com
55
+ - sysco.com
56
+ - disney.com
57
+ - humana.com
58
+ - pfizer.com
59
+ - hp.com
60
+ - lockheedmartin.com
61
+ - aig.com
62
+ - centene.com
63
+ - cisco.com
64
+ - hcahealthcare.com
65
+ - energytransfer.com
66
+ - caterpillar.com
67
+ - nationwide.com
68
+ - morganstanley.com
69
+ - libertymutual.com
70
+ - newyorklife.com
71
+ - gs.com
72
+ - aa.com
73
+ - bestbuy.com
74
+ - cigna.com
75
+ - charter.com
76
+ - delta.com
77
+ - facebook.com
78
+ - honeywell.com
79
+ - merck.com
80
+ - allstate.com
81
+ - tysonfoods.com
82
+ - united.com
83
+ - oracle.com
84
+ - techdata.com
85
+ - tiaa.org
86
+ - tjx.com
87
+ - americanexpress.com
88
+ - coca-colacompany.com
89
+ - publix.com
90
+ - nike.com
91
+ - andeavor.com
92
+ - wfscorp.com
93
+ - exeloncorp.com
94
+ - massmutual.com
95
+ - riteaid.com
96
+ - conocophillips.com
97
+ - chsinc.com
98
+ - 3m.com
99
+ - timewarner.com
100
+ - generaldynamics.com
101
+ - usaa.com
@@ -1,23 +1,53 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "async"
4
+ require "async/barrier"
5
+ require "async/dns"
6
+ require "async/reactor"
7
+ require "async/semaphore"
8
+ require "resolv"
3
9
  require "yaml"
4
- require "parallel"
10
+ require "etc"
5
11
 
6
12
  module RogueOne
7
13
  class Detector
14
+ attr_reader :custom_list
15
+ attr_reader :default_list
16
+ attr_reader :max_concurrency
17
+ attr_reader :record_type
8
18
  attr_reader :target
19
+ attr_reader :verbose
9
20
 
10
21
  GOOGLE_PUBLIC_DNS = "8.8.8.8"
11
22
 
12
- def initialize(target:)
23
+ def initialize(target:,
24
+ custom_list: nil,
25
+ default_list: "alexa",
26
+ record_type: "A",
27
+ threshold: nil,
28
+ verbose: false)
13
29
  @target = target
30
+
31
+ @custom_list = custom_list
32
+ @default_list = default_list
33
+ @record_type = record_type.upcase.to_sym
34
+ @threshold = threshold
35
+ @verbose = verbose
36
+
37
+ @max_concurrency = Etc.nprocessors * 2
14
38
  @memo = {}
39
+ @verbose_memo = nil
15
40
  end
16
41
 
17
42
  def report
18
43
  inspect
19
44
 
20
- { verdict: verdict, landing_pages: landing_pages }
45
+ {
46
+ verdict: verdict,
47
+ landing_pages: landing_pages,
48
+ results: results,
49
+ meta: meta
50
+ }.compact
21
51
  end
22
52
 
23
53
  private
@@ -30,35 +60,129 @@ module RogueOne
30
60
  !landing_pages.empty?
31
61
  end
32
62
 
63
+ def threshold
64
+ @threshold ||= (domains.length.to_f / 10.0).ceil
65
+ end
66
+
67
+ def meta
68
+ return nil unless verbose
69
+
70
+ {
71
+ record_type: record_type,
72
+ threshold: threshold,
73
+ }
74
+ end
75
+
33
76
  def landing_pages
34
77
  @memo.map do |ip, count|
35
- count > 10 ? ip : nil
78
+ count > threshold ? ip : nil
36
79
  end.compact.sort
37
80
  end
38
81
 
82
+ def results
83
+ return nil unless verbose
84
+
85
+ {
86
+ resolutions: resolutions,
87
+ occurrences: occurrences
88
+ }
89
+ end
90
+
91
+ def resolutions
92
+ (@verbose_memo || {}).sort_by { |_, v| v }.to_h
93
+ end
94
+
95
+ def occurrences
96
+ @memo.sort_by{ |_, v| -v }.to_h
97
+ end
98
+
39
99
  def inspect
40
100
  return unless @memo.empty?
41
101
 
42
- results = Parallel.map(top_100_domains) do |domain|
43
- normal_result = normal_resolver.dig(domain, "A")
44
- target_result = target_resolver.dig(domain, "A")
102
+ # read domains outside of the async blocks
103
+ load_domains
104
+
105
+ normal_resolutions = bulk_resolve(normal_resolver, domains)
106
+ resolutions = bulk_resolve(target_resolver, domains)
45
107
 
46
- target_result if target_result && normal_result != target_result
47
- end.compact
108
+ results = resolutions.map do |domain, addresses|
109
+ normal_addresses = normal_resolutions.dig(domain) || []
110
+ address = (addresses || []).first
111
+ [domain, address] if address && !normal_addresses.include?(address)
112
+ end.compact.to_h
48
113
 
49
- @memo = results.group_by(&:itself).map { |k, v| [k, v.length] }.to_h
114
+ @memo = results.values.group_by(&:itself).map { |k, v| [k, v.length] }.to_h
115
+ @verbose_memo = results if verbose
116
+ end
117
+
118
+ def load_domains
119
+ domains
120
+ end
121
+
122
+ def domains
123
+ @domains ||= custom_list ? custom_domains : top_100_domains
124
+ end
125
+
126
+ def custom_domains
127
+ read_domains custom_list
50
128
  end
51
129
 
52
130
  def top_100_domains
53
- @top_100_domains ||= YAML.safe_load(File.read(File.expand_path("./data/top_100.yml", __dir__)))
131
+ case default_list
132
+ when "alexa"
133
+ read_domains File.expand_path("./data/alexa_100.yml", __dir__)
134
+ when "fortune"
135
+ read_domains File.expand_path("./data/fortune_100.yml", __dir__)
136
+ end
137
+ end
138
+
139
+ def read_domains(path)
140
+ list = DomainList.new(path)
141
+ return list.domains if list.valid?
142
+
143
+ raise ArgumentError, "Inputted an invalid list. #{path} is not eixst." unless list.exists?
144
+ raise ArgumentError, "Inputted an invalid list. Please input a list as an YAML file." unless list.valid_format?
145
+ end
146
+
147
+ def bulk_resolve(resolver, domains)
148
+ results = []
149
+
150
+ Async do
151
+ barrier = Async::Barrier.new
152
+ semaphore = Async::Semaphore.new(max_concurrency, parent: barrier)
153
+
154
+ domains.each do |domain|
155
+ semaphore.async do
156
+ addresses = []
157
+ begin
158
+ addresses = resolver.addresses_for(domain, dns_resource_by_record_type, { retries: 1 }).map(&:to_s)
159
+ rescue Async::DNS::ResolutionFailure
160
+ # do nothing
161
+ end
162
+ results << [domain, addresses]
163
+ end
164
+ end
165
+ end
166
+ results.to_h
54
167
  end
55
168
 
56
169
  def normal_resolver
57
- @normal_resolver ||= Resolver.new(nameserver: GOOGLE_PUBLIC_DNS)
170
+ Async::DNS::Resolver.new([[:udp, GOOGLE_PUBLIC_DNS, 53], [:tcp, GOOGLE_PUBLIC_DNS, 53]])
58
171
  end
59
172
 
60
173
  def target_resolver
61
- @target_resolver ||= Resolver.new(nameserver: target)
174
+ Async::DNS::Resolver.new([[:udp, target, 53], [:tcp, target, 53]])
175
+ end
176
+
177
+ def dns_resource_by_record_type
178
+ @dns_resource_by_record_type ||= dns_resources.dig(record_type)
179
+ end
180
+
181
+ def dns_resources
182
+ {
183
+ A: Resolv::DNS::Resource::IN::A,
184
+ AAAA: Resolv::DNS::Resource::IN::AAAA,
185
+ }
62
186
  end
63
187
  end
64
188
  end
@@ -0,0 +1,29 @@
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
+ def exists?
22
+ File.exist?(path)
23
+ end
24
+
25
+ def valid_format?
26
+ domains.is_a? Array
27
+ end
28
+ end
29
+ end
@@ -1,16 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "resolv"
4
+
3
5
  module RogueOne
4
6
  class Ping
5
7
  attr_reader :resolver
8
+ attr_reader :nameserver
6
9
 
7
10
  def initialize(nameserver)
8
- @resolver = Resolver.new(nameserver: nameserver)
11
+ @nameserver = nameserver
12
+ @resolver = Resolv::DNS.new(nameserver: [nameserver])
13
+ @resolver.timeouts = 5
14
+ end
15
+
16
+ def get_a_record
17
+ resolver.getresource("example.com", Resolv::DNS::Resource::IN::A)
18
+ rescue Resolv::ResolvError => _e
19
+ nil
9
20
  end
10
21
 
11
22
  def pong?
12
- result = resolver.dig("example.com", "A")
13
- raise Error, "DNS resolve error: there is no resopnse from #{resolver.nameserver}" unless result
23
+ result = get_a_record
24
+ raise Error, "DNS resolve error: there is no resopnse from #{nameserver}" unless result
14
25
 
15
26
  true
16
27
  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.4.2"
5
5
  end
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": [
3
+ "config:base"
4
+ ]
5
+ }
@@ -10,8 +10,8 @@ Gem::Specification.new do |spec|
10
10
  spec.authors = ["Manabu Niseki"]
11
11
  spec.email = ["manabu.niseki@gmail.com"]
12
12
 
13
- spec.summary = "Rogue one: a rogue DNS detector"
14
- spec.description = 'Rogue one: a rogue DNS detector'
13
+ spec.summary = "A rogue DNS detector"
14
+ spec.description = "A rogue DNS detector"
15
15
  spec.homepage = "https://github.com/ninoseki/rogue_one"
16
16
  spec.license = "MIT"
17
17
 
@@ -24,11 +24,11 @@ Gem::Specification.new do |spec|
24
24
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
25
  spec.require_paths = ["lib"]
26
26
 
27
- spec.add_development_dependency "bundler", "~> 2.0"
27
+ spec.add_development_dependency "bundler", "~> 2.1"
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 "async-dns", "~> 1.2"
33
+ spec.add_dependency "thor", "~> 1.0"
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.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manabu Niseki
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-06-09 00:00:00.000000000 Z
11
+ date: 2020-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.0'
19
+ version: '2.1'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.0'
26
+ version: '2.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: coveralls
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,57 +44,57 @@ 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
- name: parallel
70
+ name: async-dns
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.2'
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.2'
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: '1.0'
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'
97
- description: 'Rogue one: a rogue DNS detector'
96
+ version: '1.0'
97
+ description: A rogue DNS detector
98
98
  email:
99
99
  - manabu.niseki@gmail.com
100
100
  executables:
@@ -112,19 +112,22 @@ 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
- - lib/rogue_one/data/top_100.yml
118
+ - lib/rogue_one/data/alexa_100.yml
119
+ - lib/rogue_one/data/fortune_100.yml
118
120
  - lib/rogue_one/detector.rb
121
+ - lib/rogue_one/domain_list.rb
119
122
  - lib/rogue_one/ping.rb
120
- - lib/rogue_one/resolver.rb
121
123
  - lib/rogue_one/version.rb
124
+ - renovate.json
122
125
  - rogue_one.gemspec
123
126
  homepage: https://github.com/ninoseki/rogue_one
124
127
  licenses:
125
128
  - MIT
126
129
  metadata: {}
127
- post_install_message:
130
+ post_install_message:
128
131
  rdoc_options: []
129
132
  require_paths:
130
133
  - lib
@@ -139,8 +142,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
142
  - !ruby/object:Gem::Version
140
143
  version: '0'
141
144
  requirements: []
142
- rubygems_version: 3.0.2
143
- signing_key:
145
+ rubygems_version: 3.1.2
146
+ signing_key:
144
147
  specification_version: 4
145
- summary: 'Rogue one: a rogue DNS detector'
148
+ summary: A rogue DNS detector
146
149
  test_files: []
@@ -1,101 +0,0 @@
1
- ---
2
- - google.com
3
- - facebook.com
4
- - youtube.com
5
- - yahoo.com
6
- - baidu.com
7
- - wikipedia.org
8
- - qq.com
9
- - taobao.com
10
- - twitter.com
11
- - amazon.com
12
- - linkedin.com
13
- - live.com
14
- - google.co.in
15
- - sina.com.cn
16
- - hao123.com
17
- - blogspot.com
18
- - weibo.com
19
- - tmall.com
20
- - vk.com
21
- - wordpress.com
22
- - yahoo.co.jp
23
- - sohu.com
24
- - yandex.ru
25
- - ebay.com
26
- - google.de
27
- - bing.com
28
- - pinterest.com
29
- - google.co.uk
30
- - 163.com
31
- - 360.cn
32
- - google.fr
33
- - ask.com
34
- - instagram.com
35
- - google.co.jp
36
- - tumblr.com
37
- - msn.com
38
- - google.com.br
39
- - mail.ru
40
- - microsoft.com
41
- - xvideos.com
42
- - paypal.com
43
- - google.ru
44
- - soso.com
45
- - adcash.com
46
- - google.es
47
- - google.it
48
- - imdb.com
49
- - apple.com
50
- - imgur.com
51
- - neobux.com
52
- - craigslist.org
53
- - amazon.co.jp
54
- - t.co
55
- - xhamster.com
56
- - stackoverflow.com
57
- - reddit.com
58
- - google.com.mx
59
- - google.com.hk
60
- - cnn.com
61
- - google.ca
62
- - fc2.com
63
- - go.com
64
- - ifeng.com
65
- - bbc.co.uk
66
- - vube.com
67
- - people.com.cn
68
- - blogger.com
69
- - aliexpress.com
70
- - odnoklassniki.ru
71
- - wordpress.org
72
- - alibaba.com
73
- - gmw.cn
74
- - adobe.com
75
- - huffingtonpost.com
76
- - google.com.tr
77
- - xinhuanet.com
78
- - googleusercontent.com
79
- - youku.com
80
- - godaddy.com
81
- - pornhub.com
82
- - akamaihd.net
83
- - thepiratebay.se
84
- - kickass.to
85
- - google.com.au
86
- - amazon.de
87
- - clkmon.com
88
- - ebay.de
89
- - alipay.com
90
- - google.pl
91
- - espn.go.com
92
- - dailymotion.com
93
- - about.com
94
- - bp.blogspot.com
95
- - blogspot.in
96
- - netflix.com
97
- - vimeo.com
98
- - dailymail.co.uk
99
- - redtube.com
100
- - rakuten.co.jp
101
- - conduit.com
@@ -1,49 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "resolv"
4
-
5
- module RogueOne
6
- class Resolver
7
- attr_reader :nameserver
8
-
9
- def initialize(nameserver:)
10
- @nameserver = nameserver
11
- end
12
-
13
- def dig(domain, type)
14
- _resolver.getresource(domain, resource_by_type(type)).address.to_s
15
- rescue Resolv::ResolvError => e
16
- nil
17
- end
18
-
19
- private
20
-
21
- def _resolver
22
- @_resolver ||= Resolv::DNS.new(nameserver: [nameserver])
23
- @_resolver.timeouts = 5
24
- @_resolver
25
- end
26
-
27
- def resource_by_type(type)
28
- resources.dig(type.upcase.to_sym)
29
- end
30
-
31
- def resources
32
- {
33
- ANY: Resolv::DNS::Resource::IN::ANY,
34
- NS: Resolv::DNS::Resource::IN::NS,
35
- CNAME: Resolv::DNS::Resource::IN::CNAME,
36
- SOA: Resolv::DNS::Resource::IN::SOA,
37
- HINFO: Resolv::DNS::Resource::IN::HINFO,
38
- MINFO: Resolv::DNS::Resource::IN::MINFO,
39
- MX: Resolv::DNS::Resource::IN::MX,
40
- TXT: Resolv::DNS::Resource::IN::TXT,
41
- A: Resolv::DNS::Resource::IN::A,
42
- WKS: Resolv::DNS::Resource::IN::WKS,
43
- PTR: Resolv::DNS::Resource::IN::PTR,
44
- AAAA: Resolv::DNS::Resource::IN::AAAA,
45
- SRV: Resolv::DNS::Resource::IN::SRV,
46
- }
47
- end
48
- end
49
- end