Module: WpVersion::Findable

Included in:
WpVersion
Defined in:
lib/common/models/wp_version/findable.rb

Instance Method Summary (collapse)

Instance Method Details

- (WpVersion) find(target_uri, wp_content_dir, wp_plugins_dir, versions_xml)

Find the version of the blog designated from target_uri

Parameters:

  • target_uri (URI)
  • wp_content_dir (String)
  • wp_plugins_dir (String)

Returns:



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/common/models/wp_version/findable.rb', line 14

def find(target_uri, wp_content_dir, wp_plugins_dir, versions_xml)
  methods.grep(/find_from_/).each do |method|

    if method === :find_from_advanced_fingerprinting
      version = send(method, target_uri, wp_content_dir, wp_plugins_dir, versions_xml)
    else
      version = send(method, target_uri)
    end

    if version
      return new(target_uri, number: version, found_from: method)
    end
  end
  nil
end

- (String) find_from_advanced_fingerprinting(target_uri, wp_content_dir, wp_plugins_dir, versions_xml) (protected)

Uses data/wp_versions.xml to try to identify a wordpress version.

It does this by using client side file hashing

/!\ Warning : this method might return false positive if the file used for fingerprinting is part of a theme (they can be updated)

Parameters:

  • target_uri (URI)
  • wp_content_dir (String)
  • wp_plugins_dir (String)
  • versions_xml (String)

    The path to the xml containing all versions

Returns:

  • (String)

    The version number



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/common/models/wp_version/findable.rb', line 154

def find_from_advanced_fingerprinting(target_uri, wp_content_dir, wp_plugins_dir, versions_xml)
  xml     = xml(versions_xml)

  # This wp_item will take care of encoding the path
  # and replace variables like $wp-content$ & $wp-plugins$
  wp_item = WpItem.new(target_uri,
                       wp_content_dir: wp_content_dir,
                       wp_plugins_dir: wp_plugins_dir)

  xml.xpath('//file').each do |node|
    wp_item.path = node.attribute('src').text

    response = Browser.get(wp_item.url)
    md5sum = Digest::MD5.hexdigest(response.body)

    node.search('hash').each do |hash|
      if hash.attribute('md5').text == md5sum
        return hash.search('version').text
      end
    end
  end
  nil
end

- (String) find_from_atom_generator(target_uri) (protected)

Attempts to find the WordPress version from, the generator tag in the Atom source.

Parameters:

  • target_uri (URI)

Returns:

  • (String)

    The version number



121
122
123
124
125
126
127
# File 'lib/common/models/wp_version/findable.rb', line 121

def find_from_atom_generator(target_uri)
  scan_url(
    target_uri,
    %r{<generator uri="http://wordpress.org/" version="#{version_pattern}">WordPress</generator>}i,
    'feed/atom/'
  )
end

Attempts to find the WordPress version from the p-links-opml.php file.

Parameters:

  • target_uri (URI)

Returns:

  • (String)

    The version number



211
212
213
214
215
216
217
# File 'lib/common/models/wp_version/findable.rb', line 211

def find_from_links_opml(target_uri)
  scan_url(
    target_uri,
    %r{generator="wordpress/#{version_pattern}"}i,
    'wp-links-opml.php'
  )
end

- (String) find_from_meta_generator(target_uri) (protected)

Attempts to find the wordpress version from, the generator meta tag in the html source.

The meta tag can be removed however it seems, that it is reinstated on upgrade.

Parameters:

  • target_uri (URI)

Returns:

  • (String)

    The version number



68
69
70
71
72
73
# File 'lib/common/models/wp_version/findable.rb', line 68

def find_from_meta_generator(target_uri)
  scan_url(
    target_uri,
    %r{name="generator" content="wordpress #{version_pattern}"}i
  )
end

- (String) find_from_rdf_generator(target_uri) (protected)

Attempts to find WordPress version from, the generator tag in the RDF feed source.

Parameters:

  • target_uri (URI)

Returns:

  • (String)

    The version number



95
96
97
98
99
100
101
# File 'lib/common/models/wp_version/findable.rb', line 95

def find_from_rdf_generator(target_uri)
  scan_url(
    target_uri,
    %r{<admin:generatorAgent rdf:resource="http://wordpress.org/\?v=#{version_pattern}" />}i,
    'feed/rdf/'
  )
end

- (String) find_from_readme(target_uri) (protected)

Attempts to find the WordPress version from the readme.html file.

Parameters:

  • target_uri (URI)

Returns:

  • (String)

    The version number



183
184
185
186
187
188
189
# File 'lib/common/models/wp_version/findable.rb', line 183

def find_from_readme(target_uri)
  scan_url(
    target_uri,
    %r{<br />\sversion #{version_pattern}}i,
    'readme.html'
  )
end

- (String) find_from_rss_generator(target_uri) (protected)

Attempts to find the WordPress version from, the generator tag in the RSS feed source.

Parameters:

  • target_uri (URI)

Returns:

  • (String)

    The version number



81
82
83
84
85
86
87
# File 'lib/common/models/wp_version/findable.rb', line 81

def find_from_rss_generator(target_uri)
  scan_url(
    target_uri,
    %r{<generator>http://wordpress.org/\?v=#{version_pattern}</generator>}i,
    'feed/'
  )
end

- (String) find_from_sitemap_generator(target_uri) (protected)

Attempts to find the WordPress version from the sitemap.xml file.

See: code.google.com/p/wpscan/issues/detail?id=109

Parameters:

  • target_uri (URI)

Returns:

  • (String)

    The version number



198
199
200
201
202
203
204
# File 'lib/common/models/wp_version/findable.rb', line 198

def find_from_sitemap_generator(target_uri)
  scan_url(
    target_uri,
    %r{generator="wordpress/#{version_pattern}"}i,
    'sitemap.xml'
  )
end

- (String) scan_url(target_uri, pattern, path = nil) (protected)

Returns the first match of <pattern> in the body of the url

Parameters:

  • target_uri (URI)
  • pattern (Regex)
  • path (String) (defaults to: nil)

Returns:

  • (String)


46
47
48
49
50
51
# File 'lib/common/models/wp_version/findable.rb', line 46

def scan_url(target_uri, pattern, path = nil)
  url = path ? target_uri.merge(path).to_s : target_uri.to_s
  response = Browser.get_and_follow_location(url)

  response.body[pattern, 1]
end

- (String) version_pattern

Used to check if the version is correct: must contain at least one dot.

Returns:

  • (String)


33
34
35
# File 'lib/common/models/wp_version/findable.rb', line 33

def version_pattern
  '([^\r\n"\']+\.[^\r\n"\']+)'
end