rogue_one 0.2.0 → 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: da6511f3f76c39a222c7b41458dd08675358923709006f56452e966369f166c9
4
- data.tar.gz: 99ecea46070225babfb4c2b5f9d51da679a026afb22a443cadb6939e7507b697
3
+ metadata.gz: 6967b5c72247d5e6709f0ba71a7402bd181ec8dec2bdc6caa8bd588a01c9d409
4
+ data.tar.gz: 2a79181907673bb4c64b97fe706ce3a3d200260d71f361117f6b42d0fd3c4ba6
5
5
  SHA512:
6
- metadata.gz: 7436a460f227a78b52d6bf57d85ac6e1f1b929f3b675aa02423f8cc5dc89a071cf01dc639e9ae20b688cb350bd99ec3cfef54332a07c56007b1364d82f96daab
7
- data.tar.gz: 053b1f8f9a5c6eb5bf8b10654899bf7a41e106fa7fe412ce4e1fd27ad1917efd822a121464ba873ec698ea7d424d553cde8e85cd2f0ca53d26dd6cf11ac26b63
6
+ metadata.gz: 910aa8d5b1715407536204b63ac365006ff5ae0b7b09e51d42fcae4391a0be7cb1139f25c7131d3f14b386bb1e283f4be14a5b1d7a1b35a8fc01e18fbce21359
7
+ data.tar.gz: c408c4cba8b1b170771adf46132357221db2c00100cfb0991f5547c386d299bbb129dd375609636bd426feae46a06c3dd91cdfdc73ba9528f453c665e471870e
data/README.md CHANGED
@@ -5,7 +5,9 @@
5
5
  [![CodeFactor](https://www.codefactor.io/repository/github/ninoseki/rogue_one/badge)](https://www.codefactor.io/repository/github/ninoseki/rogue_one)
6
6
  [![Coverage Status](https://coveralls.io/repos/github/ninoseki/rogue_one/badge.svg?branch=master)](https://coveralls.io/github/ninoseki/rogue_one?branch=master)
7
7
 
8
- A tiny tool for detecting a rogue DNS server and extracting landing pages from the rogue DNS server.
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.
9
11
 
10
12
  ## How it works
11
13
 
@@ -14,8 +16,9 @@ A tiny tool for detecting a rogue DNS server and extracting landing pages from t
14
16
  IPv4 space is vast. But an attacker could secure a few numbers of IP addresses for landing pages.
15
17
  It means you can (probably) find malicious landing pages by using the following methods.
16
18
 
17
- - Resolving a bunch of domains by using a rogue DNS.
19
+ - Resolving a bunch of domains by using a DNS server.
18
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.
19
22
 
20
23
  ## Installation
21
24
 
@@ -37,6 +40,7 @@ Usage:
37
40
 
38
41
  Options:
39
42
  [--custom-list=CUSTOM_LIST] # A path to a custom list of domains
43
+ [--threshold=N] # Threshold value for determining malicious or not
40
44
  [--verbose], [--no-verbose]
41
45
 
42
46
  Show a report of a given DNS server
@@ -71,7 +75,7 @@ $ rogue_one report 171.244.3.111 --custom-list tmp/roaming.yml
71
75
  ```
72
76
 
73
77
  | Key | Desc. |
74
- |---------------|--------------------------------------------------------------------------|
78
+ | ------------- | ------------------------------------------------------------------------ |
75
79
  | verdict | A detection result (`rogue one` or `benign one`) |
76
80
  | landing_pages | An array of IP of landing pages |
77
81
  | results | DNS resolution results (only available if --verbose option is specified) |
@@ -7,14 +7,16 @@ module RogueOne
7
7
  class CLI < Thor
8
8
  desc "report [DNS_SERVER]", "Show a report of a given DNS server"
9
9
  method_option :custom_list, type: :string, desc: "A path to a custom list of domains"
10
+ method_option :threshold, type: :numeric, desc: "Threshold value for determining malicious or not"
10
11
  method_option :verbose, type: :boolean
11
12
  def report(dns_server)
12
13
  with_error_handling do
13
14
  Ping.pong? dns_server
14
15
 
15
16
  custom_list = options["custom_list"]
17
+ threshold = options["threshold"]
16
18
  verbose = options["verbose"]
17
- detector = Detector.new(target: dns_server, custom_list: custom_list, verbose: verbose)
19
+ detector = Detector.new(target: dns_server, custom_list: custom_list, threshold: threshold, verbose: verbose)
18
20
  puts JSON.pretty_generate(detector.report)
19
21
  end
20
22
  end
@@ -11,9 +11,10 @@ module RogueOne
11
11
 
12
12
  GOOGLE_PUBLIC_DNS = "8.8.8.8"
13
13
 
14
- def initialize(target:, custom_list: nil, verbose: false)
14
+ def initialize(target:, custom_list: nil, threshold: nil, verbose: false)
15
15
  @target = target
16
16
  @custom_list = custom_list
17
+ @threshold = threshold
17
18
  @verbose = verbose
18
19
 
19
20
  @memo = {}
@@ -23,7 +24,12 @@ module RogueOne
23
24
  def report
24
25
  inspect
25
26
 
26
- { verdict: verdict, landing_pages: landing_pages, results: results }.compact
27
+ {
28
+ verdict: verdict,
29
+ landing_pages: landing_pages,
30
+ results: results,
31
+ meta: meta
32
+ }.compact
27
33
  end
28
34
 
29
35
  private
@@ -40,6 +46,12 @@ module RogueOne
40
46
  @threshold ||= (domains.length.to_f / 10.0).ceil
41
47
  end
42
48
 
49
+ def meta
50
+ return nil unless verbose
51
+
52
+ { threshold: threshold }
53
+ end
54
+
43
55
  def landing_pages
44
56
  @memo.map do |ip, count|
45
57
  count > threshold ? ip : nil
@@ -47,17 +59,30 @@ module RogueOne
47
59
  end
48
60
 
49
61
  def results
50
- @verbose_memo
62
+ return nil unless verbose
63
+
64
+ {
65
+ resolutions: resolutions,
66
+ occurrences: occurrences
67
+ }
68
+ end
69
+
70
+ def resolutions
71
+ (@verbose_memo || {}).sort_by { |_, v| v }.to_h
72
+ end
73
+
74
+ def occurrences
75
+ @memo.sort_by{ |_, v| -v }.to_h
51
76
  end
52
77
 
53
78
  def inspect
54
79
  return unless @memo.empty?
55
80
 
56
81
  results = Parallel.map(domains) do |domain|
57
- normal_result = normal_resolver.dig(domain, "A")
58
- target_result = target_resolver.dig(domain, "A")
82
+ normal_results = normal_resolver.get_resources(domain, "A")
83
+ target_result = target_resolver.get_resource(domain, "A")
59
84
 
60
- [domain, target_result] if target_result && normal_result != target_result
85
+ [domain, target_result] if target_result && !normal_results.include?(target_result)
61
86
  end.compact.to_h
62
87
 
63
88
  @memo = results.values.group_by(&:itself).map { |k, v| [k, v.length] }.to_h
@@ -9,7 +9,7 @@ module RogueOne
9
9
  end
10
10
 
11
11
  def pong?
12
- result = resolver.dig("example.com", "A")
12
+ result = resolver.get_resource("example.com", "A")
13
13
  raise Error, "DNS resolve error: there is no resopnse from #{resolver.nameserver}" unless result
14
14
 
15
15
  true
@@ -10,9 +10,15 @@ module RogueOne
10
10
  @nameserver = nameserver
11
11
  end
12
12
 
13
- def dig(domain, type)
13
+ def get_resource(domain, type)
14
14
  _resolver.getresource(domain, resource_by_type(type)).address.to_s
15
- rescue Resolv::ResolvError => e
15
+ rescue Resolv::ResolvError => _e
16
+ nil
17
+ end
18
+
19
+ def get_resources(domain, type)
20
+ _resolver.getresources(domain, resource_by_type(type)).map { |r| r.address.to_s }
21
+ rescue Resolv::ResolvError => _e
16
22
  nil
17
23
  end
18
24
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RogueOne
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -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
 
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.2.0
4
+ version: 0.3.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-10-29 00:00:00.000000000 Z
11
+ date: 2019-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,7 +94,7 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.20'
97
- description: 'Rogue one: a rogue DNS detector'
97
+ description: A rogue DNS detector
98
98
  email:
99
99
  - manabu.niseki@gmail.com
100
100
  executables:
@@ -144,5 +144,5 @@ requirements: []
144
144
  rubygems_version: 3.0.3
145
145
  signing_key:
146
146
  specification_version: 4
147
- summary: 'Rogue one: a rogue DNS detector'
147
+ summary: A rogue DNS detector
148
148
  test_files: []