lib/ronin/scanners/scanner.rb in ronin-0.2.4 vs lib/ronin/scanners/scanner.rb in ronin-0.3.0

- old
+ new

@@ -1,9 +1,7 @@ # -#-- -# Ronin - A Ruby platform designed for information security and data -# exploration tasks. +# Ronin - A Ruby platform for exploit development and security research. # # Copyright (c) 2006-2009 Hal Brodigan (postmodern.mod3 at gmail.com) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,11 +14,10 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -#++ # require 'ronin/scanners/exceptions/unknown_category' require 'ronin/extensions/meta' @@ -30,20 +27,27 @@ module Scanners module Scanner def self.included(base) base.metaclass_eval do # - # Returns the +Hash+ of the categories and the scanners defined - # for the class. + # The defined categories and their scanners for the class. # + # @return [Hash] + # The categories and the scanners defined for the them within + # the class. + # def scanners @scanners ||= {} end # - # Returns the category names of all defined scanners. + # Collects all categories that the class and ancestors scan + # for. # + # @return [Set] + # The category names of all defined scanners. + # def scans_for names = Set[] ancestors.each do |ancestor| if ancestor.include?(Ronin::Scanners::Scanner) @@ -53,13 +57,20 @@ return names end # - # Returns +true+ if there is a scanner with the specified category - # _name_ was defined, returns +false+ otherwise. + # Specifies whether or not there are scanners defined for the + # specified category. # + # @param [Symbol, String] name + # The name of the category to search for scanners within. + # + # @return [Boolean] + # Specifies whether there is a scanner defined for the + # specified category. + # def scans_for?(name) name = name.to_sym ancestors.each do |ancestor| if ancestor.include?(Ronin::Scanners::Scanner) @@ -69,12 +80,21 @@ return false end # - # Returns all scanner tests in the specified _category_. + # Collects all scanners in the specified category. # + # @param [Symbol, String] name + # The category name to return all scanners for. + # + # @return [Array] + # All scanners in the specified category. + # + # @raise [UnknownCategory] + # No category has the specified name. + # def scanners_in(name) name = name.to_sym unless scans_for?(name) raise(Ronin::Scanners::UnknownCategory,"unknown scanner category #{name}",caller) @@ -92,26 +112,38 @@ return tests end # - # Defines a scanner with the specified category _name_ and - # _block_. + # Defines a scanner in the category for the class. # - # When scanning against a target, a callback for saving results - # and the target object to be scanned will be passed to the - # _block_. + # @param [Symbol, String] name + # The name of the category to define the scanner for. # + # @yield [target, results, (options)] + # The block that will be called when the scanner is ran. + # + # @yieldparam [Object] target + # The target object to scan. + # + # @yieldparam [Proc] results + # A callback for enqueuing results from the scanner in + # real-time. + # + # @yieldparam [Hash] options + # Additional scanner-options that can be used to configure + # the scanning. + # + # @example Defining a scanner for the +:lfi+ category. # scanner(:lfi) do |url,results| - # ... + # # ... # end # - # If the scanner accepts a 3rd argument, it will be passed a - # +Hash+ of configuration options when the scanner is called. - # + # @example Defining a scanner for the +:sqli+ category, that + # accepts additional scanner-options. # scanner(:sqli) do |url,results,options| - # ... + # # ... # end # def scanner(name,&block) method_name = name.to_s.downcase.gsub(/[\s\._-]+/,'_') name = name.to_sym @@ -158,22 +190,40 @@ end end end # - # Runs the scanners in the given _categories_ against each_target. - # If _categories_ is not specified, all categories will be ran - # against each_target. Returns a +Hash+ of results grouped by - # scanner category. + # Runs all scanners in the given categories against +each_target+. + # If no categories are specified, all categories will be ran + # against +each_target+. # - # If a _block_ is given, it will be passed each result and the - # category the result belongs to. + # @param [Hash{Symbol => true,Hash}] categories + # The categories to scan for, with additional per-category + # scanner-options. # + # @return [Hash] + # The results grouped by scanner category. + # + # @yield [category, result] + # The block that may receive the scanner results for categories + # in real-time. + # + # @yieldparam [Symbol] category + # The category the result belongs to. + # + # @yieldparam [Object] result + # The result object enqueued by the scanner. + # + # @example Scanning a specific category. # url.scan(:rfi => true) + # # => {:rfi => [...]} # + # @example Scanning multiple categories, with scanner-options. # url.scan(:lfi => true, :sqli => {:params => ['id', 'catid']}) + # # => {:lfi => [...], :sqli => [...]} # + # @example Receiving scanner results from categories in real-time. # url.scan(:lfi => true, :rfi => true) do |category,result| # puts "[#{category}] #{result.inspect}" # end # def scan(categories={},&block) @@ -228,9 +278,15 @@ # # A place holder method which will call the specified _block_ with # each target object to be scanned. By default, the method will call # the specified _block_ once, simply passing it the +self+ object. + # + # @yield [target] + # The block that will be passed each target object to be scanned. + # + # @yieldparam [Object] target + # The target object to be scanned. # def each_target(&block) block.call(self) end end