cms_scanner 0.0.36 → 0.0.37
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 +4 -4
- data/app/controllers/core.rb +18 -4
- data/app/controllers/core/cli_options.rb +2 -0
- data/app/models/interesting_finding.rb +3 -2
- data/app/models/robots_txt.rb +2 -1
- data/app/views/json/interesting_findings/findings.erb +4 -5
- data/cms_scanner.gemspec +5 -4
- data/lib/cms_scanner.rb +10 -5
- data/lib/cms_scanner/browser.rb +2 -0
- data/lib/cms_scanner/browser/options.rb +31 -14
- data/lib/cms_scanner/errors/http.rb +14 -1
- data/lib/cms_scanner/formatter.rb +1 -1
- data/lib/cms_scanner/version.rb +1 -1
- data/lib/cms_scanner/web_site.rb +1 -1
- metadata +29 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: acd54c82dac47f135bd9a9eb739493617a114f8c
|
4
|
+
data.tar.gz: 0cd17341caa2bd782beb2d07b2666d2dbf132d06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5d16f8d26a3873ea5a76c09c48e69f4c67f1dddca9e30a41f775060cccb4543b998845133be7ee937bb21bc0cb63dcf8523c12facc5e773fb8959d20ba5b752
|
7
|
+
data.tar.gz: 581b8ea2a409f4854fbbb214f09b3c3dc7cb00c308665a9545bef7e507475da3da3d56841ee4e6022adb903d66f37fa771610ae3c8d4879f24b15ca9e64c8fb4
|
data/app/controllers/core.rb
CHANGED
@@ -18,11 +18,25 @@ module CMSScanner
|
|
18
18
|
|
19
19
|
setup_cache
|
20
20
|
|
21
|
-
|
21
|
+
check_target_availability
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
# Checks that the target is accessible, raises related errors otherwise
|
25
|
+
#
|
26
|
+
# @return [ Void ]
|
27
|
+
def check_target_availability
|
28
|
+
res = NS::Browser.get(target.url)
|
29
|
+
|
30
|
+
case res.code
|
31
|
+
when 0
|
32
|
+
fail TargetDownError, res
|
33
|
+
when 401
|
34
|
+
fail HTTPAuthRequiredError
|
35
|
+
when 403
|
36
|
+
fail AccessForbiddenError
|
37
|
+
when 407
|
38
|
+
fail ProxyAuthRequiredError
|
39
|
+
end
|
26
40
|
|
27
41
|
redirection = target.redirection
|
28
42
|
fail HTTPRedirectError, redirection if redirection && !parsed_options[:ignore_main_redirect]
|
@@ -34,6 +34,8 @@ module CMSScanner
|
|
34
34
|
OptCredentials.new(['--http-auth login:password']),
|
35
35
|
OptPositiveInteger.new(['--max-threads VALUE', '-t', 'The max threads to use'],
|
36
36
|
default: 5),
|
37
|
+
OptPositiveInteger.new(['--throttle MilliSeconds', 'Milliseconds to wait before doing another web request. ' \
|
38
|
+
'If used, the max threads will be set to 1.']),
|
37
39
|
OptPositiveInteger.new(['--request-timeout SECONDS', 'The request timeout in seconds'],
|
38
40
|
default: 60),
|
39
41
|
OptPositiveInteger.new(['--connect-timeout SECONDS', 'The connection timeout in seconds'],
|
@@ -26,13 +26,14 @@ module CMSScanner
|
|
26
26
|
res.body.split("\n").reject { |s| s.strip.empty? }
|
27
27
|
end
|
28
28
|
|
29
|
+
# @return [ String ]
|
29
30
|
def to_s
|
30
31
|
@to_s || url
|
31
32
|
end
|
32
33
|
|
34
|
+
# @return [ Bollean ]
|
33
35
|
def ==(other)
|
34
|
-
|
35
|
-
to_s == other.to_s
|
36
|
+
self.class == other.class && to_s == other.to_s
|
36
37
|
end
|
37
38
|
end
|
38
39
|
end
|
data/app/models/robots_txt.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
"interesting_findings":
|
1
|
+
"interesting_findings": {
|
2
2
|
<% unless @findings.empty? -%>
|
3
|
-
{
|
4
3
|
<% last_index = @findings.size - 1 %>
|
5
4
|
<% @findings.each.with_index do |finding, index| -%>
|
6
|
-
<%= finding.
|
5
|
+
<%= finding.to_s.to_json %>: {
|
6
|
+
"url": <%= finding.url.to_s.to_json %>,
|
7
7
|
"found_by": <%= finding.found_by.to_s.to_json %>,
|
8
8
|
"confidence": <%= finding.confidence.to_json %>,
|
9
9
|
"confirmed_by": [
|
@@ -20,6 +20,5 @@
|
|
20
20
|
"interesting_entries": <%= finding.interesting_entries.to_json %>
|
21
21
|
}<% unless index == last_index %>,<% end %>
|
22
22
|
<% end -%>
|
23
|
-
}
|
24
23
|
<% end -%>
|
25
|
-
|
24
|
+
},
|
data/cms_scanner.gemspec
CHANGED
@@ -31,19 +31,20 @@ Gem::Specification.new do |s|
|
|
31
31
|
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
32
32
|
s.require_path = 'lib'
|
33
33
|
|
34
|
-
s.add_dependency '
|
35
|
-
s.add_dependency 'typhoeus', '~> 0.7'
|
34
|
+
s.add_dependency 'typhoeus', '~> 0.8'
|
36
35
|
s.add_dependency 'nokogiri', '~> 1.6.6'
|
36
|
+
s.add_dependency 'yajl-ruby', '~> 1.2.1' # Better JSON parser regarding memory usage
|
37
37
|
s.add_dependency 'addressable', '~> 2.3.8'
|
38
38
|
s.add_dependency 'activesupport', '~> 4.2'
|
39
39
|
s.add_dependency 'public_suffix', '~> 1.5'
|
40
40
|
s.add_dependency 'ruby-progressbar', '~> 1.7.5'
|
41
|
+
s.add_dependency 'opt_parse_validator', '~> 0.0.13'
|
41
42
|
|
42
43
|
s.add_development_dependency 'rake', '~> 10.4.2'
|
43
44
|
s.add_development_dependency 'rspec', '~> 3.3'
|
44
45
|
s.add_development_dependency 'rspec-its', '~> 1.2'
|
45
46
|
s.add_development_dependency 'bundler', '~> 1.6'
|
46
|
-
s.add_development_dependency 'rubocop', '~> 0.
|
47
|
-
s.add_development_dependency 'webmock', '~> 1.
|
47
|
+
s.add_development_dependency 'rubocop', '~> 0.34'
|
48
|
+
s.add_development_dependency 'webmock', '~> 1.22'
|
48
49
|
s.add_development_dependency 'simplecov', '~> 0.10'
|
49
50
|
end
|
data/lib/cms_scanner.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
# Gems
|
2
|
-
require 'opt_parse_validator'
|
3
2
|
require 'typhoeus'
|
4
3
|
require 'nokogiri'
|
5
|
-
require '
|
6
|
-
require 'active_support/concern'
|
7
|
-
require 'addressable/uri'
|
4
|
+
require 'yajl/json_gem'
|
8
5
|
require 'public_suffix'
|
6
|
+
require 'addressable/uri'
|
9
7
|
require 'ruby-progressbar'
|
8
|
+
require 'opt_parse_validator'
|
9
|
+
require 'active_support/concern'
|
10
|
+
require 'active_support/inflector'
|
10
11
|
# Standard Libs
|
11
12
|
require 'erb'
|
12
13
|
require 'uri'
|
@@ -38,7 +39,11 @@ module CMSScanner
|
|
38
39
|
|
39
40
|
# Number of requests performed to display at the end of the scan
|
40
41
|
Typhoeus.on_complete do |response|
|
41
|
-
|
42
|
+
next if response.cached?
|
43
|
+
|
44
|
+
self.total_requests += 1
|
45
|
+
|
46
|
+
NS::Browser.instance.trottle!
|
42
47
|
end
|
43
48
|
|
44
49
|
# Module to be able to use these class methods when the CMSScanner
|
data/lib/cms_scanner/browser.rb
CHANGED
@@ -12,6 +12,7 @@ module CMSScanner
|
|
12
12
|
:proxy_auth,
|
13
13
|
:random_user_agent,
|
14
14
|
:request_timeout,
|
15
|
+
:throttle,
|
15
16
|
:user_agent,
|
16
17
|
:user_agents_list,
|
17
18
|
:vhost
|
@@ -19,6 +20,15 @@ module CMSScanner
|
|
19
20
|
|
20
21
|
attr_accessor(*OPTIONS)
|
21
22
|
|
23
|
+
# @return [ String ]
|
24
|
+
def default_user_agent
|
25
|
+
"#{NS} v#{NS::VERSION}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def hydra
|
29
|
+
@hydra ||= Typhoeus::Hydra.new(max_concurrency: max_threads || 1)
|
30
|
+
end
|
31
|
+
|
22
32
|
# @param [ Hash ] options
|
23
33
|
def load_options(options = {})
|
24
34
|
OPTIONS.each do |sym|
|
@@ -26,22 +36,21 @@ module CMSScanner
|
|
26
36
|
end
|
27
37
|
end
|
28
38
|
|
29
|
-
def hydra
|
30
|
-
@hydra ||= Typhoeus::Hydra.new(max_concurrency: max_threads || 1)
|
31
|
-
end
|
32
|
-
|
33
39
|
# Set the threads attribute and update
|
34
40
|
# the max_concurrency of Typhoeus::Hydra
|
35
41
|
#
|
42
|
+
# If the throttle attribute is > 0, max_threads will be forced to 1
|
43
|
+
#
|
36
44
|
# @param [ Integer ] number
|
37
45
|
def max_threads=(number)
|
38
|
-
@max_threads = number.to_i > 0 ? number.to_i : 1
|
46
|
+
@max_threads = number.to_i > 0 && throttle == 0 ? number.to_i : 1
|
47
|
+
|
39
48
|
hydra.max_concurrency = @max_threads
|
40
49
|
end
|
41
50
|
|
42
|
-
# @return [ String ] The
|
43
|
-
def
|
44
|
-
@
|
51
|
+
# @return [ String ] The user agent
|
52
|
+
def user_agent
|
53
|
+
@user_agent ||= random_user_agent ? user_agents.sample : default_user_agent
|
45
54
|
end
|
46
55
|
|
47
56
|
# @return [ Array<String> ]
|
@@ -58,14 +67,22 @@ module CMSScanner
|
|
58
67
|
@user_agents
|
59
68
|
end
|
60
69
|
|
61
|
-
# @return [ String ]
|
62
|
-
def
|
63
|
-
|
70
|
+
# @return [ String ] The path to the user agents list
|
71
|
+
def user_agents_list
|
72
|
+
@user_agents_list ||= File.join(APP_DIR, 'user_agents.txt')
|
64
73
|
end
|
65
74
|
|
66
|
-
# @
|
67
|
-
|
68
|
-
|
75
|
+
# @param [ value ] The throttle time in milliseconds
|
76
|
+
#
|
77
|
+
# if value > 0, the max_threads will be set to 1
|
78
|
+
def throttle=(value)
|
79
|
+
@throttle = value.to_i.abs / 1000.0
|
80
|
+
|
81
|
+
self.max_threads = 1 if @throttle > 0
|
82
|
+
end
|
83
|
+
|
84
|
+
def trottle!
|
85
|
+
sleep(throttle) if throttle > 0
|
69
86
|
end
|
70
87
|
end
|
71
88
|
end
|
@@ -1,5 +1,18 @@
|
|
1
1
|
module CMSScanner
|
2
|
-
class Error <
|
2
|
+
class Error < StandardError
|
3
|
+
end
|
4
|
+
|
5
|
+
# Target Down Error
|
6
|
+
class TargetDownError < Error
|
7
|
+
attr_reader :response
|
8
|
+
|
9
|
+
def initialize(response)
|
10
|
+
@response = response
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
"The url supplied '#{response.request.url}' seems to be down (#{response.return_message})"
|
15
|
+
end
|
3
16
|
end
|
4
17
|
|
5
18
|
# HTTP Authentication Required Error
|
data/lib/cms_scanner/version.rb
CHANGED
data/lib/cms_scanner/web_site.rb
CHANGED
metadata
CHANGED
@@ -1,57 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cms_scanner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.37
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- WPScanTeam
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: typhoeus
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: '0.8'
|
20
20
|
type: :runtime
|
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: 0.
|
26
|
+
version: '0.8'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: nokogiri
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 1.6.6
|
34
34
|
type: :runtime
|
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: 1.6.6
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: yajl-ruby
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 1.
|
47
|
+
version: 1.2.1
|
48
48
|
type: :runtime
|
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: 1.
|
54
|
+
version: 1.2.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: addressable
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: 1.7.5
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: opt_parse_validator
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.0.13
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.0.13
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: rake
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -170,28 +184,28 @@ dependencies:
|
|
170
184
|
requirements:
|
171
185
|
- - "~>"
|
172
186
|
- !ruby/object:Gem::Version
|
173
|
-
version: '0.
|
187
|
+
version: '0.34'
|
174
188
|
type: :development
|
175
189
|
prerelease: false
|
176
190
|
version_requirements: !ruby/object:Gem::Requirement
|
177
191
|
requirements:
|
178
192
|
- - "~>"
|
179
193
|
- !ruby/object:Gem::Version
|
180
|
-
version: '0.
|
194
|
+
version: '0.34'
|
181
195
|
- !ruby/object:Gem::Dependency
|
182
196
|
name: webmock
|
183
197
|
requirement: !ruby/object:Gem::Requirement
|
184
198
|
requirements:
|
185
199
|
- - "~>"
|
186
200
|
- !ruby/object:Gem::Version
|
187
|
-
version: '1.
|
201
|
+
version: '1.22'
|
188
202
|
type: :development
|
189
203
|
prerelease: false
|
190
204
|
version_requirements: !ruby/object:Gem::Requirement
|
191
205
|
requirements:
|
192
206
|
- - "~>"
|
193
207
|
- !ruby/object:Gem::Version
|
194
|
-
version: '1.
|
208
|
+
version: '1.22'
|
195
209
|
- !ruby/object:Gem::Dependency
|
196
210
|
name: simplecov
|
197
211
|
requirement: !ruby/object:Gem::Requirement
|