Module: Ronin::Scanners::Scanner

Public Visibility

Public Class Method Summary

included(base)
scanner(name, &block) {|target, results, options| ... }

Defines a scanner in the category for the class.

scanners

The defined categories and their scanners for the class.

Returns: Hash

scanners_in(name)

Collects all scanners in the specified category.

Returns: Array

scans_for

Collects all categories that the class and ancestors scan.

Returns: Set

scans_for?(name)

Specifies whether or not there are scanners defined for the.

Returns: Boolean

Public Instance Method Summary

#scan(categories = {}, &block) {|category, result| ... }

Runs all scanners in the given categories against each_target.

Returns: Hash

Public Class Method Details

included

public included(base)
[View source]


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/ronin/scanners/scanner.rb', line 29

def self.included(base)
  base.metaclass_eval do
    #
    # 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

    #
    # 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)
          names += ancestor.scanners.keys
        end
      end

      return names
    end

    #
    # 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)
          return true if ancestor.scanners.has_key?(name)
        end
      end

      return false
    end

    #
    # 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)
      end

      tests = []

      ancestors.each do |ancestor|
        if ancestor.include?(Ronin::Scanners::Scanner)
          if ancestor.scanners.has_key?(name)
            tests += ancestor.scanners[name]
          end
        end
      end

      return tests
    end

    #
    # Defines a scanner in the category for the class.
    #
    # @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
    #
    # @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

      (scanners[name] ||= []) << block

      class_def("first_#{method_name}") do |*arguments|
        options = case arguments.length
                  when 1
                    arguments.first
                  when 0
                    true
                  else
                    raise(ArgumentError,"wrong number of arguments (#{arguments.length} for 1)",caller)
                  end

        first_result = nil

        scan(name => options) do |category,result|
          first_result = result
          break
        end

        return first_result
      end

      class_def("has_#{method_name}?") do |*arguments|
        !(self.send("first_#{method_name}",*arguments).nil?)
      end

      name = name.to_s

      module_eval %{
        def #{method_name}_scan(options=true,&block)
          results = scan(:#{name.dump} => options) do |category,result|
            block.call(result) if block
          end

          return results[:#{name.dump}]
        end
      }

      return true
    end
  end
end

scanner

public scanner(name, &block) {|target, results, options| ... }

Defines a scanner in the category for the class.

Meta Tags

Examples

Defining a scanner for the :lfi category.

  scanner(:lfi) do |url,results|
    # ...
  end

Defining a scanner for the :sqli category, that

         accepts additional scanner-options.
  scanner(:sqli) do |url,results,options|
    # ...
  end

Parameters:

[Symbol, String] name

The name of the category to define the scanner for.

Yields:

[target, results, (options)]

The block that will be called when the scanner is ran.

Yield Parameters:

[Object] target

The target object to scan.

[Proc] results

A callback for enqueuing results from the scanner in real-time.

[Hash] options

Additional scanner-options that can be used to configure the scanning.

[View source]


147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/ronin/scanners/scanner.rb', line 147

def scanner(name,&block)
  method_name = name.to_s.downcase.gsub(/[\s\._-]+/,'_')
  name = name.to_sym

  (scanners[name] ||= []) << block

  class_def("first_#{method_name}") do |*arguments|
    options = case arguments.length
              when 1
                arguments.first
              when 0
                true
              else
                raise(ArgumentError,"wrong number of arguments (#{arguments.length} for 1)",caller)
              end

    first_result = nil

    scan(name => options) do |category,result|
      first_result = result
      break
    end

    return first_result
  end

  class_def("has_#{method_name}?") do |*arguments|
    !(self.send("first_#{method_name}",*arguments).nil?)
  end

  name = name.to_s

  module_eval %{
    def #{method_name}_scan(options=true,&block)
      results = scan(:#{name.dump} => options) do |category,result|
        block.call(result) if block
      end

      return results[:#{name.dump}]
    end
  }

  return true
end

scanners

public Hash scanners

The defined categories and their scanners for the class.

Meta Tags

Returns:

[Hash]

The categories and the scanners defined for the them within the class.

[View source]


38
39
40
# File 'lib/ronin/scanners/scanner.rb', line 38

def scanners
  @scanners ||= {}
end

scanners_in

public Array scanners_in(name)

Collects all scanners in the specified category.

Meta Tags

Parameters:

[Symbol, String] name

The category name to return all scanners for.

Returns:

[Array]

All scanners in the specified category.

Raises:

[UnknownCategory]

No category has the specified name.

[View source]


96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/ronin/scanners/scanner.rb', line 96

def scanners_in(name)
  name = name.to_sym

  unless scans_for?(name)
    raise(Ronin::Scanners::UnknownCategory,"unknown scanner category #{name}",caller)
  end

  tests = []

  ancestors.each do |ancestor|
    if ancestor.include?(Ronin::Scanners::Scanner)
      if ancestor.scanners.has_key?(name)
        tests += ancestor.scanners[name]
      end
    end
  end

  return tests
end

scans_for

public Set scans_for

Collects all categories that the class and ancestors scan for.

Meta Tags

Returns:

[Set]

The category names of all defined scanners.

[View source]


49
50
51
52
53
54
55
56
57
58
59
# File 'lib/ronin/scanners/scanner.rb', line 49

def scans_for
  names = Set[]

  ancestors.each do |ancestor|
    if ancestor.include?(Ronin::Scanners::Scanner)
      names += ancestor.scanners.keys
    end
  end

  return names
end

scans_for?

public Boolean scans_for?(name)

Specifies whether or not there are scanners defined for the specified category.

Meta Tags

Parameters:

[Symbol, String] name

The name of the category to search for scanners within.

Returns:

[Boolean]

Specifies whether there is a scanner defined for the specified category.

[View source]


72
73
74
75
76
77
78
79
80
81
82
# File 'lib/ronin/scanners/scanner.rb', line 72

def scans_for?(name)
  name = name.to_sym

  ancestors.each do |ancestor|
    if ancestor.include?(Ronin::Scanners::Scanner)
      return true if ancestor.scanners.has_key?(name)
    end
  end

  return false
end

Public Instance Method Details

scan

public Hash scan(categories = {}, &block) {|category, result| ... }

Runs all scanners in the given categories against each_target. If no categories are specified, all categories will be ran against each_target.

Meta Tags

Examples

Scanning a specific category.

  url.scan(:rfi => true)
  # => {:rfi => [...]}

Scanning multiple categories, with scanner-options.

  url.scan(:lfi => true, :sqli => {:params => ['id', 'catid']})
  # => {:lfi => [...], :sqli => [...]}

Receiving scanner results from categories in real-time.

  url.scan(:lfi => true, :rfi => true) do |category,result|
    puts "[#{category}] #{result.inspect}"
  end

Parameters:

[Hash{Symbol =>true,Hash}] categories

The categories to scan for, with additional per-category scanner-options.

Yields:

[category, result]

The block that may receive the scanner results for categories in real-time.

Yield Parameters:

[Symbol] category

The category the result belongs to.

[Object] result

The result object enqueued by the scanner.

Returns:

[Hash]

The results grouped by scanner category.

[View source]


229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/ronin/scanners/scanner.rb', line 229

def scan(categories={},&block)
  tests = {}
  options = {}
  results = {}

  if categories.empty?
    self.class.scans_for.each { |name| categories[name] = true }
  end

  categories.each do |name,opts|
    name = name.to_sym

    if opts
      tests[name] = self.class.scanners_in(name)

      options[name] = if opts.kind_of?(Hash)
        opts
      else
        {}
      end

      results[name] = []
    end
  end

  current_category = nil
  result_callback = lambda { |result|
    results[current_category] << result
    block.call(current_category,result) if block
  }

  each_target do |target|
    tests.each do |name,scanners|
      current_category = name

      scanners.each do |scanner|
        if scanner.arity == 3
          scanner.call(target,result_callback,options[name])
        else
          scanner.call(target,result_callback)
        end
      end
    end
  end

  return results
end

Protected Visibility

Protected Instance Method Summary

#each_target(&block) {|target| ... }

A place holder method which will call the specified block with.

Protected Instance Method Details

each_target

protected each_target(&block) {|target| ... }

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.

Meta Tags

Yields:

[target]

The block that will be passed each target object to be scanned.

Yield Parameters:

[Object] target

The target object to be scanned.

[View source]


290
291
292
# File 'lib/ronin/scanners/scanner.rb', line 290

def each_target(&block)
  block.call(self)
end
Generated on Friday, September 25 2009 at 02:57:19 PM by YARD 0.2.3.5 (ruby-1.8.6).