Class: Fingerprinter::Technologies

Inherits:
Object
  • Object
show all
Defined in:
lib/fingerprinter.rb,
lib/fingerprinter/core/detector.rb

Overview

Technologies : Groups the different detection methods

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Technologies

Returns a new instance of Technologies.



27
28
29
30
# File 'lib/fingerprinter.rb', line 27

def initialize(options = {})
  ScanOptions.build(options)
  @results ||= Concurrent::Hash.new
end

Instance Attribute Details

#http_clientObject (readonly)

Returns the value of attribute http_client.



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

def http_client
  @http_client
end

#resultsObject

Returns the value of attribute results.



24
25
26
# File 'lib/fingerprinter.rb', line 24

def results
  @results
end

Class Method Details

.kbObject



32
33
34
35
36
# File 'lib/fingerprinter.rb', line 32

def self.kb
  @kb ||= {
    inspected: Concurrent::Array.new
  }
end

.meta_detection(doc, regexes, type = 'generator') ⇒ Object



32
33
34
35
36
37
38
39
# File 'lib/fingerprinter/core/detector.rb', line 32

def self.meta_detection(doc, regexes, type = 'generator')
  nodes = doc.xpath("//meta[@name='#{type}']/@content")
  nodes&.each do |node|
    return true if regexes.any? { |regex| node.value.match?(regex) }
  end

  false
end

.response_headers_check(response, regexes) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/fingerprinter/core/detector.rb', line 7

def self.response_headers_check(response, regexes)
  response.headers&.each do |header, value|
    regex = regexes[header.downcase]
    next unless regex

    if value.is_a?(Array)
      return true if value.any? { |v| regex.match?(v) }
    elsif regex.match?(value)
      return true
    end
  end

  false
end

.title_detection(doc, title) ⇒ Object



41
42
43
# File 'lib/fingerprinter/core/detector.rb', line 41

def self.title_detection(doc, title)
  doc.title&.downcase == title.downcase
end

.whole_body_check(response, regexes) ⇒ Object



22
23
24
25
26
27
28
29
30
# File 'lib/fingerprinter/core/detector.rb', line 22

def self.whole_body_check(response, regexes)
  return false if response.body.nil?

  regexes.each do |regex|
    return true if response.body.match?(regex)
  end

  false
end

Instance Method Details

#run(urls) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/fingerprinter.rb', line 38

def run(urls)
  urls.each do |url|
    next if EXCLUSIONS.any? { |exclusion| url.match?(exclusion) }

    response = get_response(url)
    next unless response
    next if wildcard?(response)

    url = effective_url(response, url)
  
    responses = response.redirections
    responses << response

    responses.each do |response|
      doc = Utilities::Parser.doc(response.body)

      results[url] = Concurrent::Array.new
      data = { response:, doc:, url: }
      Technologies.subclasses.each { |technology| results[url] << technology.run(data) }
    end
  end

  results.transform_values! { |v| v.compact.uniq }
  results
end