Class: CMSScanner::Target

Inherits:
WebSite
  • Object
show all
Includes:
Server::Generic
Defined in:
lib/cms_scanner/target.rb,
lib/cms_scanner/target/scope.rb,
lib/cms_scanner/target/hashes.rb,
lib/cms_scanner/target/server/iis.rb,
lib/cms_scanner/target/platform/php.rb,
lib/cms_scanner/target/server/apache.rb,
lib/cms_scanner/target/server/generic.rb

Overview

Scope system logic

Defined Under Namespace

Modules: Platform, Server Classes: Scope

Instance Attribute Summary

Attributes inherited from WebSite

#opts, #uri

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Server::Generic

#headers, #server

Methods inherited from WebSite

#access_forbidden?, #http_auth?, #online?, #proxy_auth?, #redirection, #url, #url=

Constructor Details

#initialize(url, opts = {}) ⇒ Target

Returns a new instance of Target.

Parameters:

  • url (String)
  • opts (Hash) (defaults to: {})

Options Hash (opts):



15
16
17
18
19
20
# File 'lib/cms_scanner/target.rb', line 15

def initialize(url, opts = {})
  super(url, opts)

  scope << uri.host
  [*opts[:scope]].each { |s| scope << s }
end

Class Method Details

.page_hash(page) ⇒ String

Note:

Comments are deleted to avoid cache generation details

Returns The md5sum of the page.

Parameters:

Returns:

  • (String)

    The md5sum of the page



9
10
11
12
13
# File 'lib/cms_scanner/target/hashes.rb', line 9

def self.page_hash(page)
  page = NS::Browser.get(page, followlocation: true) unless page.is_a?(Typhoeus::Response)

  Digest::MD5.hexdigest(page.body.gsub(/<!--.*?-->/m, ''))
end

Instance Method Details

#comments_from_page(pattern, page = nil) {|MatchData, Nokogiri::XML::Comment| ... } ⇒ Array<Array<MatchData, Nokogiri::XML::Comment>>

Parameters:

Yields:

  • (MatchData, Nokogiri::XML::Comment)

Returns:

  • (Array<Array<MatchData, Nokogiri::XML::Comment>>)


34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/cms_scanner/target.rb', line 34

def comments_from_page(pattern, page = nil)
  page    = NS::Browser.get(url(page)) unless page.is_a?(Typhoeus::Response)
  matches = []

  page.html.xpath('//comment()').each do |node|
    next unless node.text.to_s.strip =~ pattern

    yield Regexp.last_match, node if block_given?

    matches << [Regexp.last_match, node]
  end

  matches
end

#error_404_hashString

Note:

This is used to detect potential custom 404 responding with a 200

Returns The hash of a 404.

Returns:

  • (String)

    The hash of a 404



22
23
24
# File 'lib/cms_scanner/target/hashes.rb', line 22

def error_404_hash
  @error_404_hash ||= self.class.page_hash(non_existant_page_url)
end

#homepage_hashString

Returns The hash of the homepage.

Returns:

  • (String)

    The hash of the homepage



16
17
18
# File 'lib/cms_scanner/target/hashes.rb', line 16

def homepage_hash
  @homepage_hash ||= self.class.page_hash(url)
end

#homepage_or_404?(page) ⇒ Boolean

Returns Wether or not the page is a the homepage or a 404 based on its md5sum.

Parameters:

Returns:

  • (Boolean)

    Wether or not the page is a the homepage or a 404 based on its md5sum



33
34
35
36
37
# File 'lib/cms_scanner/target/hashes.rb', line 33

def homepage_or_404?(page)
  md5sum = self.class.page_hash(page)

  md5sum == homepage_hash || md5sum == error_404_hash
end

#in_scope?(url) ⇒ Boolean

Returns true if the url given is in scope.

Parameters:

  • url (String)

    An absolute URL

Returns:

  • (Boolean)

    true if the url given is in scope



12
13
14
15
16
# File 'lib/cms_scanner/target/scope.rb', line 12

def in_scope?(url)
  scope.include?(Addressable::URI.parse(url.strip).host)
rescue
  false
end

#in_scope_urls(res, xpath = '//link|//script|//style|//img|//a', attributes = %w(href src))) ⇒ Array<String>

Returns The in scope absolute URLs detected in the response’s body.

Parameters:

  • res (Typhoeus::Response)
  • xpath (String) (defaults to: '//link|//script|//style|//img|//a')
  • attributes (Array<String>) (defaults to: %w(href src)))

Returns:

  • (Array<String>)

    The in scope absolute URLs detected in the response’s body



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/cms_scanner/target/scope.rb', line 23

def in_scope_urls(res, xpath = '//link|//script|//style|//img|//a', attributes = %w(href src))
  found = []

  res.html.xpath(xpath).each do |tag|
    attributes.each do |attribute|
      attr_value = tag[attribute]

      next unless attr_value && !attr_value.empty?

      url = uri.join(attr_value.strip).to_s

      next unless in_scope?(url)

      yield url if block_given? && !found.include?(url)
      found << url
    end
  end

  found.uniq
end

#interesting_files(opts = {}) ⇒ Findings

Parameters:

  • opts (Hash) (defaults to: {})

Returns:

  • (Findings)


25
26
27
# File 'lib/cms_scanner/target.rb', line 25

def interesting_files(opts = {})
  @interesting_files ||= NS::Finders::InterestingFiles::Base.find(self, opts)
end

#non_existant_page_urlString

Returns The URL of an unlikely existant page.

Returns:

  • (String)

    The URL of an unlikely existant page



27
28
29
# File 'lib/cms_scanner/target/hashes.rb', line 27

def non_existant_page_url
  uri.join(Digest::MD5.hexdigest(rand(999_999_999).to_s) + '.html').to_s
end

#scopeArray<PublicSuffix::Domain, String>

Returns:



5
6
7
# File 'lib/cms_scanner/target/scope.rb', line 5

def scope
  @scope ||= Scope.new
end