Class: ViolentRuby::VulnerabilityScanner

Inherits:
Object
  • Object
show all
Defined in:
lib/violent_ruby/vulnerability_scanner/vulnerability_scanner.rb

Overview

Vulnerability Scanner provides a friendly interface to easily manage banner grabbing targets to match a list of known vulnerable services that we want to identify.

Create a new Vulnerability Scanner

The Vulnerability Scanner scanner class can be setup in a few flexible ways.

Banner Grabbing

The Vulnerability Scanner provides a simple banner grabbing method which can be used.

Example Usage

The VulnerabilityScanner is meant to be easy and flexible to use.

Examples:

Provide no targets, ip addresses or even a file.

scanner = ViolentRuby::VulnerabilityScanner.new

Provide targets.

ipaddrs = ['192.168.0.2', '192.168.0.3', '192.168.0.4']
scanner = ViolentRuby::VulnerabilityScanner.new(targets: ipaddrs)

Provide a file of known vulnerabilities.

scanner = ViolentRuby::VulnerabilityScanner.new(known_vulnerabilities: "vuln_banners.txt")

Just set targets and provide a file later.

scanner = ViolentRuby::VulnerabilityScanner.new
['192.168.0.2', '192.168.0.3'].each do |ip|
  scanner.targets << ip
end
scanner.targets
# => ['192.168.0.2', '192.168.0.3']
File.readlines("vuln_banners.txt").map(&:strip).each |banner|
  scanner.known_vulnerabilities << banner
end
# => ['MS-IIS WEB SERVER 4.0', 'MS-IIS WEB SERVER 5.0']
scanner.scan

Connect to 192.168.0.2 on port 8080

scanner = ViolentRuby::VulnerabilityScanner.new

# If no banner, or hit timeout.
scanner.retrieve_banner('192.168.0.2', 8080)
# => false 

# If banner exists.
scanner.retrieve_banner('192.168.0.2', 80)
# => "MS-IIS WEB SERVER 5.0"

Connect to 192.168.0.2 on port 8080, trying for 10 seconds

scanner = ViolentRuby::VulnerabilityScanner.new
scanner.retrieve_banner('192.168.0.2', 8080, 10)

Connect to 192.168.0.2 on port 8080, with a given block

scanner = ViolentRuby::VulnerabilityScanner.new
scanner.retrieve_banner('192.168.0.2', 8080) do |banner|
  # do something with banner ( false if none found )
  if banner
    puts "Banner found: " + banner
  else
    puts "Banner not found."
  end
end

Basic

require 'violent_ruby'
config  = { targets: ['192.168.0.2', '192.168.0.3' ], known_vulnerabilities: 'vulns.txt' }
scanner = ViolentRuby::VulnerabilityScanner.new(config)
scanner.scan

Advanced (sort’a)

require 'violent_ruby'
scanner = ViolentRuby::VulnerabilityScanner.new
scanner.targets = ['192.168.0.2', '192.168.0.3' ]
scanner.known_vulnerabilities = 'vulns.txt'
scanner.scan(port: 8080) 

Author:

  • Kent ‘picat’ Gruber

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ VulnerabilityScanner

Create a new instance of the vulnerability scanner.

Parameters:

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

    The options to create a new Vulnerability Scanner. Very optional.

  • args (Array<String>) (defaults to: {})

    :targets The targets to work with.

  • args (Array<String>) (defaults to: {})

    :known_vulnerabilities A file containing known vulnerabilities.



93
94
95
96
97
98
# File 'lib/violent_ruby/vulnerability_scanner/vulnerability_scanner.rb', line 93

def initialize(args = {})
  @targets                   = []
  @known_vulnerabilities     = [] 
  self.targets               = args[:targets] if args[:targets]
  self.known_vulnerabilities = args[:known_vulnerabilities] if args[:known_vulnerabilities]
end

Instance Attribute Details

#known_vulnerabilitiesObject



85
86
87
# File 'lib/violent_ruby/vulnerability_scanner/vulnerability_scanner.rb', line 85

def known_vulnerabilities
  @known_vulnerabilities
end

#targetsObject



83
84
85
# File 'lib/violent_ruby/vulnerability_scanner/vulnerability_scanner.rb', line 83

def targets
  @targets
end

Instance Method Details

#check_vulnerabilities(banner, file = false) ⇒ Boolean Also known as: vulnerable?

Check if a given banner is included in a given file which should contain a list of vulnerable banners to match against in order to determine vulnerabilities.

Parameters:

  • banner (String)

    Target banner to check.

  • optional (String)

    file A file containing vulnerable banners.

Returns:

  • (Boolean)


129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/violent_ruby/vulnerability_scanner/vulnerability_scanner.rb', line 129

def check_vulnerabilities(banner, file = false)
  if file
    File.readlines(file).map(&:strip).each do |line|
      return true if line.match?(banner)
    end
  else
    @known_vulnerabilities.each do |vulnerability|
      return true if vulnerability.match?(banner)
    end
  end
  false
end

#retrieve_banner(ip, port, seconds = 2) ⇒ String, Boolean

Retrieve a banner from a given ip and port for a given ammount of seconds, or default for two seconds.

Parameters:

  • ip (String)

    Target ip address.

  • port (Integer)

    Target port number.

  • seconds (Integer) (defaults to: 2)

    Timeout value.

Returns:

  • (String, Boolean)


107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/violent_ruby/vulnerability_scanner/vulnerability_scanner.rb', line 107

def retrieve_banner(ip, port, seconds = 2)
  banner = false
  Timeout.timeout(seconds) do 
    socket = TCPSocket.new(ip, port)
    banner = socket.recv(1024)
    socket.close
  end
  return false unless banner
  banner.strip!
  yield banner if block_given?
  banner
rescue
  false
end

#scan(args = {}) ⇒ void

This method returns an undefined value.

Do the scanning!

Parameters:

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

    Scan arguments.

  • args (String) (defaults to: {})

    :ip @see handle_ip

  • args (Array<String>) (defaults to: {})

    :ips @see handle_ip

  • args (Integer) (defaults to: {})

    :port @see handle_port

  • args (Array<Integer>) (defaults to: {})

    :ports @see handle_port

  • args (String) (defaults to: {})

    :file @see handle_file

  • args (Integer) (defaults to: {})

    :timeout @see handle_timeout



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/violent_ruby/vulnerability_scanner/vulnerability_scanner.rb', line 155

def scan(args = {})
  ip_addrs = handle_ip(args)
  ports    = handle_port(args)
  timeout  = handle_timeout(args)
  file     = handle_file(args)
  results  = []
  ip_addrs.each do |ip|
    ports.each do |port|
      retrieve_banner(ip, port, timeout) do |banner|
        results << result(ip, port, banner) if vulnerable?(banner, file)
      end
    end
  end
  results
end