cms_scanner 0.0.39.4 → 0.0.40
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/cli_options.rb +2 -1
- data/app/finders/interesting_findings/xml_rpc.rb +2 -0
- data/app/models.rb +1 -0
- data/app/models/headers.rb +1 -0
- data/app/models/robots_txt.rb +1 -0
- data/app/models/user.rb +31 -0
- data/app/models/xml_rpc.rb +57 -23
- data/cms_scanner.gemspec +10 -9
- data/lib/cms_scanner.rb +6 -5
- data/lib/cms_scanner/browser.rb +6 -2
- data/lib/cms_scanner/browser/options.rb +2 -0
- data/lib/cms_scanner/finders/base_finders.rb +1 -0
- data/lib/cms_scanner/finders/finder.rb +3 -2
- data/lib/cms_scanner/finders/finder/breadth_first_dictionary_attack.rb +102 -0
- data/lib/cms_scanner/formatter.rb +1 -0
- data/lib/cms_scanner/progressbar_null_output.rb +21 -0
- data/lib/cms_scanner/target.rb +14 -17
- data/lib/cms_scanner/target/hashes.rb +1 -1
- data/lib/cms_scanner/target/scope.rb +2 -3
- data/lib/cms_scanner/target/server/generic.rb +1 -0
- data/lib/cms_scanner/typhoeus/response.rb +6 -1
- data/lib/cms_scanner/version.rb +1 -1
- metadata +37 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c4b37ccad3760d463de8eaebf2bd9dd3c11df74
|
4
|
+
data.tar.gz: e532f0a510747d99cebe122f00ffc209c90e4861
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5fbb20fc97d62e99224db5142a05c35ab2092e41394759b87d1724a6acf4c832252de936f56f3f5da643e07ec4c3fd15a16fbeacbd3a6dd634995b8424654403
|
7
|
+
data.tar.gz: e92192374822ccecbee941488b0ec5cda5a92061f6b6fd6a9a9fe3c358d602d3de427e8d3ab602e26280bb0e599f094a82c468906b0f723b69ea85978c40b413
|
@@ -48,7 +48,8 @@ module CMSScanner
|
|
48
48
|
OptPositiveInteger.new(['--request-timeout SECONDS', 'The request timeout in seconds'],
|
49
49
|
default: 60),
|
50
50
|
OptPositiveInteger.new(['--connect-timeout SECONDS', 'The connection timeout in seconds'],
|
51
|
-
default: 30)
|
51
|
+
default: 30),
|
52
|
+
OptBoolean.new(['--disable-tls-checks', 'Disables SSL/TLS certificate verification'])
|
52
53
|
] + cli_browser_proxy_options + cli_browser_cookies_options + cli_browser_cache_options
|
53
54
|
end
|
54
55
|
|
@@ -18,6 +18,7 @@ module CMSScanner
|
|
18
18
|
url = target.homepage_res.headers['X-Pingback']
|
19
19
|
|
20
20
|
return unless target.in_scope?(url)
|
21
|
+
|
21
22
|
potential_urls << url
|
22
23
|
|
23
24
|
NS::XMLRPC.new(url, confidence: 30, found_by: 'Headers (Passive Detection)')
|
@@ -29,6 +30,7 @@ module CMSScanner
|
|
29
30
|
url = tag.attribute('href').to_s
|
30
31
|
|
31
32
|
next unless target.in_scope?(url)
|
33
|
+
|
32
34
|
potential_urls << url
|
33
35
|
|
34
36
|
return NS::XMLRPC.new(url, confidence: 30,
|
data/app/models.rb
CHANGED
data/app/models/headers.rb
CHANGED
data/app/models/robots_txt.rb
CHANGED
data/app/models/user.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module CMSScanner
|
2
|
+
# User
|
3
|
+
class User
|
4
|
+
include Finders::Finding
|
5
|
+
|
6
|
+
attr_accessor :password
|
7
|
+
attr_reader :id, :username
|
8
|
+
|
9
|
+
# @param [ String ] username
|
10
|
+
# @param [ Hash ] opts
|
11
|
+
# @option opts [ Integer ] :id
|
12
|
+
# @option opts [ String ] :password
|
13
|
+
def initialize(username, opts = {})
|
14
|
+
@username = username
|
15
|
+
@password = opts[:password]
|
16
|
+
@id = opts[:id]
|
17
|
+
|
18
|
+
parse_finding_options(opts)
|
19
|
+
end
|
20
|
+
|
21
|
+
def ==(other)
|
22
|
+
return false unless self.class == other.class
|
23
|
+
|
24
|
+
username == other.username
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
username
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/app/models/xml_rpc.rb
CHANGED
@@ -1,35 +1,69 @@
|
|
1
1
|
module CMSScanner
|
2
2
|
# XML RPC
|
3
3
|
class XMLRPC < InterestingFinding
|
4
|
-
# @
|
5
|
-
|
6
|
-
|
7
|
-
#
|
8
|
-
# @return [ Typhoeus::Response ]
|
9
|
-
def call(method, params = [], request_params = {})
|
10
|
-
NS::Browser.post(url, request_params.merge(body: request_body(method, params)))
|
4
|
+
# @return [ Browser ]
|
5
|
+
def browser
|
6
|
+
@browser ||= NS::Browser.instance
|
11
7
|
end
|
12
8
|
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
# @param [ Array ] params
|
17
|
-
#
|
18
|
-
# @return [ String ] The body of the XML RPC request
|
19
|
-
def request_body(method, params = [])
|
20
|
-
p_body = ''
|
9
|
+
# @return [ Array<String> ]
|
10
|
+
def available_methods
|
11
|
+
return @available_methods if @available_methods
|
21
12
|
|
22
|
-
|
13
|
+
@available_methods = []
|
14
|
+
|
15
|
+
res = method_call('system.listMethods').run
|
16
|
+
doc = Nokogiri::XML.parse(res.body)
|
17
|
+
|
18
|
+
doc.search('methodResponse params param value array data value string').each do |s|
|
19
|
+
@available_methods << s.text
|
20
|
+
end
|
21
|
+
|
22
|
+
@available_methods
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
body << '</methodCall>'
|
25
|
+
# @return [ Boolean ] Whether or not the XMLRPC is enabled
|
26
|
+
def enabled?
|
27
|
+
!available_methods.empty?
|
28
28
|
end
|
29
29
|
|
30
|
-
#
|
31
|
-
#
|
30
|
+
# @param [ String ] method_name
|
31
|
+
# @param [ Array ] method_params
|
32
|
+
# @param [ Hash ] request_params
|
32
33
|
#
|
33
|
-
#
|
34
|
+
# @return [ Typhoeus::Request ]
|
35
|
+
def method_call(method_name, method_params = [], request_params = {})
|
36
|
+
browser.forge_request(
|
37
|
+
url,
|
38
|
+
request_params.merge(
|
39
|
+
method: :post,
|
40
|
+
body: ::XMLRPC::Create.new.methodCall(method_name, *method_params)
|
41
|
+
)
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
# @param [ Array<Array> ] methods_and_params
|
46
|
+
# @param [ Hash ] request_params
|
47
|
+
#
|
48
|
+
# Example of methods_and_params:
|
49
|
+
# [
|
50
|
+
# [method1, param1, param2],
|
51
|
+
# [method2, param1],
|
52
|
+
# [method3]
|
53
|
+
# ]
|
54
|
+
#
|
55
|
+
# @return [ Typhoeus::Request ]
|
56
|
+
def multi_call(methods_and_params = [], request_params = {})
|
57
|
+
browser.forge_request(
|
58
|
+
url,
|
59
|
+
request_params.merge(
|
60
|
+
method: :post,
|
61
|
+
body: ::XMLRPC::Create.new.methodCall(
|
62
|
+
'system.multicall',
|
63
|
+
methods_and_params.collect { |m| { methodName: m[0], params: m[1..-1] } }
|
64
|
+
)
|
65
|
+
)
|
66
|
+
)
|
67
|
+
end
|
34
68
|
end
|
35
69
|
end
|
data/cms_scanner.gemspec
CHANGED
@@ -32,23 +32,24 @@ Gem::Specification.new do |s|
|
|
32
32
|
s.require_path = 'lib'
|
33
33
|
|
34
34
|
s.add_dependency 'nokogiri', '~> 1.8.0'
|
35
|
-
s.add_dependency 'opt_parse_validator', '~> 0.0.16.
|
35
|
+
s.add_dependency 'opt_parse_validator', '~> 0.0.16.2'
|
36
36
|
s.add_dependency 'public_suffix', '~> 3.0.0'
|
37
|
-
s.add_dependency 'ruby-progressbar', '~> 1.
|
37
|
+
s.add_dependency 'ruby-progressbar', '~> 1.10.0'
|
38
38
|
s.add_dependency 'typhoeus', '~> 1.3.0'
|
39
|
-
s.add_dependency '
|
39
|
+
s.add_dependency 'xmlrpc', '~> 0.3'
|
40
|
+
s.add_dependency 'yajl-ruby', '~> 1.4.1' # Better JSON parser regarding memory usage
|
40
41
|
|
41
42
|
# Already required by opt_parse_validator
|
42
43
|
# so version restriction loosen to avoid potential future conflicts
|
43
|
-
s.add_dependency 'activesupport', '~> 5.
|
44
|
+
s.add_dependency 'activesupport', '~> 5.2'
|
44
45
|
s.add_dependency 'addressable', '~> 2.5'
|
45
46
|
|
46
47
|
s.add_development_dependency 'bundler', '~> 1.6'
|
47
48
|
s.add_development_dependency 'coveralls', '~> 0.8.0'
|
48
|
-
s.add_development_dependency 'rake', '~> 12.
|
49
|
-
s.add_development_dependency 'rspec', '~> 3.
|
49
|
+
s.add_development_dependency 'rake', '~> 12.3'
|
50
|
+
s.add_development_dependency 'rspec', '~> 3.8.0'
|
50
51
|
s.add_development_dependency 'rspec-its', '~> 1.2.0'
|
51
|
-
s.add_development_dependency 'rubocop', '~> 0.
|
52
|
-
s.add_development_dependency 'simplecov', '~> 0.
|
53
|
-
s.add_development_dependency 'webmock', '~> 3.
|
52
|
+
s.add_development_dependency 'rubocop', '~> 0.59.1'
|
53
|
+
s.add_development_dependency 'simplecov', '~> 0.16.1'
|
54
|
+
s.add_development_dependency 'webmock', '~> 3.4.2'
|
54
55
|
end
|
data/lib/cms_scanner.rb
CHANGED
@@ -5,7 +5,6 @@ require 'yajl/json_gem'
|
|
5
5
|
require 'public_suffix'
|
6
6
|
require 'addressable/uri'
|
7
7
|
require 'ruby-progressbar'
|
8
|
-
require 'ruby-progressbar/outputs/null'
|
9
8
|
require 'opt_parse_validator'
|
10
9
|
require 'active_support/concern'
|
11
10
|
require 'active_support/inflector'
|
@@ -14,11 +13,13 @@ require 'erb'
|
|
14
13
|
require 'uri'
|
15
14
|
require 'fileutils'
|
16
15
|
require 'pathname'
|
16
|
+
require 'xmlrpc/client'
|
17
17
|
# Monkey Patches
|
18
|
-
require 'cms_scanner/typhoeus/response'
|
19
|
-
require 'cms_scanner/typhoeus/hydra'
|
20
|
-
require 'cms_scanner/public_suffix/domain'
|
21
|
-
require 'cms_scanner/numeric'
|
18
|
+
require 'cms_scanner/typhoeus/response' # Adds a Response#html using Nokogiri to parse the body
|
19
|
+
require 'cms_scanner/typhoeus/hydra' # https://github.com/typhoeus/typhoeus/issues/439
|
20
|
+
require 'cms_scanner/public_suffix/domain' # Adds a Domain#match method and logic, used in scope stuff
|
21
|
+
require 'cms_scanner/numeric' # Adds a Numeric#bytes_to_human
|
22
|
+
require 'cms_scanner/progressbar_null_output'
|
22
23
|
# Custom Libs
|
23
24
|
require 'cms_scanner/helper'
|
24
25
|
require 'cms_scanner/exit_code'
|
data/lib/cms_scanner/browser.rb
CHANGED
@@ -46,13 +46,17 @@ module CMSScanner
|
|
46
46
|
# @return [ Hash ]
|
47
47
|
def default_request_params
|
48
48
|
params = {
|
49
|
-
# Disable SSL-Certificate checks, see http://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html
|
50
|
-
ssl_verifypeer: false, ssl_verifyhost: 0,
|
51
49
|
headers: { 'User-Agent' => user_agent }.merge(headers || {}),
|
52
50
|
accept_encoding: 'gzip, deflate',
|
53
51
|
method: :get
|
54
52
|
}
|
55
53
|
|
54
|
+
if disable_tls_checks
|
55
|
+
# See http://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html
|
56
|
+
params[:ssl_verifypeer] = false
|
57
|
+
params[:ssl_verifyhost] = 0
|
58
|
+
end
|
59
|
+
|
56
60
|
typhoeus_to_browser_opts.each do |typhoeus_opt, browser_opt|
|
57
61
|
attr_value = public_send(browser_opt)
|
58
62
|
params[typhoeus_opt] = attr_value unless attr_value.nil?
|
@@ -6,6 +6,7 @@ module CMSScanner
|
|
6
6
|
cookie_jar
|
7
7
|
cookie_string
|
8
8
|
connect_timeout
|
9
|
+
disable_tls_checks
|
9
10
|
headers
|
10
11
|
http_auth
|
11
12
|
max_threads
|
@@ -62,6 +63,7 @@ module CMSScanner
|
|
62
63
|
|
63
64
|
File.open(user_agents_list).each do |line|
|
64
65
|
next if line == "\n" || line[0, 1] == '#'
|
66
|
+
|
65
67
|
@user_agents << line.chomp
|
66
68
|
end
|
67
69
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'cms_scanner/finders/finder/smart_url_checker'
|
2
2
|
require 'cms_scanner/finders/finder/enumerator'
|
3
3
|
require 'cms_scanner/finders/finder/fingerprinter'
|
4
|
+
require 'cms_scanner/finders/finder/breadth_first_dictionary_attack'
|
4
5
|
|
5
6
|
module CMSScanner
|
6
7
|
module Finders
|
@@ -32,9 +33,9 @@ module CMSScanner
|
|
32
33
|
# @return [ ProgressBar::Base ]
|
33
34
|
def create_progress_bar(opts = {})
|
34
35
|
bar_opts = { format: '%t %a <%B> (%c / %C) %P%% %e' }
|
35
|
-
bar_opts[:output] =
|
36
|
+
bar_opts[:output] = ProgressBarNullOutput unless opts[:show_progression]
|
36
37
|
|
37
|
-
@progress_bar = ProgressBar.create(bar_opts.merge(opts))
|
38
|
+
@progress_bar = ::ProgressBar.create(bar_opts.merge(opts))
|
38
39
|
end
|
39
40
|
|
40
41
|
# @return [ Browser ]
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module CMSScanner
|
2
|
+
module Finders
|
3
|
+
class Finder
|
4
|
+
# Module to provide an easy way to perform password attacks
|
5
|
+
module BreadthFirstDictionaryAttack
|
6
|
+
# @param [ Array<CMSScanner::User> ] users
|
7
|
+
# @param [ Array<String> ] passwords
|
8
|
+
# @param [ Hash ] opts
|
9
|
+
# @option opts [ Boolean ] :show_progression
|
10
|
+
#
|
11
|
+
# @yield [ CMSScanner::User ] When a valid combination is found
|
12
|
+
#
|
13
|
+
# TODO: Make rubocop happy about metrics etc
|
14
|
+
#
|
15
|
+
# rubocop:disable all
|
16
|
+
def attack(users, passwords, opts = {})
|
17
|
+
create_progress_bar(total: users.size * passwords.size, show_progression: opts[:show_progression])
|
18
|
+
queue_count = 0
|
19
|
+
|
20
|
+
passwords.each_with_index do |password, password_index|
|
21
|
+
remaining_users = users.select { |u| u.password.nil? }
|
22
|
+
|
23
|
+
break if remaining_users.empty?
|
24
|
+
|
25
|
+
remaining_users.each do |user|
|
26
|
+
request = login_request(user.username, password)
|
27
|
+
|
28
|
+
request.on_complete do |res|
|
29
|
+
progress_bar.title = "Trying #{user.username} / #{password}"
|
30
|
+
progress_bar.increment
|
31
|
+
|
32
|
+
if valid_credentials?(res)
|
33
|
+
user.password = password
|
34
|
+
|
35
|
+
yield user
|
36
|
+
|
37
|
+
offset = progress_bar.total - progress_bar.progress < hydra.max_concurrency ? 2 : 1
|
38
|
+
|
39
|
+
progress_bar.total -= passwords.size - password_index - offset
|
40
|
+
elsif errored_response?(res)
|
41
|
+
output_error(res)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
hydra.queue(request)
|
46
|
+
queue_count += 1
|
47
|
+
|
48
|
+
if queue_count >= hydra.max_concurrency
|
49
|
+
hydra.run
|
50
|
+
queue_count = 0
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
hydra.run
|
56
|
+
progress_bar.stop
|
57
|
+
end
|
58
|
+
# rubocop:enable all
|
59
|
+
|
60
|
+
# @param [ String ] username
|
61
|
+
# param [ String ] password
|
62
|
+
#
|
63
|
+
# @return [ Typhoeus::Request ]
|
64
|
+
def login_request(username, password)
|
65
|
+
# To Implement in the finder related to the attack
|
66
|
+
end
|
67
|
+
|
68
|
+
# @param [ Typhoeus::Response ] response
|
69
|
+
#
|
70
|
+
# @return [ Boolean ] Whether or not credentials related to the request are valid
|
71
|
+
def valid_credentials?(response)
|
72
|
+
# To Implement in the finder related to the attack
|
73
|
+
end
|
74
|
+
|
75
|
+
# @param [ Typhoeus::Response ] response
|
76
|
+
#
|
77
|
+
# @return [ Boolean ] Whether or not something wrong happened
|
78
|
+
# other than wrong credentials
|
79
|
+
def errored_response?(response)
|
80
|
+
# To Implement in the finder related to the attack
|
81
|
+
end
|
82
|
+
|
83
|
+
protected
|
84
|
+
|
85
|
+
# @param [ Typhoeus::Response ] response
|
86
|
+
def output_error(response)
|
87
|
+
error = if response.timed_out?
|
88
|
+
'Request timed out.'
|
89
|
+
elsif response.code.zero?
|
90
|
+
"No response from remote server. WAF/IPS? (#{response.return_message})"
|
91
|
+
elsif response.code.to_s =~ /^50/
|
92
|
+
'Server error, try reducing the number of threads.'
|
93
|
+
else
|
94
|
+
"Unknown response received Code: #{response.code}\nBody: #{response.body}"
|
95
|
+
end
|
96
|
+
|
97
|
+
progress_bar.log("Error: #{error}")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'ruby-progressbar/outputs/null'
|
2
|
+
|
3
|
+
module CMSScanner
|
4
|
+
# Adds the feature to log message sent to #log
|
5
|
+
# So they can be retrieved at some point, like after a password attack with a JSON output
|
6
|
+
# which won't display the progressbar but still call #log for errors etc
|
7
|
+
class ProgressBarNullOutput < ::ProgressBar::Outputs::Null
|
8
|
+
# @retutn [ Array<String> ]
|
9
|
+
def logs
|
10
|
+
@logs ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
# Override of parent method
|
14
|
+
# @return [ Array<String> ] return the logs when no string provided
|
15
|
+
def log(string = nil)
|
16
|
+
return logs if string.nil?
|
17
|
+
|
18
|
+
logs << string
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/cms_scanner/target.rb
CHANGED
@@ -80,36 +80,33 @@ module CMSScanner
|
|
80
80
|
|
81
81
|
# @param [ Typhoeus::Response, String ] page
|
82
82
|
# @param [ String ] xpath
|
83
|
-
# @param [ Array<String> ] attributes
|
84
83
|
#
|
85
84
|
# @yield [ String, Nokogiri::XML::Element ] The url and its associated tag
|
86
85
|
#
|
87
86
|
# @return [ Array<String> ] The absolute URLs detected in the response's body from the HTML tags
|
88
|
-
def urls_from_page(page = nil, xpath = '
|
87
|
+
def urls_from_page(page = nil, xpath = '//@href|//@src|//@data-src')
|
89
88
|
page = NS::Browser.get(url(page)) unless page.is_a?(Typhoeus::Response)
|
90
89
|
found = []
|
91
90
|
|
92
|
-
page.html.xpath(xpath).each do |
|
93
|
-
|
94
|
-
attr_value = tag[attribute]
|
91
|
+
page.html.xpath(xpath).each do |node|
|
92
|
+
attr_value = node.text.to_s
|
95
93
|
|
96
|
-
|
94
|
+
next unless attr_value && !attr_value.empty?
|
97
95
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
96
|
+
node_uri = begin
|
97
|
+
uri.join(attr_value.strip)
|
98
|
+
rescue StandardError
|
99
|
+
# Skip potential malformed URLs etc.
|
100
|
+
next
|
101
|
+
end
|
104
102
|
|
105
|
-
|
103
|
+
node_uri_string = node_uri.to_s
|
106
104
|
|
107
|
-
|
105
|
+
next unless node_uri.host
|
108
106
|
|
109
|
-
|
107
|
+
yield node_uri_string, node.parent if block_given? && !found.include?(node_uri_string)
|
110
108
|
|
111
|
-
|
112
|
-
end
|
109
|
+
found << node_uri_string
|
113
110
|
end
|
114
111
|
|
115
112
|
found.uniq
|
@@ -17,15 +17,14 @@ module CMSScanner
|
|
17
17
|
|
18
18
|
# @param [ Typhoeus::Response ] res
|
19
19
|
# @param [ String ] xpath
|
20
|
-
# @param [ Array<String> ] attributes
|
21
20
|
#
|
22
21
|
# @yield [ String, Nokogiri::XML::Element ] The in scope url and its associated tag
|
23
22
|
#
|
24
23
|
# @return [ Array<String> ] The in scope absolute URLs detected in the response's body
|
25
|
-
def in_scope_urls(res, xpath = '
|
24
|
+
def in_scope_urls(res, xpath = '//@href|//@src|//@data-src')
|
26
25
|
found = []
|
27
26
|
|
28
|
-
urls_from_page(res, xpath
|
27
|
+
urls_from_page(res, xpath) do |url, tag|
|
29
28
|
next unless in_scope?(url)
|
30
29
|
|
31
30
|
yield url, tag if block_given?
|
@@ -1,9 +1,14 @@
|
|
1
1
|
module Typhoeus
|
2
2
|
# Custom Response class
|
3
3
|
class Response
|
4
|
-
# @return [ Nokogiri::HTML ] The response's body parsed by Nokogiri
|
4
|
+
# @return [ Nokogiri::HTML ] The response's body parsed by Nokogiri::HTML
|
5
5
|
def html
|
6
6
|
@html ||= Nokogiri::HTML(body.encode('UTF-8', invalid: :replace, undef: :replace))
|
7
7
|
end
|
8
|
+
|
9
|
+
# @return [ Nokogiri::XML ] The response's body parsed by Nokogiri::XML
|
10
|
+
def xml
|
11
|
+
@xml ||= Nokogiri::XML(body.encode('UTF-8', invalid: :replace, undef: :replace))
|
12
|
+
end
|
8
13
|
end
|
9
14
|
end
|
data/lib/cms_scanner/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.40
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- WPScanTeam
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-09-
|
11
|
+
date: 2018-09-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.0.16.
|
33
|
+
version: 0.0.16.2
|
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: 0.0.16.
|
40
|
+
version: 0.0.16.2
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: public_suffix
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.
|
61
|
+
version: 1.10.0
|
62
62
|
type: :runtime
|
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: 1.
|
68
|
+
version: 1.10.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: typhoeus
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,34 +80,48 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 1.3.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: xmlrpc
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.3'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.3'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: yajl-ruby
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
101
|
- - "~>"
|
88
102
|
- !ruby/object:Gem::Version
|
89
|
-
version: 1.
|
103
|
+
version: 1.4.1
|
90
104
|
type: :runtime
|
91
105
|
prerelease: false
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
93
107
|
requirements:
|
94
108
|
- - "~>"
|
95
109
|
- !ruby/object:Gem::Version
|
96
|
-
version: 1.
|
110
|
+
version: 1.4.1
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: activesupport
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
115
|
- - "~>"
|
102
116
|
- !ruby/object:Gem::Version
|
103
|
-
version: '5.
|
117
|
+
version: '5.2'
|
104
118
|
type: :runtime
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
108
122
|
- - "~>"
|
109
123
|
- !ruby/object:Gem::Version
|
110
|
-
version: '5.
|
124
|
+
version: '5.2'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: addressable
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -156,28 +170,28 @@ dependencies:
|
|
156
170
|
requirements:
|
157
171
|
- - "~>"
|
158
172
|
- !ruby/object:Gem::Version
|
159
|
-
version: '12.
|
173
|
+
version: '12.3'
|
160
174
|
type: :development
|
161
175
|
prerelease: false
|
162
176
|
version_requirements: !ruby/object:Gem::Requirement
|
163
177
|
requirements:
|
164
178
|
- - "~>"
|
165
179
|
- !ruby/object:Gem::Version
|
166
|
-
version: '12.
|
180
|
+
version: '12.3'
|
167
181
|
- !ruby/object:Gem::Dependency
|
168
182
|
name: rspec
|
169
183
|
requirement: !ruby/object:Gem::Requirement
|
170
184
|
requirements:
|
171
185
|
- - "~>"
|
172
186
|
- !ruby/object:Gem::Version
|
173
|
-
version: 3.
|
187
|
+
version: 3.8.0
|
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: 3.
|
194
|
+
version: 3.8.0
|
181
195
|
- !ruby/object:Gem::Dependency
|
182
196
|
name: rspec-its
|
183
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -198,42 +212,42 @@ dependencies:
|
|
198
212
|
requirements:
|
199
213
|
- - "~>"
|
200
214
|
- !ruby/object:Gem::Version
|
201
|
-
version: 0.
|
215
|
+
version: 0.59.1
|
202
216
|
type: :development
|
203
217
|
prerelease: false
|
204
218
|
version_requirements: !ruby/object:Gem::Requirement
|
205
219
|
requirements:
|
206
220
|
- - "~>"
|
207
221
|
- !ruby/object:Gem::Version
|
208
|
-
version: 0.
|
222
|
+
version: 0.59.1
|
209
223
|
- !ruby/object:Gem::Dependency
|
210
224
|
name: simplecov
|
211
225
|
requirement: !ruby/object:Gem::Requirement
|
212
226
|
requirements:
|
213
227
|
- - "~>"
|
214
228
|
- !ruby/object:Gem::Version
|
215
|
-
version: 0.
|
229
|
+
version: 0.16.1
|
216
230
|
type: :development
|
217
231
|
prerelease: false
|
218
232
|
version_requirements: !ruby/object:Gem::Requirement
|
219
233
|
requirements:
|
220
234
|
- - "~>"
|
221
235
|
- !ruby/object:Gem::Version
|
222
|
-
version: 0.
|
236
|
+
version: 0.16.1
|
223
237
|
- !ruby/object:Gem::Dependency
|
224
238
|
name: webmock
|
225
239
|
requirement: !ruby/object:Gem::Requirement
|
226
240
|
requirements:
|
227
241
|
- - "~>"
|
228
242
|
- !ruby/object:Gem::Version
|
229
|
-
version: 3.
|
243
|
+
version: 3.4.2
|
230
244
|
type: :development
|
231
245
|
prerelease: false
|
232
246
|
version_requirements: !ruby/object:Gem::Requirement
|
233
247
|
requirements:
|
234
248
|
- - "~>"
|
235
249
|
- !ruby/object:Gem::Version
|
236
|
-
version: 3.
|
250
|
+
version: 3.4.2
|
237
251
|
description: Framework to provide an easy way to implement CMS Scanners
|
238
252
|
email:
|
239
253
|
- team@wpscan.org
|
@@ -265,6 +279,7 @@ files:
|
|
265
279
|
- app/models/headers.rb
|
266
280
|
- app/models/interesting_finding.rb
|
267
281
|
- app/models/robots_txt.rb
|
282
|
+
- app/models/user.rb
|
268
283
|
- app/models/version.rb
|
269
284
|
- app/models/xml_rpc.rb
|
270
285
|
- app/user_agents.txt
|
@@ -317,6 +332,7 @@ files:
|
|
317
332
|
- lib/cms_scanner/finders.rb
|
318
333
|
- lib/cms_scanner/finders/base_finders.rb
|
319
334
|
- lib/cms_scanner/finders/finder.rb
|
335
|
+
- lib/cms_scanner/finders/finder/breadth_first_dictionary_attack.rb
|
320
336
|
- lib/cms_scanner/finders/finder/enumerator.rb
|
321
337
|
- lib/cms_scanner/finders/finder/fingerprinter.rb
|
322
338
|
- lib/cms_scanner/finders/finder/smart_url_checker.rb
|
@@ -333,6 +349,7 @@ files:
|
|
333
349
|
- lib/cms_scanner/formatter/buffer.rb
|
334
350
|
- lib/cms_scanner/helper.rb
|
335
351
|
- lib/cms_scanner/numeric.rb
|
352
|
+
- lib/cms_scanner/progressbar_null_output.rb
|
336
353
|
- lib/cms_scanner/public_suffix/domain.rb
|
337
354
|
- lib/cms_scanner/references.rb
|
338
355
|
- lib/cms_scanner/target.rb
|