cms_scanner 0.0.41.10 → 0.0.42.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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/app/app.rb +23 -4
  3. data/app/controllers/core.rb +8 -6
  4. data/app/controllers/core/cli_options.rb +2 -0
  5. data/app/controllers/interesting_findings.rb +2 -0
  6. data/app/finders/interesting_findings.rb +2 -0
  7. data/app/finders/interesting_findings/fantastico_fileslist.rb +6 -8
  8. data/app/finders/interesting_findings/headers.rb +3 -1
  9. data/app/finders/interesting_findings/robots_txt.rb +5 -7
  10. data/app/finders/interesting_findings/search_replace_db_2.rb +8 -10
  11. data/app/finders/interesting_findings/xml_rpc.rb +8 -6
  12. data/app/formatters/cli.rb +2 -0
  13. data/app/formatters/cli_no_color.rb +2 -0
  14. data/app/formatters/cli_no_colour.rb +2 -0
  15. data/app/formatters/json.rb +2 -0
  16. data/app/models/fantastico_fileslist.rb +16 -12
  17. data/app/models/headers.rb +29 -25
  18. data/app/models/interesting_finding.rb +44 -40
  19. data/app/models/robots_txt.rb +18 -14
  20. data/app/models/user.rb +25 -21
  21. data/app/models/version.rb +45 -41
  22. data/app/models/xml_rpc.rb +58 -54
  23. data/lib/cms_scanner.rb +5 -85
  24. data/lib/cms_scanner/browser.rb +2 -0
  25. data/lib/cms_scanner/browser/actions.rb +13 -13
  26. data/lib/cms_scanner/browser/options.rb +2 -0
  27. data/lib/cms_scanner/cache/file_store.rb +2 -0
  28. data/lib/cms_scanner/cache/typhoeus.rb +2 -0
  29. data/lib/cms_scanner/controller.rb +2 -0
  30. data/lib/cms_scanner/controllers.rb +3 -1
  31. data/lib/cms_scanner/errors.rb +11 -0
  32. data/lib/cms_scanner/errors/http.rb +52 -51
  33. data/lib/cms_scanner/errors/scan.rb +10 -6
  34. data/lib/cms_scanner/exit_code.rb +2 -0
  35. data/lib/cms_scanner/finders.rb +2 -0
  36. data/lib/cms_scanner/finders/base_finders.rb +2 -0
  37. data/lib/cms_scanner/finders/finder.rb +3 -1
  38. data/lib/cms_scanner/finders/finder/breadth_first_dictionary_attack.rb +3 -1
  39. data/lib/cms_scanner/finders/finder/enumerator.rb +44 -15
  40. data/lib/cms_scanner/finders/finder/fingerprinter.rb +9 -21
  41. data/lib/cms_scanner/finders/finder/smart_url_checker.rb +2 -0
  42. data/lib/cms_scanner/finders/finder/smart_url_checker/findings.rb +2 -0
  43. data/lib/cms_scanner/finders/finding.rb +2 -0
  44. data/lib/cms_scanner/finders/findings.rb +2 -0
  45. data/lib/cms_scanner/finders/independent_finder.rb +2 -0
  46. data/lib/cms_scanner/finders/independent_finders.rb +2 -0
  47. data/lib/cms_scanner/finders/same_type_finder.rb +2 -0
  48. data/lib/cms_scanner/finders/same_type_finders.rb +2 -0
  49. data/lib/cms_scanner/finders/unique_finder.rb +2 -0
  50. data/lib/cms_scanner/finders/unique_finders.rb +2 -0
  51. data/lib/cms_scanner/formatter.rb +2 -0
  52. data/lib/cms_scanner/formatter/buffer.rb +3 -1
  53. data/lib/cms_scanner/helper.rb +2 -0
  54. data/lib/cms_scanner/numeric.rb +2 -0
  55. data/lib/cms_scanner/progressbar_null_output.rb +2 -0
  56. data/lib/cms_scanner/public_suffix/domain.rb +2 -0
  57. data/lib/cms_scanner/references.rb +2 -0
  58. data/lib/cms_scanner/scan.rb +86 -0
  59. data/lib/cms_scanner/target.rb +2 -0
  60. data/lib/cms_scanner/target/hashes.rb +2 -0
  61. data/lib/cms_scanner/target/platform.rb +2 -0
  62. data/lib/cms_scanner/target/platform/php.rb +4 -2
  63. data/lib/cms_scanner/target/scope.rb +2 -0
  64. data/lib/cms_scanner/target/server.rb +2 -0
  65. data/lib/cms_scanner/target/server/apache.rb +2 -0
  66. data/lib/cms_scanner/target/server/generic.rb +2 -0
  67. data/lib/cms_scanner/target/server/iis.rb +2 -0
  68. data/lib/cms_scanner/target/server/nginx.rb +2 -0
  69. data/lib/cms_scanner/typhoeus/hydra.rb +2 -0
  70. data/lib/cms_scanner/typhoeus/response.rb +2 -0
  71. data/lib/cms_scanner/version.rb +3 -1
  72. data/lib/cms_scanner/vulnerability.rb +2 -0
  73. data/lib/cms_scanner/web_site.rb +34 -2
  74. metadata +4 -6
  75. data/app/controllers.rb +0 -2
  76. data/app/finders.rb +0 -1
  77. data/app/formatters.rb +0 -4
  78. data/app/models.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e47006d4ef6041b74990ece7fb987edbe92e4ac12640d12b601cb917fd07384
4
- data.tar.gz: 5c36f333c1a404df5e7a373be1d06dd874d662515ac33171babab21a497161b0
3
+ metadata.gz: 19ca3bad75160815e98141684a64b01032d20ab64b6ad9820bad8ee8312efa6a
4
+ data.tar.gz: 0b26c2137534fea2e6ea40c79944a6db999819c93709239ae3a9786b8358d51e
5
5
  SHA512:
6
- metadata.gz: a9ec0fc35cc97167ff34deccd9f2ecdb20d7be1499ce9e77ec56f2b1f05568a82c5870036cdb54d9faf5a6a1639242f9be27449a927c7b60c605bbcd1c9374c3
7
- data.tar.gz: 61bf5514e607909b1fe92a7afe114f813e2f7ff08cdbf89ba64d27881eb997e6f790fa80fa0050dea4df6aa6f698ae292561bb8b8136c2bbf2e219053f9bae7c
6
+ metadata.gz: 89b98c3e832204d8cf90c6ae034a73c7478bfdd0a25722275f3d131bc578101257a8c471d070a5f3791ac50741579271940bd234ee5e2d0eb24e7eaa497d01be
7
+ data.tar.gz: 4bde15301bb4262dfb0fc6029ad42c0f6ef4617895b84a8e3ef197f6cde7f79196f85264ca840f535b2eedf58c3fb0a55ac75e6e5695ff0893b84c557a4e56b5
data/app/app.rb CHANGED
@@ -1,4 +1,23 @@
1
- require_relative 'formatters'
2
- require_relative 'controllers'
3
- require_relative 'models'
4
- require_relative 'finders'
1
+ # frozen_string_literal: true
2
+
3
+ # Formatters
4
+ require_relative 'formatters/cli'
5
+ require_relative 'formatters/cli_no_colour'
6
+ require_relative 'formatters/cli_no_color'
7
+ require_relative 'formatters/json'
8
+
9
+ # Controllers
10
+ require_relative 'controllers/core'
11
+ require_relative 'controllers/interesting_findings'
12
+
13
+ # Models
14
+ require_relative 'models/interesting_finding'
15
+ require_relative 'models/robots_txt'
16
+ require_relative 'models/fantastico_fileslist'
17
+ require_relative 'models/headers'
18
+ require_relative 'models/xml_rpc'
19
+ require_relative 'models/version'
20
+ require_relative 'models/user'
21
+
22
+ # Finders
23
+ require_relative 'finders/interesting_findings'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'core/cli_options'
2
4
 
3
5
  module CMSScanner
@@ -37,22 +39,22 @@ module CMSScanner
37
39
 
38
40
  case res.code
39
41
  when 0
40
- raise TargetDownError, res
42
+ raise Error::TargetDown, res
41
43
  when 401
42
- raise HTTPAuthRequiredError
44
+ raise Error::HTTPAuthRequired
43
45
  when 403
44
- raise AccessForbiddenError, parsed_options[:random_user_agent]
46
+ raise Error::AccessForbidden, parsed_options[:random_user_agent]
45
47
  when 407
46
- raise ProxyAuthRequiredError
48
+ raise Error::ProxyAuthRequired
47
49
  end
48
50
 
49
51
  # Checks for redirects
50
- # An out of scope redirect will raise an HTTPRedirectError
52
+ # An out of scope redirect will raise an Error::HTTPRedirect
51
53
  effective_url = target.homepage_res.effective_url
52
54
 
53
55
  return if target.in_scope?(effective_url)
54
56
 
55
- raise HTTPRedirectError, effective_url unless parsed_options[:ignore_main_redirect]
57
+ raise Error::HTTPRedirect, effective_url unless parsed_options[:ignore_main_redirect]
56
58
 
57
59
  target.homepage_res = res
58
60
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  module Controller
3
5
  # CLI Options for the Core Controller
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  module Controller
3
5
  # InterestingFindings Controller
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'interesting_findings/headers'
2
4
  require_relative 'interesting_findings/robots_txt'
3
5
  require_relative 'interesting_findings/fantastico_fileslist'
@@ -1,21 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  module Finders
3
5
  module InterestingFindings
4
6
  # FantasticoFileslist finder
5
7
  class FantasticoFileslist < Finder
6
- # @return [ String ] The url of the fantastico_fileslist.txt file
7
- def url
8
- target.url('fantastico_fileslist.txt')
9
- end
10
-
11
8
  # @return [ InterestingFinding ]
12
9
  def aggressive(_opts = {})
13
- res = NS::Browser.get(url)
10
+ path = 'fantastico_fileslist.txt'
11
+ res = target.head_and_get(path)
14
12
 
15
- return unless res&.code == 200 && !res.body.empty?
13
+ return if res.body.strip.empty?
16
14
  return unless res.headers && res.headers['Content-Type'] =~ %r{\Atext/plain}
17
15
 
18
- NS::FantasticoFileslist.new(url, confidence: 70, found_by: found_by)
16
+ NS::Model::FantasticoFileslist.new(target.url(path), confidence: 70, found_by: found_by)
19
17
  end
20
18
  end
21
19
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  module Finders
3
5
  module InterestingFindings
@@ -5,7 +7,7 @@ module CMSScanner
5
7
  class Headers < Finder
6
8
  # @return [ InterestingFinding ]
7
9
  def passive(_opts = {})
8
- r = NS::Headers.new(target.homepage_url, confidence: 100, found_by: found_by)
10
+ r = NS::Model::Headers.new(target.homepage_url, confidence: 100, found_by: found_by)
9
11
 
10
12
  r.interesting_entries.empty? ? nil : r
11
13
  end
@@ -1,20 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  module Finders
3
5
  module InterestingFindings
4
6
  # Robots.txt finder
5
7
  class RobotsTxt < Finder
6
- # @return [ String ] The url of the robots.txt file
7
- def url
8
- target.url('robots.txt')
9
- end
10
-
11
8
  # @return [ InterestingFinding ]
12
9
  def aggressive(_opts = {})
13
- res = NS::Browser.get(url)
10
+ path = 'robots.txt'
11
+ res = target.head_and_get(path)
14
12
 
15
13
  return unless res&.code == 200 && res.body =~ /(?:user-agent|(?:dis)?allow):/i
16
14
 
17
- NS::RobotsTxt.new(url, confidence: 100, found_by: found_by)
15
+ NS::Model::RobotsTxt.new(target.url(path), confidence: 100, found_by: found_by)
18
16
  end
19
17
  end
20
18
  end
@@ -1,22 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  module Finders
3
5
  module InterestingFindings
4
6
  # SearchReplaceDB2 finder
5
7
  class SearchReplaceDB2 < Finder
6
- # @return [ String ] The url to the searchreplacedb2 PHP file
7
- def url
8
- target.url('searchreplacedb2.php')
9
- end
10
-
11
8
  # @return [ InterestingFinding ]
12
9
  def aggressive(_opts = {})
13
- res = NS::Browser.get(url)
10
+ path = 'searchreplacedb2.php'
14
11
 
15
- return unless res&.code == 200 && res.body =~ /by interconnect/i
12
+ return unless target.head_and_get(path).body =~ /by interconnect/i
16
13
 
17
- NS::InterestingFinding.new(url, confidence: 100,
18
- found_by: found_by,
19
- references: references)
14
+ NS::Model::InterestingFinding.new(target.url(path),
15
+ confidence: 100,
16
+ found_by: found_by,
17
+ references: references)
20
18
  end
21
19
 
22
20
  def references
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  module Finders
3
5
  module InterestingFindings
@@ -21,7 +23,7 @@ module CMSScanner
21
23
 
22
24
  potential_urls << url
23
25
 
24
- NS::XMLRPC.new(url, confidence: 30, found_by: 'Headers (Passive Detection)')
26
+ NS::Model::XMLRPC.new(url, confidence: 30, found_by: 'Headers (Passive Detection)')
25
27
  end
26
28
 
27
29
  # @return [ XMLRPC ]
@@ -33,8 +35,8 @@ module CMSScanner
33
35
 
34
36
  potential_urls << url
35
37
 
36
- return NS::XMLRPC.new(url, confidence: 30,
37
- found_by: 'Link Tag (Passive Detection)')
38
+ return NS::Model::XMLRPC.new(url, confidence: 30,
39
+ found_by: 'Link Tag (Passive Detection)')
38
40
  end
39
41
  nil
40
42
  end
@@ -50,9 +52,9 @@ module CMSScanner
50
52
 
51
53
  next unless res&.body =~ /<methodResponse>/i
52
54
 
53
- return NS::XMLRPC.new(potential_url,
54
- confidence: 100,
55
- found_by: DIRECT_ACCESS)
55
+ return NS::Model::XMLRPC.new(potential_url,
56
+ confidence: 100,
57
+ found_by: DIRECT_ACCESS)
56
58
  end
57
59
  nil
58
60
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  module Formatter
3
5
  # CLI Formatter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  module Formatter
3
5
  # Because Reason https://github.com/wpscanteam/CMSScanner/issues/56
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  module Formatter
3
5
  # CLI No Colour Formatter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  module Formatter
3
5
  # JSON Formatter
@@ -1,20 +1,24 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
- # FantasticoFileslist
3
- class FantasticoFileslist < InterestingFinding
4
- # @return [ Array<String> ] The interesting files/dirs detected
5
- def interesting_entries
6
- results = []
4
+ module Model
5
+ # FantasticoFileslist
6
+ class FantasticoFileslist < InterestingFinding
7
+ # @return [ Array<String> ] The interesting files/dirs detected
8
+ def interesting_entries
9
+ results = []
7
10
 
8
- entries.each do |entry|
9
- next unless entry =~ /(?:admin|\.log|\.sql|\.db)/i
11
+ entries.each do |entry|
12
+ next unless entry =~ /(?:admin|\.log|\.sql|\.db)/i
10
13
 
11
- results << entry
14
+ results << entry
15
+ end
16
+ results
12
17
  end
13
- results
14
- end
15
18
 
16
- def references
17
- { url: ['http://www.acunetix.com/vulnerabilities/fantastico-fileslist/'] }
19
+ def references
20
+ { url: ['http://www.acunetix.com/vulnerabilities/fantastico-fileslist/'] }
21
+ end
18
22
  end
19
23
  end
20
24
  end
@@ -1,35 +1,39 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
- # Interesting Headers
3
- class Headers < InterestingFinding
4
- # @return [ Hash ] The headers
5
- def entries
6
- res = NS::Browser.get(url)
7
- return [] unless res&.headers
4
+ module Model
5
+ # Interesting Headers
6
+ class Headers < InterestingFinding
7
+ # @return [ Hash ] The headers
8
+ def entries
9
+ res = NS::Browser.get(url)
10
+ return [] unless res&.headers
8
11
 
9
- res.headers
10
- end
12
+ res.headers
13
+ end
11
14
 
12
- # @return [ Array<String> ] The interesting headers detected
13
- def interesting_entries
14
- results = []
15
+ # @return [ Array<String> ] The interesting headers detected
16
+ def interesting_entries
17
+ results = []
15
18
 
16
- entries.each do |header, value|
17
- next if known_headers.include?(header.downcase)
19
+ entries.each do |header, value|
20
+ next if known_headers.include?(header.downcase)
18
21
 
19
- results << "#{header}: #{[*value].join(', ')}"
22
+ results << "#{header}: #{[*value].join(', ')}"
23
+ end
24
+ results
20
25
  end
21
- results
22
- end
23
26
 
24
- # @return [ Array<String> ] Downcased known headers
25
- def known_headers
26
- %w[
27
- age accept-ranges cache-control content-encoding content-length content-type connection date
28
- etag expires keep-alive location last-modified link pragma set-cookie strict-transport-security
29
- transfer-encoding vary x-cache x-content-security-policy x-content-type-options
30
- x-frame-options x-language x-permitted-cross-domain-policies x-pingback x-varnish
31
- x-webkit-csp x-xss-protection
32
- ]
27
+ # @return [ Array<String> ] Downcased known headers
28
+ def known_headers
29
+ %w[
30
+ age accept-ranges cache-control content-encoding content-length content-type connection date
31
+ etag expires keep-alive location last-modified link pragma set-cookie strict-transport-security
32
+ transfer-encoding vary x-cache x-content-security-policy x-content-type-options
33
+ x-frame-options x-language x-permitted-cross-domain-policies x-pingback x-varnish
34
+ x-webkit-csp x-xss-protection
35
+ ]
36
+ end
33
37
  end
34
38
  end
35
39
  end
@@ -1,44 +1,48 @@
1
- module CMSScanner
2
- # Interesting Finding
3
- class InterestingFinding
4
- include Finders::Finding
5
-
6
- attr_reader :url
7
- attr_writer :to_s
8
-
9
- # @param [ String ] url
10
- # @param [ Hash ] opts
11
- # :to_s (override the to_s method)
12
- # See Finders::Finding for other available options
13
- def initialize(url, opts = {})
14
- @url = url
15
- @to_s = opts[:to_s]
16
-
17
- parse_finding_options(opts)
18
- end
19
-
20
- # @return [ Array<String> ]
21
- def entries
22
- res = NS::Browser.get(url)
23
-
24
- return [] unless res && res.headers['Content-Type'] =~ %r{\Atext/plain;}i
25
-
26
- res.body.split("\n").reject { |s| s.strip.empty? }
27
- end
1
+ # frozen_string_literal: true
28
2
 
29
- # @return [ String ]
30
- def to_s
31
- @to_s || url
32
- end
33
-
34
- # @return [ String ]
35
- def type
36
- @type ||= self.class.to_s.demodulize.underscore
37
- end
38
-
39
- # @return [ Boolean ]
40
- def ==(other)
41
- self.class == other.class && to_s == other.to_s
3
+ module CMSScanner
4
+ module Model
5
+ # Interesting Finding
6
+ class InterestingFinding
7
+ include Finders::Finding
8
+
9
+ attr_reader :url
10
+ attr_writer :to_s
11
+
12
+ # @param [ String ] url
13
+ # @param [ Hash ] opts
14
+ # :to_s (override the to_s method)
15
+ # See Finders::Finding for other available options
16
+ def initialize(url, opts = {})
17
+ @url = url
18
+ @to_s = opts[:to_s]
19
+
20
+ parse_finding_options(opts)
21
+ end
22
+
23
+ # @return [ Array<String> ]
24
+ def entries
25
+ res = NS::Browser.get(url)
26
+
27
+ return [] unless res && res.headers['Content-Type'] =~ %r{\Atext/plain;}i
28
+
29
+ res.body.split("\n").reject { |s| s.strip.empty? }
30
+ end
31
+
32
+ # @return [ String ]
33
+ def to_s
34
+ @to_s || url
35
+ end
36
+
37
+ # @return [ String ]
38
+ def type
39
+ @type ||= self.class.to_s.demodulize.underscore
40
+ end
41
+
42
+ # @return [ Boolean ]
43
+ def ==(other)
44
+ self.class == other.class && to_s == other.to_s
45
+ end
42
46
  end
43
47
  end
44
48
  end