cms_scanner 0.0.41.10 → 0.0.42.0

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