cms_scanner 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/finders/interesting_files/xml_rpc.rb +1 -3
- data/app/models.rb +1 -0
- data/app/models/interesting_file.rb +0 -4
- data/app/models/version.rb +17 -0
- data/app/views/cli/core/finished.erb +0 -1
- data/app/views/cli/interesting_files/findings.erb +1 -1
- data/cms_scanner.gemspec +2 -2
- data/lib/cms_scanner.rb +1 -0
- data/lib/cms_scanner/finders.rb +2 -0
- data/lib/cms_scanner/finders/finding.rb +4 -0
- data/lib/cms_scanner/finders/independent_finders.rb +1 -1
- data/lib/cms_scanner/finders/unique_finder.rb +17 -0
- data/lib/cms_scanner/finders/unique_finders.rb +39 -0
- data/lib/cms_scanner/target.rb +1 -0
- data/lib/cms_scanner/target/platform/wordpress.rb +2 -4
- data/lib/cms_scanner/target/platform/wordpress/custom_directories.rb +1 -2
- data/lib/cms_scanner/target/server/apache.rb +3 -2
- data/lib/cms_scanner/target/server/iis.rb +1 -2
- data/lib/cms_scanner/typhoeus/response.rb +9 -0
- data/lib/cms_scanner/version.rb +1 -1
- data/spec/app/controllers/core_spec.rb +0 -2
- data/spec/app/controllers/interesting_files_spec.rb +0 -2
- data/spec/app/finders/interesting_files/fantastico_fileslist_spec.rb +0 -2
- data/spec/app/finders/interesting_files/headers_spec.rb +0 -2
- data/spec/app/finders/interesting_files/robots_txt_spec.rb +0 -2
- data/spec/app/finders/interesting_files/search_replace_db_2_spec.rb +0 -2
- data/spec/app/finders/interesting_files/xml_rpc_spec.rb +0 -2
- data/spec/app/finders/interesting_files_spec.rb +1 -2
- data/spec/app/formatters/cli_no_colour_spec.rb +0 -2
- data/spec/app/formatters/cli_spec.rb +0 -2
- data/spec/app/formatters/json_spec.rb +0 -2
- data/spec/app/models/fantastico_fileslist_spec.rb +0 -1
- data/spec/app/models/headers_spec.rb +0 -1
- data/spec/app/models/interesting_file_spec.rb +0 -2
- data/spec/app/models/robots_txt_spec.rb +0 -1
- data/spec/app/models/version_spec.rb +23 -0
- data/spec/app/models/xml_rpc_spec.rb +0 -1
- data/spec/app/views_spec.rb +0 -2
- data/spec/dummy_finding.rb +21 -0
- data/spec/dummy_independent_finders.rb +25 -0
- data/spec/dummy_unique_finders.rb +32 -0
- data/spec/lib/browser_spec.rb +0 -1
- data/spec/lib/cache/file_store_spec.rb +0 -1
- data/spec/lib/cache/typhoeus_spec.rb +0 -2
- data/spec/lib/cms_scanner_spec.rb +0 -1
- data/spec/lib/controller_spec.rb +0 -2
- data/spec/lib/controllers_spec.rb +0 -2
- data/spec/lib/finders/findings_spec.rb +1 -3
- data/spec/lib/finders/independent_finders_spec.rb +4 -6
- data/spec/lib/finders/unique_finder_spec.rb +24 -0
- data/spec/lib/finders/unique_finders_spec.rb +133 -0
- data/spec/lib/formatter_spec.rb +0 -3
- data/spec/lib/target_spec.rb +0 -2
- data/spec/lib/web_site_spec.rb +0 -3
- data/spec/output/core/finished.cli_no_colour +0 -1
- data/spec/output/interesting_files/empty.cli_no_colour +1 -0
- data/spec/output/interesting_files/findings.cli_no_colour +1 -0
- data/spec/shared_examples/browser_actions.rb +0 -2
- data/spec/shared_examples/finding.rb +21 -1
- data/spec/shared_examples/formatter_buffer.rb +0 -2
- data/spec/shared_examples/independent_finder.rb +1 -3
- data/spec/shared_examples/target/platform/php.rb +0 -1
- data/spec/shared_examples/target/platform/wordpress.rb +0 -2
- data/spec/shared_examples/target/server/apache.rb +0 -1
- data/spec/shared_examples/target/server/generic.rb +0 -1
- data/spec/shared_examples/target/server/iis.rb +0 -1
- data/spec/shared_examples/views/core.rb +0 -1
- data/spec/shared_examples/views/interesting_files.rb +0 -1
- metadata +21 -7
- data/spec/dummy_finders.rb +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0866fc4bfc65ce2c0b92ac2b4d8b0e6d412f0f4e
|
4
|
+
data.tar.gz: d1a849df9cfb4d7e2efb41bf836b62df007e02b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6351f6c0f03e6c4a7983933c723a9f479cc1b9a39d5ff4683930f9bb91b1c6f9b4f087b0ffaa5e193c7fcbfb00bb41317884cd9da25d062d0df4604e416c8e15
|
7
|
+
data.tar.gz: 40fa45e9e46359b1f9b5c818ed470213fe7434c73fdbf93eeed173ea27c5c0f8a3ef589f7c61c510cb6c90ae7da19568947a2d571a5723695dadb32a3a5ed00d
|
@@ -25,9 +25,7 @@ module CMSScanner
|
|
25
25
|
|
26
26
|
# @return [ XMLRPC ]
|
27
27
|
def passive_body(_opts = {})
|
28
|
-
|
29
|
-
|
30
|
-
page.css('link[rel="pingback"]').each do |tag|
|
28
|
+
NS::Browser.get(target.url).html.css('link[rel="pingback"]').each do |tag|
|
31
29
|
url = tag.attribute('href').to_s
|
32
30
|
|
33
31
|
next unless target.in_scope?(url)
|
data/app/models.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
module CMSScanner
|
2
|
+
# Version
|
3
|
+
class Version
|
4
|
+
include NS::Finders::Finding
|
5
|
+
|
6
|
+
attr_reader :number
|
7
|
+
|
8
|
+
def initialize(number, opts = {})
|
9
|
+
@number = number
|
10
|
+
parse_finding_options(opts)
|
11
|
+
end
|
12
|
+
|
13
|
+
def ==(other)
|
14
|
+
number == other.number
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -18,4 +18,4 @@ Interesting Findings: <%= @findings.size %>
|
|
18
18
|
<% end -%>
|
19
19
|
<%= render('_array', a: finding.references, s: 'Reference', p: 'References') -%>
|
20
20
|
<%= render('_array', a: finding.interesting_entries, s: 'Interesting Entry', p: 'Interesting Entries') -%>
|
21
|
-
<% end
|
21
|
+
<% end %>
|
data/cms_scanner.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.version = CMSScanner::VERSION
|
10
10
|
s.platform = Gem::Platform::RUBY
|
11
11
|
s.required_ruby_version = '>= 2.0.0'
|
12
|
-
s.authors = ['WPScanTeam - Erwan
|
12
|
+
s.authors = ['WPScanTeam - Erwan Le Rousseau']
|
13
13
|
s.email = ['erwan.lr@gmail.com']
|
14
14
|
s.summary = 'Experimental CMSScanner'
|
15
15
|
s.description = 'Experimental CMSScanner'
|
@@ -31,7 +31,7 @@ Gem::Specification.new do |s|
|
|
31
31
|
s.add_development_dependency 'rspec', '~> 3.1'
|
32
32
|
s.add_development_dependency 'rspec-its'
|
33
33
|
s.add_development_dependency 'bundler', '~> 1.6'
|
34
|
-
s.add_development_dependency 'rubocop', '~> 0.
|
34
|
+
s.add_development_dependency 'rubocop', '~> 0.28'
|
35
35
|
s.add_development_dependency 'webmock', '>= 1.18'
|
36
36
|
s.add_development_dependency 'simplecov', '~> 0.9'
|
37
37
|
end
|
data/lib/cms_scanner.rb
CHANGED
data/lib/cms_scanner/finders.rb
CHANGED
@@ -3,3 +3,5 @@ require 'cms_scanner/finders/finding'
|
|
3
3
|
require 'cms_scanner/finders/findings'
|
4
4
|
require 'cms_scanner/finders/independent_finders'
|
5
5
|
require 'cms_scanner/finders/independent_finder'
|
6
|
+
require 'cms_scanner/finders/unique_finders'
|
7
|
+
require 'cms_scanner/finders/unique_finder'
|
@@ -32,6 +32,10 @@ module CMSScanner
|
|
32
32
|
def parse_finding_options(opts = {})
|
33
33
|
FINDING_OPTS.each { |opt| send("#{opt}=", opts[opt]) if opts.key?(opt) }
|
34
34
|
end
|
35
|
+
|
36
|
+
def eql?(other)
|
37
|
+
self == other && confidence == other.confidence && found_by == other.found_by
|
38
|
+
end
|
35
39
|
end
|
36
40
|
end
|
37
41
|
end
|
@@ -2,7 +2,7 @@ module CMSScanner
|
|
2
2
|
module Finders
|
3
3
|
# Independent Finders container
|
4
4
|
# This class is designed to handle independent results
|
5
|
-
# which are not related with others
|
5
|
+
# which are not related with each others
|
6
6
|
# e.g: interesting files
|
7
7
|
class IndependentFinders < Array
|
8
8
|
# @return [ Findings ]
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module CMSScanner
|
2
|
+
module Finders
|
3
|
+
# Unique Finder
|
4
|
+
module UniqueFinder
|
5
|
+
def self.included(klass)
|
6
|
+
klass.class_eval do
|
7
|
+
include IndependentFinder
|
8
|
+
|
9
|
+
# @return [ Array ]
|
10
|
+
def finders
|
11
|
+
@finders ||= NS::Finders::UniqueFinders.new
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module CMSScanner
|
2
|
+
module Finders
|
3
|
+
# Unique Finders container
|
4
|
+
#
|
5
|
+
# This class is designed to return a unique result such as a version
|
6
|
+
# Note: Finders contained can return multiple results but the #run will only
|
7
|
+
# returned the best finding
|
8
|
+
class UniqueFinders < IndependentFinders
|
9
|
+
# @param [ Hash ] opts
|
10
|
+
# @option opts [ Symbol ] mode :mixed, :passive or :aggressive
|
11
|
+
# @option opts [ Int ] :confidence_threshold If a finding's confidence reaches this value,
|
12
|
+
# it will be returned as the best finding.
|
13
|
+
# Default is 100.
|
14
|
+
# If <= 0, all finders will be ran.
|
15
|
+
#
|
16
|
+
# @return [ Object ]
|
17
|
+
def run(opts = {})
|
18
|
+
opts[:confidence_threshold] ||= 100
|
19
|
+
|
20
|
+
symbols_from_mode(opts[:mode]).each do |symbol|
|
21
|
+
each do |finder|
|
22
|
+
[*finder.send(symbol, opts)].each do |found|
|
23
|
+
findings << found
|
24
|
+
end
|
25
|
+
|
26
|
+
next if opts[:confidence_threshold] <= 0
|
27
|
+
|
28
|
+
findings.each do |f|
|
29
|
+
return f if f.confidence >= opts[:confidence_threshold]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# results are sorted by confidence ASC
|
35
|
+
findings.sort_by(&:confidence).last
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/cms_scanner/target.rb
CHANGED
@@ -6,6 +6,7 @@ module CMSScanner
|
|
6
6
|
# Target to Scan
|
7
7
|
class Target < WebSite
|
8
8
|
include Server::Generic
|
9
|
+
|
9
10
|
# @note Subdomains are considered out of scope (maybe consider them in ?)
|
10
11
|
# Also, // are handled by Addressable::URI, but worngly :/
|
11
12
|
# e.g: Addressable::URI.parse('//file').host => file
|
@@ -9,12 +9,10 @@ module CMSScanner
|
|
9
9
|
module WordPress
|
10
10
|
include PHP
|
11
11
|
|
12
|
-
WORDPRESS_PATTERN = %r{/(?:(?:wp-content/(?:themes|plugins|
|
12
|
+
WORDPRESS_PATTERN = %r{/(?:(?:wp-content/(?:themes|plugins|uploads))|wp-includes)/}i
|
13
13
|
|
14
14
|
def wordpress?
|
15
|
-
|
16
|
-
|
17
|
-
page.css('script, link').each do |tag|
|
15
|
+
NS::Browser.get(url).html.css('script, link').each do |tag|
|
18
16
|
tag_url = tag.attribute('href').to_s
|
19
17
|
|
20
18
|
next unless in_scope?(tag_url)
|
@@ -14,11 +14,10 @@ module CMSScanner
|
|
14
14
|
# @return [ String ] The wp-content directory
|
15
15
|
def content_dir
|
16
16
|
unless @content_dir
|
17
|
-
page = Nokogiri::HTML(Browser.get(url).body)
|
18
17
|
escaped_url = Regexp.escape(url).gsub(/https?/i, 'https?')
|
19
18
|
pattern = %r{#{escaped_url}(.+?)\/(?:themes|plugins|uploads)\/}i
|
20
19
|
|
21
|
-
|
20
|
+
NS::Browser.get(url).html.css('link,script,style,img').each do |tag|
|
22
21
|
%w(href src).each do |attribute|
|
23
22
|
attr_value = tag.attribute(attribute).to_s
|
24
23
|
|
@@ -30,10 +30,11 @@ module CMSScanner
|
|
30
30
|
def directory_listing_entries(path = nil, params = {})
|
31
31
|
return [] unless directory_listing?(path, params)
|
32
32
|
|
33
|
-
doc = Nokogiri::HTML(NS::Browser.get(url(path), params).body)
|
34
33
|
found = []
|
35
34
|
|
36
|
-
|
35
|
+
NS::Browser.get(url(path), params).html.css('td a').each do |node|
|
36
|
+
found << node.text.to_s
|
37
|
+
end
|
37
38
|
|
38
39
|
found[1..-1] # returns the array w/o the first element 'Parent Directory'
|
39
40
|
end
|
@@ -30,10 +30,9 @@ module CMSScanner
|
|
30
30
|
def directory_listing_entries(path = nil, params = {})
|
31
31
|
return [] unless directory_listing?(path, params)
|
32
32
|
|
33
|
-
doc = Nokogiri::HTML(NS::Browser.get(url(path), params).body)
|
34
33
|
found = []
|
35
34
|
|
36
|
-
|
35
|
+
NS::Browser.get(url(path), params).html.css('pre a').each do |node|
|
37
36
|
entry = node.text.to_s
|
38
37
|
|
39
38
|
next if entry == '[To Parent Directory]'
|
data/lib/cms_scanner/version.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe CMSScanner::Controller::Core do
|
4
|
-
|
5
4
|
subject(:core) { described_class.new }
|
6
5
|
let(:target_url) { 'http://example.com/' }
|
7
6
|
let(:parsed_options) { { url: target_url } }
|
@@ -148,5 +147,4 @@ describe CMSScanner::Controller::Core do
|
|
148
147
|
core.after_scan
|
149
148
|
end
|
150
149
|
end
|
151
|
-
|
152
150
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe CMSScanner::Controller::InterestingFiles do
|
4
|
-
|
5
4
|
subject(:controller) { described_class.new }
|
6
5
|
let(:target_url) { 'http://example.com/' }
|
7
6
|
let(:parsed_options) { { url: target_url } }
|
@@ -46,5 +45,4 @@ describe CMSScanner::Controller::InterestingFiles do
|
|
46
45
|
end
|
47
46
|
end
|
48
47
|
end
|
49
|
-
|
50
48
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe CMSScanner::Finders::InterestingFile::FantasticoFileslist do
|
4
|
-
|
5
4
|
subject(:finder) { described_class.new(target) }
|
6
5
|
let(:target) { CMSScanner::Target.new(url) }
|
7
6
|
let(:url) { 'http://example.com/' }
|
@@ -64,5 +63,4 @@ describe CMSScanner::Finders::InterestingFile::FantasticoFileslist do
|
|
64
63
|
end
|
65
64
|
end
|
66
65
|
end
|
67
|
-
|
68
66
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe CMSScanner::Finders::InterestingFile::Headers do
|
4
|
-
|
5
4
|
subject(:finder) { described_class.new(target) }
|
6
5
|
let(:target) { CMSScanner::Target.new(url) }
|
7
6
|
let(:url) { 'http://example.com/' }
|
@@ -34,5 +33,4 @@ describe CMSScanner::Finders::InterestingFile::Headers do
|
|
34
33
|
end
|
35
34
|
end
|
36
35
|
end
|
37
|
-
|
38
36
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe CMSScanner::Finders::InterestingFile::RobotsTxt do
|
4
|
-
|
5
4
|
subject(:finder) { described_class.new(target) }
|
6
5
|
let(:target) { CMSScanner::Target.new(url) }
|
7
6
|
let(:url) { 'http://example.com/' }
|
@@ -52,5 +51,4 @@ describe CMSScanner::Finders::InterestingFile::RobotsTxt do
|
|
52
51
|
end
|
53
52
|
end
|
54
53
|
end
|
55
|
-
|
56
54
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe CMSScanner::Finders::InterestingFile::SearchReplaceDB2 do
|
4
|
-
|
5
4
|
subject(:finder) { described_class.new(target) }
|
6
5
|
let(:target) { CMSScanner::Target.new(url) }
|
7
6
|
let(:url) { 'http://example.com/' }
|
@@ -51,5 +50,4 @@ describe CMSScanner::Finders::InterestingFile::SearchReplaceDB2 do
|
|
51
50
|
end
|
52
51
|
end
|
53
52
|
end
|
54
|
-
|
55
53
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe CMSScanner::Finders::InterestingFile::XMLRPC do
|
4
|
-
|
5
4
|
subject(:finder) { described_class.new(target) }
|
6
5
|
let(:target) { CMSScanner::Target.new(url) }
|
7
6
|
let(:url) { 'http://ex.lo/' }
|
@@ -134,5 +133,4 @@ describe CMSScanner::Finders::InterestingFile::XMLRPC do
|
|
134
133
|
end
|
135
134
|
end
|
136
135
|
end
|
137
|
-
|
138
136
|
end
|
@@ -1,13 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe CMSScanner::Finders::InterestingFiles do
|
4
|
-
|
5
4
|
it_behaves_like CMSScanner::Finders::IndependentFinder do
|
6
5
|
let(:expected_finders) { %w(Headers RobotsTxt FantasticoFileslist SearchReplaceDB2 XMLRPC) }
|
6
|
+
let(:expected_finders_class) { CMSScanner::Finders::IndependentFinders }
|
7
7
|
end
|
8
8
|
|
9
9
|
subject(:files) { described_class.new(target) }
|
10
10
|
let(:target) { CMSScanner::Target.new(url) }
|
11
11
|
let(:url) { 'http://example.com/' }
|
12
|
-
|
13
12
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe CMSScanner::Formatter::CliNoColour do
|
4
|
-
|
5
4
|
subject(:formatter) { described_class.new }
|
6
5
|
|
7
6
|
describe '#format' do
|
@@ -13,5 +12,4 @@ describe CMSScanner::Formatter::CliNoColour do
|
|
13
12
|
expect(formatter.red('Text')).to eq 'Text'
|
14
13
|
end
|
15
14
|
end
|
16
|
-
|
17
15
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe CMSScanner::Formatter::Cli do
|
4
|
-
|
5
4
|
subject(:formatter) { described_class.new }
|
6
5
|
|
7
6
|
describe '#format' do
|
@@ -17,5 +16,4 @@ describe CMSScanner::Formatter::Cli do
|
|
17
16
|
expect(formatter.green('Another Text')).to eq "\e[32mAnother Text\e[0m"
|
18
17
|
end
|
19
18
|
end
|
20
|
-
|
21
19
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe CMSScanner::Formatter::Json do
|
4
|
-
|
5
4
|
it_behaves_like CMSScanner::Formatter::Buffer
|
6
5
|
|
7
6
|
subject(:formatter) { described_class.new }
|
@@ -29,5 +28,4 @@ describe CMSScanner::Formatter::Json do
|
|
29
28
|
formatter.beautify
|
30
29
|
end
|
31
30
|
end
|
32
|
-
|
33
31
|
end
|