ryo 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: 629de22168d1f622da5000de5afff03d261aae34f0813939b67671c3af6d200f
4
- data.tar.gz: dd04dc76ddd036a2c8de555c21393652f16c0c4629cce743b0ce61b2a1ea7699
3
+ metadata.gz: 4023db8a1481146ed0517b06ca7192b6785c31db7512f04613c7d6ef0e9f183f
4
+ data.tar.gz: 8d0309f005ab9642926ffffe00b6d7b953de252988107aae5fd2d4a55dca8c7b
5
5
  SHA512:
6
- metadata.gz: a423eb6a99f0d17c928f78c99b4f28cef152e194f4de3a0706e6a323769ef75949caf2175f3cde0f6fa1dca5bde52a24a29e3db6aee1a602c01cc3fe5654ed90
7
- data.tar.gz: 3d738fc25ed18646203e497dcb6005af100d2d35e15d01e3df504c982f052b89437a969a04b4ee853b122d07ee7c8ae338a247c311c604c4594a488a8f82c492
6
+ metadata.gz: 5902dc32f735913b4b982c3837fff1d65b1a4005e47a339060e7c4fa12888d29a9a4743faa79d0a3c9450b5ac36fe3567c11f360bc09889f3c75c426264175dd
7
+ data.tar.gz: bf3fec78c637bed9c6a06e05f830c7b9936435a4b8ce3e0ca4446c03e0159779f60da20a2f69717f6f0d87588c6381ffe6fe497a2e21e8040371e13d1374c2a3
data/README.md CHANGED
@@ -16,6 +16,9 @@ Ryo is a yet another website recon tool powered by Ruby.
16
16
  ## Features & ToDo list
17
17
 
18
18
  - [x] Directory & File brute force
19
+ - [x] DNS dig
20
+ - By using [Google Public DNS](https://developers.google.com/speed/public-dns/)
21
+ - [x] Shodan search
19
22
  - [x] Subdomain discovery
20
23
  - By using [DNSDumpster](https://dnsdumpster.com/) and [FindSubdomains](https://findsubdomains.com/)
21
24
  - [x] Website's technology detection
@@ -38,50 +41,220 @@ $ ryo
38
41
  Commands:
39
42
  ryo all URL # Run all discovery plugins against a given URL
40
43
  ryo dir URL # Discover directories and files belong to a given URL
44
+ ryo discover URL # Run discovery plugin(s) against a given URL
45
+ ryo dns URL # Discover DNS records of a given URL
41
46
  ryo help [COMMAND] # Describe available commands or one specific command
47
+ ryo shodan URL # Discover Shodan information of a given URL
42
48
  ryo subdomain URL # Discover subdomains of a given URL
43
49
  ryo tech URL # Discover used technolgies of a given URL
44
50
  ryo whois URL # Discover whois information of a given URL
45
51
  ```
46
52
 
53
+ In order to use Shodan search, please set your Shodan API key as `SHODAN_API_KEY` environment variable.
54
+
55
+ **Example:**
56
+
47
57
  ```sh
48
58
  # start Webrick HTTP server
49
59
  # $ ruby -rwebrick -e 'WEBrick::HTTPServer.new(:DocumentRoot => "./", :Port => 8000).start'
50
60
  $ ryo all http://localhost:8000 | jq .
61
+ ```
62
+
63
+ **Output:**
64
+
65
+ ```json
51
66
  {
52
67
  "dir": [
53
- "http://localhost:8000/.git/",
54
- "http://localhost:8000/.git/branches/",
55
68
  "http://localhost:8000/.git/COMMIT_EDITMSG",
56
69
  "http://localhost:8000/.git/config",
70
+ "http://localhost:8000/.git/branches/",
71
+ "http://localhost:8000/.git/HEAD",
57
72
  "http://localhost:8000/.git/description",
58
73
  "http://localhost:8000/.git/FETCH_HEAD",
59
- "http://localhost:8000/.git/HEAD",
60
- "http://localhost:8000/.git/hooks/",
61
74
  "http://localhost:8000/.git/index",
62
- "http://localhost:8000/.git/info/",
63
75
  "http://localhost:8000/.git/info/exclude",
76
+ "http://localhost:8000/.git/",
64
77
  "http://localhost:8000/.git/logs/",
78
+ "http://localhost:8000/.git/info/",
65
79
  "http://localhost:8000/.git/logs/HEAD",
80
+ "http://localhost:8000/.git/hooks/",
66
81
  "http://localhost:8000/.git/logs/refs/heads/master",
67
82
  "http://localhost:8000/.git/logs/refs/remotes/origin/HEAD",
68
- "http://localhost:8000/.git/objects/",
83
+ "http://localhost:8000/.git/logs/refs/remotes/origin/master",
69
84
  "http://localhost:8000/.git/packed-refs",
70
85
  "http://localhost:8000/.git/refs/",
71
86
  "http://localhost:8000/.git/refs/heads/master",
72
87
  "http://localhost:8000/.git/refs/remotes/origin/HEAD",
88
+ "http://localhost:8000/.git/refs/remotes/origin/master",
73
89
  "http://localhost:8000/.gitignore",
74
90
  "http://localhost:8000/.gitignore/",
91
+ "http://localhost:8000/.git/objects/",
75
92
  "http://localhost:8000/.travis.yml",
76
- "http://localhost:8000/Bin/",
77
93
  "http://localhost:8000/bin/",
94
+ "http://localhost:8000/Bin/",
78
95
  "http://localhost:8000/Gemfile",
79
96
  "http://localhost:8000/Gemfile.lock",
80
97
  "http://localhost:8000/LICENSE",
81
98
  "http://localhost:8000/Rakefile",
82
- "http://localhost:8000/README.md",
83
- "http://localhost:8000/readme.md"
99
+ "http://localhost:8000/readme.md",
100
+ "http://localhost:8000/README.md"
84
101
  ],
102
+ "dns": {
103
+ "A": {
104
+ "Status": 3,
105
+ "TC": false,
106
+ "RD": true,
107
+ "RA": true,
108
+ "AD": true,
109
+ "CD": false,
110
+ "Question": [
111
+ {
112
+ "name": "localhost.",
113
+ "type": 1
114
+ }
115
+ ],
116
+ "Authority": [
117
+ {
118
+ "name": ".",
119
+ "type": 6,
120
+ "TTL": 34709,
121
+ "data": "a.root-servers.net. nstld.verisign-grs.com. 2018090700 1800 900 604800 86400"
122
+ }
123
+ ]
124
+ },
125
+ "AAAA": {
126
+ "Status": 3,
127
+ "TC": false,
128
+ "RD": true,
129
+ "RA": true,
130
+ "AD": true,
131
+ "CD": false,
132
+ "Question": [
133
+ {
134
+ "name": "localhost.",
135
+ "type": 28
136
+ }
137
+ ],
138
+ "Authority": [
139
+ {
140
+ "name": ".",
141
+ "type": 6,
142
+ "TTL": 27096,
143
+ "data": "a.root-servers.net. nstld.verisign-grs.com. 2018090700 1800 900 604800 86400"
144
+ }
145
+ ]
146
+ },
147
+ "CNAME": {
148
+ "Status": 3,
149
+ "TC": false,
150
+ "RD": true,
151
+ "RA": true,
152
+ "AD": true,
153
+ "CD": false,
154
+ "Question": [
155
+ {
156
+ "name": "localhost.",
157
+ "type": 5
158
+ }
159
+ ],
160
+ "Authority": [
161
+ {
162
+ "name": ".",
163
+ "type": 6,
164
+ "TTL": 44332,
165
+ "data": "a.root-servers.net. nstld.verisign-grs.com. 2018090700 1800 900 604800 86400"
166
+ }
167
+ ]
168
+ },
169
+ "MX": {
170
+ "Status": 3,
171
+ "TC": false,
172
+ "RD": true,
173
+ "RA": true,
174
+ "AD": true,
175
+ "CD": false,
176
+ "Question": [
177
+ {
178
+ "name": "localhost.",
179
+ "type": 15
180
+ }
181
+ ],
182
+ "Authority": [
183
+ {
184
+ "name": ".",
185
+ "type": 6,
186
+ "TTL": 86026,
187
+ "data": "a.root-servers.net. nstld.verisign-grs.com. 2018090702 1800 900 604800 86400"
188
+ }
189
+ ]
190
+ },
191
+ "NS": {
192
+ "Status": 3,
193
+ "TC": false,
194
+ "RD": true,
195
+ "RA": true,
196
+ "AD": true,
197
+ "CD": false,
198
+ "Question": [
199
+ {
200
+ "name": "localhost.",
201
+ "type": 2
202
+ }
203
+ ],
204
+ "Authority": [
205
+ {
206
+ "name": ".",
207
+ "type": 6,
208
+ "TTL": 12268,
209
+ "data": "a.root-servers.net. nstld.verisign-grs.com. 2018090601 1800 900 604800 86400"
210
+ }
211
+ ]
212
+ },
213
+ "SOA": {
214
+ "Status": 3,
215
+ "TC": false,
216
+ "RD": true,
217
+ "RA": true,
218
+ "AD": true,
219
+ "CD": false,
220
+ "Question": [
221
+ {
222
+ "name": "localhost.",
223
+ "type": 6
224
+ }
225
+ ],
226
+ "Authority": [
227
+ {
228
+ "name": ".",
229
+ "type": 6,
230
+ "TTL": 7174,
231
+ "data": "a.root-servers.net. nstld.verisign-grs.com. 2018090601 1800 900 604800 86400"
232
+ }
233
+ ]
234
+ },
235
+ "TXT": {
236
+ "Status": 3,
237
+ "TC": false,
238
+ "RD": true,
239
+ "RA": true,
240
+ "AD": true,
241
+ "CD": false,
242
+ "Question": [
243
+ {
244
+ "name": "localhost.",
245
+ "type": 16
246
+ }
247
+ ],
248
+ "Authority": [
249
+ {
250
+ "name": ".",
251
+ "type": 6,
252
+ "TTL": 36307,
253
+ "data": "a.root-servers.net. nstld.verisign-grs.com. 2018090601 1800 900 604800 86400"
254
+ }
255
+ ]
256
+ }
257
+ },
85
258
  "subdomain": [],
86
259
  "tech": {
87
260
  "HTTPServer": [
data/lib/ryo.rb CHANGED
@@ -19,6 +19,8 @@ module Ryo
19
19
 
20
20
  h = {}
21
21
  h[:dir] = Plugin::Dir.discover(target.uri) if options[:dir] || options[:all]
22
+ h[:dns] = Plugin::DNS.discover(target.domain) if options[:dns] || options[:all]
23
+ h[:shodan] = Plugin::Shodan.discover(target.ip) if options[:shodan] || options[:all]
22
24
  h[:subdomain] = Plugin::Subdomain.discover(target.fld) if options[:subdomain] || options[:all]
23
25
  h[:tech] = Plugin::Tech.discover(target.uri) if options[:tech] || options[:all]
24
26
  h[:whois] = Plugin::Whois.discover(target.domain) if options[:whois] || options[:all]
@@ -8,6 +8,18 @@ module Ryo
8
8
  puts hash.to_json
9
9
  end
10
10
 
11
+ desc "dns URL", "Discover DNS records of a given URL"
12
+ def dns(url)
13
+ hash = run_discovery(url, dns: true)
14
+ puts hash.to_json
15
+ end
16
+
17
+ desc "shodan URL", "Discover Shodan information of a given URL"
18
+ def shodan(url)
19
+ hash = run_discovery(url, shodan: true)
20
+ puts hash.to_json
21
+ end
22
+
11
23
  desc "subdomain URL", "Discover subdomains of a given URL"
12
24
  def subdomain(url)
13
25
  hash = run_discovery(url, subdomain: true)
@@ -28,6 +40,7 @@ module Ryo
28
40
 
29
41
  desc "discover URL", "Run discovery plugin(s) against a given URL"
30
42
  method_option :dir, type: :boolean, default: false
43
+ method_option :shodan, type: :boolean, default: false
31
44
  method_option :subdomain, type: :boolean, default: false
32
45
  method_option :tech, type: :boolean, default: false
33
46
  method_option :whois, type: :boolean, default: false
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "./plugin/dir"
4
+ require_relative "./plugin/dns"
5
+ require_relative "./plugin/shodan"
4
6
  require_relative "./plugin/subdomain"
5
7
  require_relative "./plugin/tech"
6
8
  require_relative "./plugin/whois"
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ryo
4
+ module Plugin
5
+ class DNS
6
+ TYPES = %w(A AAAA CNAME MX NS SOA TXT).freeze
7
+
8
+ attr_reader :domain
9
+ def initialize(domain)
10
+ @domain = domain
11
+ end
12
+
13
+ def endpoint
14
+ "https://dns.google.com/resolve"
15
+ end
16
+
17
+ def fetch_body(params)
18
+ res = Client.http.get(endpoint, params: params)
19
+ res.body.to_s
20
+ end
21
+
22
+ def dig(type)
23
+ params = { name: domain, type: type }
24
+ body = fetch_body(params)
25
+ JSON.parse(body)
26
+ end
27
+
28
+ def discover
29
+ h = {}
30
+ TYPES.each do |type|
31
+ h[type] = dig(type)
32
+ end
33
+ h
34
+ end
35
+
36
+ def self.discover(domain)
37
+ new(domain).discover
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "shodanz"
4
+
5
+ module Ryo
6
+ module Plugin
7
+ class Shodan
8
+ attr_reader :client
9
+ def initialize
10
+ raise ArgumentError, "Please set your Shodan API key via ENV['SHODAN_API_KEY']" unless ENV["SHODAN_API_KEY"]
11
+ @client = Shodanz.client.new
12
+ end
13
+
14
+ def discover(ip)
15
+ ip == "N/A" ? { error: "Invalid IP" } : client.rest_api.host(ip)
16
+ end
17
+
18
+ def self.discover(ip)
19
+ begin
20
+ new.discover(ip)
21
+ rescue ArgumentError => e
22
+ { error: e.to_s }
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -25,6 +25,13 @@ module Ryo
25
25
  end
26
26
  end
27
27
 
28
+ def ip
29
+ @ip ||= String.new.tap do |out|
30
+ h = Plugin::DNS.new(domain).dig("A")
31
+ out << (h.dig("Answer")&.first&.dig("data") || "N/A")
32
+ end
33
+ end
34
+
28
35
  private
29
36
 
30
37
  def tlds
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ryo
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  spec.add_development_dependency "bundler", "~> 1.16"
28
28
  spec.add_development_dependency "coveralls", "~> 0.8"
29
+ spec.add_development_dependency "dotenv", "~> 2.5"
29
30
  spec.add_development_dependency "glint", "~> 0.1"
30
31
  spec.add_development_dependency "rake", "~> 10.0"
31
32
  spec.add_development_dependency "rspec", "~> 3.0"
@@ -34,6 +35,7 @@ Gem::Specification.new do |spec|
34
35
 
35
36
  spec.add_dependency "http", "~> 3.3"
36
37
  spec.add_dependency "oga", "~> 2.15"
38
+ spec.add_dependency "shodanz", "~> 1.0"
37
39
  spec.add_dependency "simple_whatweb", "~> 0.2"
38
40
  spec.add_dependency "thor", "~> 0.19"
39
41
  spec.add_dependency "thread", "~> 0.2.2"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ryo
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: 2018-09-07 00:00:00.000000000 Z
11
+ date: 2018-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: dotenv
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.5'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: glint
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -136,6 +150,20 @@ dependencies:
136
150
  - - "~>"
137
151
  - !ruby/object:Gem::Version
138
152
  version: '2.15'
153
+ - !ruby/object:Gem::Dependency
154
+ name: shodanz
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '1.0'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '1.0'
139
167
  - !ruby/object:Gem::Dependency
140
168
  name: simple_whatweb
141
169
  requirement: !ruby/object:Gem::Requirement
@@ -204,6 +232,8 @@ files:
204
232
  - lib/ryo/plugin.rb
205
233
  - lib/ryo/plugin/aux/paths.txt
206
234
  - lib/ryo/plugin/dir.rb
235
+ - lib/ryo/plugin/dns.rb
236
+ - lib/ryo/plugin/shodan.rb
207
237
  - lib/ryo/plugin/subdomain.rb
208
238
  - lib/ryo/plugin/subdomain/base.rb
209
239
  - lib/ryo/plugin/subdomain/dnsdumpster.rb