class ViolentRuby::VulnerabilityScanner
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. @author Kent 'picat' Gruber
Create a new Vulnerability Scanner¶ ↑
The Vulnerability Scanner scanner class can be setup in a few flexible ways.
@example Provide no targets, ip addresses or even a file.
scanner = ViolentRuby::VulnerabilityScanner.new
@example Provide targets.
ipaddrs = ['192.168.0.2', '192.168.0.3', '192.168.0.4'] scanner = ViolentRuby::VulnerabilityScanner.new(targets: ipaddrs)
@example Provide a file of known vulnerabilities.
scanner = ViolentRuby::VulnerabilityScanner.new(known_vulnerabilities: "vuln_banners.txt")
@example 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
Banner Grabbing¶ ↑
The Vulnerability Scanner provides a simple banner grabbing method which can be used.
@example 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"
@example 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)
@example 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
Example Usage ¶ ↑
The VulnerabilityScanner
is meant to be easy and flexible to use.
@example 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
@example 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)
Attributes
@attr [Array<String>] known_vulnerabilities
List of known vulnerabilities.
@attr [Array<String>] targets List of target ip addresses.
Public Class Methods
Create a new instance of the vulnerability scanner.
@param [Hash] args The options to create a new Vulnerability Scanner. Very optional. @param args [Array<String>] :targets The targets to work with. @param args [Array<String>] :known_vulnerabilities A file containing known vulnerabilities. @return [VulnerabilityScanner]
# 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
Public Instance Methods
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.
@param [String] banner Target banner to check. @param optional [String] file A file containing vulnerable banners. @return [Boolean]
# 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
@param [String,Array<String>] args Either a banner string or an array of banner strings. @return [void]
# File lib/violent_ruby/vulnerability_scanner/vulnerability_scanner.rb, line 183 def known_vulnerabilities=(args) if File.readable?(args) File.readlines(args[:known_vulnerabilities]).map(&:strip).each do |line| @known_vulnerabilities << line end elsif args.is_a? String @known_vulnerabilities << args elsif args.is_a? Array args.each { |vulnerability| @known_vulnerabilities << vulnerability } end end
Do the scanning!
@param [Hash] args Scan arguments. @param args [String] :ip @see handle_ip
@param args [Array<String>] :ips @see handle_ip
@param args [Integer] :port @see handle_port
@param args [Array<Integer>] :ports @see handle_port
@param args [String] :file @see handle_file
@param args [Integer] :timeout @see handle_timeout
@return [void]
# 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
@param [String,Array<String>] args Either a IP address or an array of IP addresses. @return [void]
# File lib/violent_ruby/vulnerability_scanner/vulnerability_scanner.rb, line 173 def targets=(args) if args.is_a? String @targets << args else args.is_a? Array args.each { |target| @targets << target } end end
Private Instance Methods
@api private This method manages dealing with handling the file
argument for the scan
method in a clean manner.
@param [Hash] args @param args [Integer] :file File containing vulnerable banners. @return [String, Boolean]
# File lib/violent_ruby/vulnerability_scanner/vulnerability_scanner.rb, line 267 def handle_file(args = {}) if args[:file] args[:file] else false end end
@api private This method manages dealing with handling the ip
arguments for the scan
method in a clean manner.
@param [Hash] args @param args [String] :ip Single ip address. @param args [Array<String>] :ips Multiple ip addresses. @return [Array<String>]
# File lib/violent_ruby/vulnerability_scanner/vulnerability_scanner.rb, line 217 def handle_ip(args = {}) if args[:ip] [args[:ip]] elsif args[:ips] args[:ips] else @targets end end
@api private This method manages dealing with handling the port
arguments for the scan
method in a clean manner.
@param [Hash] args @param args [String] :port Single port. @param args [Array<String>] :ips Multiple ports. @return [Array<Integer>]
# File lib/violent_ruby/vulnerability_scanner/vulnerability_scanner.rb, line 235 def handle_port(args = {}) if args[:port] [args[:port]] elsif args[:ports] args[:ports] else [21, 22, 25, 80, 110, 443] end end
@api private This method manages dealing with handling the timeout
argument for the scan
method in a clean manner.
@param [Hash] args @param args [Integer] :timeout Timeout in seconds. @return [Integer]
# File lib/violent_ruby/vulnerability_scanner/vulnerability_scanner.rb, line 252 def handle_timeout(args = {}) if args[:timeout] args[:timeout] else 2 end end
@api private This method manages what is done with the result once we know a vulnerable banner is found.
@param [String] ip @param [Integer] port @param [String] banner @return [Hash]
# File lib/violent_ruby/vulnerability_scanner/vulnerability_scanner.rb, line 205 def result(ip, port, banner) {ip: ip, port: port, banner: banner} end