cms_scanner 0.0.39.4 → 0.0.40
Sign up to get free protection for your applications and to get access to all the features.
- 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
|