class Apullo::Fingerprint::HTTP

Attributes

headers[W]

Public Class Methods

new(target) click to toggle source
Calls superclass method Apullo::Fingerprint::Base::new
# File lib/apullo/fingerprints/http.rb, line 16
def initialize(target)
  super target

  @headers = {}
end

Private Instance Methods

body() click to toggle source
# File lib/apullo/fingerprints/http.rb, line 52
def body
  return {} unless @body

  hash = Hash.new(@body)
  {
    md5: hash.md5,
    mmh3: hash.mmh3,
    sha1: hash.sha1,
    sha256: hash.sha256,
  }
end
build_doc() click to toggle source
# File lib/apullo/fingerprints/http.rb, line 86
def build_doc
  Oga.parse_html(@body)
rescue ArgumentError, LL::ParserError => _e
  nil
end
build_http() click to toggle source
# File lib/apullo/fingerprints/http.rb, line 133
def build_http
  if target.scheme == "http"
    Net::HTTP.start(target.uri.host, target.uri.port)
  else
    Net::HTTP.start(target.uri.host, target.uri.port, use_ssl: true)
  end
end
build_results() click to toggle source
# File lib/apullo/fingerprints/http.rb, line 24
def build_results
  get(target.uri.path)

  {
    body: body,
    cert: cert,
    favicon: favicon,
    headers: response_headers,
    meta: {
      url: target.url,
      links: links
    }
  }
end
cert() click to toggle source
# File lib/apullo/fingerprints/http.rb, line 39
def cert
  return {} unless @peer_cert

  hash = Hash.new(@peer_cert.to_der)
  {
    md5: hash.md5,
    serial: @peer_cert.serial.to_i,
    sha1: hash.sha1,
    sha256: hash.sha256,
  }
end
default_favicon_url() click to toggle source
# File lib/apullo/fingerprints/http.rb, line 82
def default_favicon_url
  "#{target.uri.scheme}://#{target.uri.host}:#{target.uri.port}/favicon.ico"
end
favicon() click to toggle source
# File lib/apullo/fingerprints/http.rb, line 65
def favicon
  url = favicon_url
  return {} unless url

  favicon = Favicon.new(url)
  favicon.results
end
favicon_url() click to toggle source
# File lib/apullo/fingerprints/http.rb, line 92
def favicon_url
  return nil unless @body

  doc = build_doc
  return nil unless doc

  icon = doc.at_css("link[rel='shortcut icon']") || doc.at_css("link[rel='icon']")
  return default_favicon_url unless icon

  href = icon.get("href")
  return default_favicon_url unless href

  return href if href.start_with?("http://", "https://")

  target.url.end_with?("/") ? target.url + href : "#{target.url}/#{href}"
end
get(path, limit: 3) click to toggle source
# File lib/apullo/fingerprints/http.rb, line 109
def get(path, limit: 3)
  http = build_http
  path = path.empty? ? "/" : path
  request = Net::HTTP::Get.new(path, headers)
  response = http.request request

  location = response["Location"]
  if location && limit.positive?
    if location.start_with?("http://", "https://")
      rebuild_target location
      get(target.uri.path)
    else
      get(location, limit: limit - 1)
    end
  else
    @peer_cert = http.peer_cert
    @body = response.body
    @response_headers = response.each_header.to_h
    @path = path
  end
rescue Errno::ECONNREFUSED, Net::HTTPError, OpenSSL::OpenSSLError, Timeout::Error => _e
  nil
end
headers() click to toggle source
# File lib/apullo/fingerprints/http.rb, line 78
def headers
  @headers.compact
end
rebuild_target(url) click to toggle source
# File lib/apullo/fingerprints/http.rb, line 141
def rebuild_target(url)
  @target = Target.new(url)
end
response_headers() click to toggle source
# File lib/apullo/fingerprints/http.rb, line 74
def response_headers
  @response_headers || {}
end