Module: WPScan::Target::Platform::WordPress

Includes:
CMSScanner::Target::Platform::PHP
Included in:
WPScan::Target
Defined in:
lib/wpscan/target/platform/wordpress.rb,
lib/wpscan/target/platform/wordpress/custom_directories.rb

Overview

wp-content & plugins directory implementation

Constant Summary collapse

WORDPRESS_PATTERN =
%r{/(?:(?:wp-content/(?:themes|(?:mu\-)?plugins|uploads))|wp-includes)/}i

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#mu_pluginsObject Also known as: mu_plugins?

These methods are used in the associated interesting_findings finders to keep the boolean state of the finding rather than re-check the whole thing again



16
17
18
# File 'lib/wpscan/target/platform/wordpress.rb', line 16

def mu_plugins
  @mu_plugins
end

#multisiteObject Also known as: multisite?

These methods are used in the associated interesting_findings finders to keep the boolean state of the finding rather than re-check the whole thing again



16
17
18
# File 'lib/wpscan/target/platform/wordpress.rb', line 16

def multisite
  @multisite
end

#registration_enabledObject Also known as: registration_enabled?

These methods are used in the associated interesting_findings finders to keep the boolean state of the finding rather than re-check the whole thing again



16
17
18
# File 'lib/wpscan/target/platform/wordpress.rb', line 16

def registration_enabled
  @registration_enabled
end

Instance Method Details

#content_dirString

Returns The wp-content directory.

Returns:

  • (String)

    The wp-content directory



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/wpscan/target/platform/wordpress/custom_directories.rb', line 15

def content_dir
  unless @content_dir
    escaped_url = Regexp.escape(url).gsub(/https?/i, 'https?')
    pattern     = %r{#{escaped_url}(.+?)\/(?:themes|plugins|uploads)\/}i

    in_scope_urls(homepage_res) do |url|
      return @content_dir = Regexp.last_match[1] if url.match(pattern)
    end
  end

  @content_dir
end

#content_dir=(dir) ⇒ Object



6
7
8
# File 'lib/wpscan/target/platform/wordpress/custom_directories.rb', line 6

def content_dir=(dir)
  @content_dir = dir.chomp('/')
end

#content_uriAddressable::URI

Returns:

  • (Addressable::URI)


29
30
31
# File 'lib/wpscan/target/platform/wordpress/custom_directories.rb', line 29

def content_uri
  uri.join("#{content_dir}/")
end

#content_urlString

Returns:

  • (String)


34
35
36
# File 'lib/wpscan/target/platform/wordpress/custom_directories.rb', line 34

def content_url
  content_uri.to_s
end

#do_login(username, password) ⇒ Typhoeus::Response

Parameters:

  • username (String)
  • password (String)

Returns:

  • (Typhoeus::Response)


51
52
53
# File 'lib/wpscan/target/platform/wordpress.rb', line 51

def (username, password)
  (username, password).run
end

#login_request(username, password) ⇒ Typhoeus::Request

Parameters:

  • username (String)
  • password (String)

Returns:

  • (Typhoeus::Request)


59
60
61
62
63
64
65
# File 'lib/wpscan/target/platform/wordpress.rb', line 59

def (username, password)
  Browser.instance.forge_request(
    ,
    method: :post,
    body: { log: username, pwd: password }
  )
end

#login_urlString

Returns The URL to the login page.

Returns:

  • (String)

    The URL to the login page



68
69
70
# File 'lib/wpscan/target/platform/wordpress.rb', line 68

def 
  url('wp-login.php')
end

#plugins_dirString

Returns:

  • (String)


39
40
41
# File 'lib/wpscan/target/platform/wordpress/custom_directories.rb', line 39

def plugins_dir
  @plugins_dir ||= "#{content_dir}/plugins"
end

#plugins_dir=(dir) ⇒ Object



10
11
12
# File 'lib/wpscan/target/platform/wordpress/custom_directories.rb', line 10

def plugins_dir=(dir)
  @plugins_dir = dir.chomp('/')
end

#plugins_uriAddressable::URI

Returns:

  • (Addressable::URI)


44
45
46
# File 'lib/wpscan/target/platform/wordpress/custom_directories.rb', line 44

def plugins_uri
  uri.join("#{plugins_dir}/")
end

#plugins_urlString

Returns:

  • (String)


49
50
51
# File 'lib/wpscan/target/platform/wordpress/custom_directories.rb', line 49

def plugins_url
  plugins_uri.to_s
end

#registration_urlString

Returns:

  • (String)


39
40
41
# File 'lib/wpscan/target/platform/wordpress.rb', line 39

def registration_url
  multisite? ? url('wp-signup.php') : url('wp-login.php?action=register')
end

#sub_dirString, False

TODO: Factorise the code and the content_dir one ? @note: nil can not be returned here, otherwise if there is no sub_dir

the check would be done each time

Returns:

  • (String, False)

    The sub_dir is found, false otherwise



57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/wpscan/target/platform/wordpress/custom_directories.rb', line 57

def sub_dir
  unless @sub_dir
    escaped_url = Regexp.escape(url).gsub(/https?/i, 'https?')
    pattern     = %r{#{escaped_url}(.+?)\/(?:xmlrpc\.php|wp\-includes\/)}i

    in_scope_urls(homepage_res) do |url|
      return @sub_dir = Regexp.last_match[1] if url.match(pattern)
    end

    @sub_dir = false
  end

  @sub_dir
end

#url(path = nil) ⇒ String

Override of the WebSite#url to consider the custom WP directories

Parameters:

  • path (String) (defaults to: nil)

    Optional path to merge with the uri

Returns:

  • (String)


77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/wpscan/target/platform/wordpress/custom_directories.rb', line 77

def url(path = nil)
  return @uri.to_s unless path

  if path =~ %r{wp\-content/plugins}i
    path.gsub!('wp-content/plugins', plugins_dir)
  elsif path =~ /wp\-content/i
    path.gsub!('wp-content', content_dir)
  elsif path[0] != '/' && sub_dir
    path = "#{sub_dir}/#{path}"
  end

  super(path)
end

#wordpress?Boolean

Returns:

  • (Boolean)


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/wpscan/target/platform/wordpress.rb', line 22

def wordpress?
  # res = Browser.get(url)

  in_scope_urls(homepage_res) do |url|
    return true if Addressable::URI.parse(url).path.match(WORDPRESS_PATTERN)
  end

  homepage_res.html.css('meta[name="generator"]').each do |node|
    return true if node['content'] =~ /wordpress/i
  end

  return true unless comments_from_page(/wordpress/i, homepage_res).empty?

  false
end

#wordpress_hosted?Boolean

Returns:

  • (Boolean)


43
44
45
# File 'lib/wpscan/target/platform/wordpress.rb', line 43

def wordpress_hosted?
  uri.host =~ /wordpress.com$/i ? true : false
end