Class List Method List File List

# Module: WpItems::Detectable

Included in:
  WpItems
Defined in:
  lib/common/collections/wp_items/detectable.rb

## Instance Attribute Summary (collapse)

- - (Object) item_xpath readonly

  Returns the value of attribute item_xpath.

- - (Object) vulns_file readonly

  Returns the value of attribute vulns_file.

## Instance Method Summary (collapse)

- - (WpItems) aggressive_detection(wp_target, options = {})
- - (WpItem) create_item(klass, name, wp_target, vulns_file = nil) protected
- - (Class) item_class protected
- - (WpItems) passive_detection(wp_target, options = {})
- - (ProgressBar) progress_bar(targets_size, options)

  :nocov:.

- - (Hash) request_params protected

  The default request parameters.

- - (Array<WpItem>) targets_items(wp_target, options = {}) protected
- - (WpItem) targets_items_from_file(file, wp_target, item_class, vulns_file) protected
- - (Array<WpItem>) vulnerable_targets_items(wp_target, item_class, vulns_file) protected

## Instance Attribute Details

### - (`Object`) item_xpath (readonly)

Returns the value of attribute item_xpath

    6
    7
    8
    # File 'lib/common/collections/wp_items/detectable.rb', line 6

    def item_xpath
      @item_xpath
    end

### - (`Object`) vulns_file (readonly)

Returns the value of attribute vulns_file

    6
    7
    8
    # File 'lib/common/collections/wp_items/detectable.rb', line 6

    def vulns_file
      @vulns_file
    end

## Instance Method Details

### - (`WpItems`) aggressive_detection(wp_target, options = {})

Parameters:

- wp_target (`WpTarget`)
- options (`Hash`) (defaults to: `{}`)

Options Hash (`options`):

- :show_progression (`Boolean`) —

  Whether or not output the progress bar

- :only_vulnerable (`Boolean`) —

  Only check for vulnerable items

- :exclude_content (`String`)

Returns:

- (`WpItems`)

    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    # File 'lib/common/collections/wp_items/detectable.rb', line 15

    def aggressive_detection(wp_target, options = {})
      browser          = Browser.instance
      hydra            = browser.hydra
      targets          = targets_items(wp_target, options)
      progress_bar     = progress_bar(targets.size, options)
      exist_options    = {
        error_404_hash:  wp_target.error_404_hash,
        homepage_hash:   wp_target.homepage_hash,
        exclude_content: options[:exclude_content] ? %r{#{options[:exclude_content]}} : nil
      }

      # If we only want the vulnerable ones, the passive detection is ignored
      # Otherwise, a passive detection is performed, and results will be merged
      results = options[:only_vulnerable] ? new : passive_detection(wp_target, options)

      targets.each do |target_item|
        request = browser.forge_request(target_item.url, request_params)

        request.on_complete do |response|
          progress_bar.progress += 1 if options[:show_progression]

          if target_item.exists?(exist_options, response)
            if !results.include?(target_item)
              results << target_item
            end
          end
        end

        hydra.queue(request)
      end

      hydra.run
      results.sort!
      results # can't just return results.sort because the #sort returns an array, and we want a WpItems
    end

### - (`WpItem`) create_item(klass, name, wp_target, vulns_file = nil) (protected)

Parameters:

- klass (`Class`)
- name (`String`)
- wp_target (`WpTarget`)
- [ (`Hash`) —

  a customizable set of options

Returns:

- (`WpItem`)

    153
    154
    155
    156
    157
    158
    159
    160
    161
    # File 'lib/common/collections/wp_items/detectable.rb', line 153

    def create_item(klass, name, wp_target, vulns_file = nil)
      klass.new(
        wp_target.uri,
        name:           name,
        vulns_file:     vulns_file,
        wp_content_dir: wp_target.wp_content_dir,
        wp_plugins_dir: wp_target.wp_plugins_dir
      )
    end

### - (`Class`) item_class (protected)

Returns:

- (`Class`)

    186
    187
    188
    # File 'lib/common/collections/wp_items/detectable.rb', line 186

    def item_class
      Object.const_get(self.to_s.gsub(/.$/, ''))
    end

### - (`WpItems`) passive_detection(wp_target, options = {})

Parameters:

- wp_target (`WpTarget`)
- options (`Hash`) (defaults to: `{}`)

Returns:

- (`WpItems`)

    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    # File 'lib/common/collections/wp_items/detectable.rb', line 71

    def passive_detection(wp_target, options = {})
      results      = new
      item_class   = self.item_class
      type         = self.to_s.gsub(/Wp/, '').downcase
      response     = Browser.get(wp_target.url)
      item_options = {
        wp_content_dir: wp_target.wp_content_dir,
        wp_plugins_dir: wp_target.wp_plugins_dir,
        vulns_file:     self.vulns_file
      }

      regex1 = %r{(?:[^=:]+)\s?(?:=|:)\s?(?:"|')[^"']+\\?/}
      regex2 = %r{\\?/}
      regex3 = %r{\\?/([^/\\"']+)\\?(?:/|"|')}

      names = response.body.scan(/#{regex1}#{Regexp.escape(wp_target.wp_content_dir)}#{regex2}#{Regexp.escape(type)}#{regex3}/i)

      names.flatten.uniq.each do |name|
        results << item_class.new(wp_target.uri, item_options.merge(name: name))
      end

      results.sort!
      results
    end

### - (`ProgressBar`) progress_bar(targets_size, options)

:nocov:

Parameters:

- targets_size (`Integer`)
- options (`Hash`)

Returns:

- (`ProgressBar`)

    56
    57
    58
    59
    60
    61
    62
    63
    64
    # File 'lib/common/collections/wp_items/detectable.rb', line 56

    def progress_bar(targets_size, options)
      if options[:show_progression]
        ProgressBar.create(
          format: '%t %a <%B> (%c / %C) %P%% %e',
          title: '  ', # Used to craete a left margin
          total: targets_size
        )
      end
    end

### - (`Hash`) request_params (protected)

The default request parameters

Returns:

- (`Hash`)

    101
    # File 'lib/common/collections/wp_items/detectable.rb', line 101

    def request_params; { cache_ttl: 0, followlocation: true } end

### - (`Array<WpItem>`) targets_items(wp_target, options = {}) (protected)

Parameters:

- wp_target (`WpTarget`)
- options (`options`) (defaults to: `{}`)

Options Hash (`options`):

- :only_vulnerable (`Boolean`)
- :file (`String`) —

  The path to the file containing the targets

Returns:

- (`Array<WpItem>`)

    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    # File 'lib/common/collections/wp_items/detectable.rb', line 109

    def targets_items(wp_target, options = {})
      item_class = self.item_class
      vulns_file = self.vulns_file

      targets = vulnerable_targets_items(wp_target, item_class, vulns_file)

      unless options[:only_vulnerable]
        unless options[:file]
          raise 'A file must be supplied'
        end

        targets += targets_items_from_file(options[:file], wp_target, item_class, vulns_file)
      end

      targets.uniq! { |t| t.name }
      targets.sort_by { rand }
    end

### - (`WpItem`) targets_items_from_file(file, wp_target, item_class, vulns_file) (protected)

Parameters:

- file (`String`)
- wp_target (`WpTarget`)
- item_class (`Class`)
- vulns_file (`String`)

Returns:

- (`WpItem`)

    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    # File 'lib/common/collections/wp_items/detectable.rb', line 169

    def targets_items_from_file(file, wp_target, item_class, vulns_file)
      targets = []

      File.open(file, 'r') do |f|
        f.readlines.collect do |item_name|
          targets << create_item(
            item_class,
            item_name.strip,
            wp_target,
            vulns_file
          )
        end
      end
      targets
    end

### - (`Array<WpItem>`) vulnerable_targets_items(wp_target, item_class, vulns_file) (protected)

Parameters:

- wp_target (`WpTarget`)
- item_class (`Class`)
- vulns_file (`String`)

Returns:

- (`Array<WpItem>`)

    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    # File 'lib/common/collections/wp_items/detectable.rb', line 132

    def vulnerable_targets_items(wp_target, item_class, vulns_file)
      targets = []
      xml     = xml(vulns_file)

      xml.xpath(item_xpath).each do |node|
        targets << create_item(
          item_class,
          node.attribute('name').text,
          wp_target,
          vulns_file
        )
      end
      targets
    end