Class: RangeScan::Scanner

Inherits:
Object
  • Object
show all
Defined in:
lib/rangescan/scanner.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(headers: {}, host: nil, max_concurrency: nil, port: nil, scheme: "http", timeout: 5, user_agent: nil, verify_ssl: true) ⇒ Scanner

Returns a new instance of Scanner.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/rangescan/scanner.rb', line 25

def initialize(
  headers: {},
  host: nil,
  max_concurrency: nil,
  port: nil,
  scheme: "http",
  timeout: 5,
  user_agent: nil,
  verify_ssl: true
)
  @headers = headers
  @host = host
  @port = port || (scheme == "http" ? 80 : 443)
  @scheme = scheme
  @timeout = timeout
  @user_agent = user_agent
  @verify_ssl = verify_ssl

  @ssl_context = OpenSSL::SSL::SSLContext.new
  @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE unless verify_ssl

  @max_concurrency = max_concurrency || Etc.nprocessors * 8
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



13
14
15
# File 'lib/rangescan/scanner.rb', line 13

def context
  @context
end

#headersObject (readonly)

Returns the value of attribute headers.



14
15
16
# File 'lib/rangescan/scanner.rb', line 14

def headers
  @headers
end

#hostObject (readonly)

Returns the value of attribute host.



15
16
17
# File 'lib/rangescan/scanner.rb', line 15

def host
  @host
end

#max_concurrencyObject (readonly)

Returns the value of attribute max_concurrency.



16
17
18
# File 'lib/rangescan/scanner.rb', line 16

def max_concurrency
  @max_concurrency
end

#portObject (readonly)

Returns the value of attribute port.



17
18
19
# File 'lib/rangescan/scanner.rb', line 17

def port
  @port
end

#processor_countObject (readonly)

Returns the value of attribute processor_count.



18
19
20
# File 'lib/rangescan/scanner.rb', line 18

def processor_count
  @processor_count
end

#schemeObject (readonly)

Returns the value of attribute scheme.



19
20
21
# File 'lib/rangescan/scanner.rb', line 19

def scheme
  @scheme
end

#ssl_contextObject (readonly)

Returns the value of attribute ssl_context.



20
21
22
# File 'lib/rangescan/scanner.rb', line 20

def ssl_context
  @ssl_context
end

#timeoutObject (readonly)

Returns the value of attribute timeout.



21
22
23
# File 'lib/rangescan/scanner.rb', line 21

def timeout
  @timeout
end

#user_agentObject (readonly)

Returns the value of attribute user_agent.



22
23
24
# File 'lib/rangescan/scanner.rb', line 22

def user_agent
  @user_agent
end

#verify_sslObject (readonly)

Returns the value of attribute verify_ssl.



23
24
25
# File 'lib/rangescan/scanner.rb', line 23

def verify_ssl
  @verify_ssl
end

Instance Method Details

#scan(ipv4s) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/rangescan/scanner.rb', line 55

def scan(ipv4s)
  results = []
  Async do
    barrier = Async::Barrier.new
    semaphore = Async::Semaphore.new(max_concurrency, parent: barrier)

    ipv4s.each do |ipv4|
      semaphore.async do
        url = url_for(ipv4)

        endpoint = Async::HTTP::Endpoint.parse(url, ssl_context: ssl_context, timeout: timeout)
        client = Async::HTTP::Client.new(endpoint, retries: 0)
        res = client.get(endpoint.path, default_request_headers)

        headers = res.headers.fields.to_h
        body = res.read || ""

        results << {
          url: url,
          ipv4: ipv4,
          code: res.status,
          headers: Utils.to_utf8(headers),
          body: Utils.to_utf8(body)
        }
      rescue Errno::ECONNRESET, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, EOFError, OpenSSL::SSL::SSLError, Async::TimeoutError
        next
      end
    end
    barrier.wait
  end
  results.compact
end

#url_for(ipv4) ⇒ Object



49
50
51
52
53
# File 'lib/rangescan/scanner.rb', line 49

def url_for(ipv4)
  return "#{scheme}://#{ipv4}" if (port == 80 && scheme == "http") || (port == 443 && scheme == "https")

  "#{scheme}://#{ipv4}:#{port}"
end