Class: WpTarget

Inherits:
WebSite show all
Includes:
WpConfigBackup, WpCustomDirectories, WpFullPathDisclosure, WpLoginProtection, WpMustUsePlugins, WpReadme, WpRegistrable
Defined in:
lib/wpscan/wp_target.rb,
lib/wpscan/wp_target/wp_readme.rb,
lib/wpscan/wp_target/wp_registrable.rb,
lib/wpscan/wp_target/wp_config_backup.rb,
lib/wpscan/wp_target/wp_login_protection.rb,
lib/wpscan/wp_target/wp_must_use_plugins.rb,
lib/wpscan/wp_target/wp_custom_directories.rb,
lib/wpscan/wp_target/wp_full_path_disclosure.rb

Defined Under Namespace

Modules: WpConfigBackup, WpCustomDirectories, WpFullPathDisclosure, WpLoginProtection, WpMustUsePlugins, WpReadme, WpRegistrable

Constant Summary

Constants included from WpLoginProtection

WpLoginProtection::LOGIN_PROTECTION_METHOD_PATTERN

Instance Attribute Summary collapse

Attributes inherited from WebSite

#uri

Class Method Summary collapse

Instance Method Summary collapse

Methods included from WpFullPathDisclosure

#full_path_disclosure_url, #has_full_path_disclosure?

Methods included from WpCustomDirectories

#default_wp_content_dir_exists?, #wp_content_dir, #wp_plugins_dir, #wp_plugins_dir_exists?

Methods included from WpLoginProtection

#has_login_protection?, #login_protection_plugin

Methods included from WpMustUsePlugins

#has_must_use_plugins?, #must_use_url

Methods included from WpConfigBackup

#config_backup, config_backup_files

Methods included from WpRegistrable

#multisite?, #registration_enabled?, #registration_url

Methods included from WpReadme

#has_readme?, #readme_url

Methods inherited from WebSite

#error_404_hash, #has_basic_auth?, has_log?, #has_xml_rpc?, #homepage_hash, #online?, page_hash, #redirection, #rss_url, #url, #url=, #xml_rpc_url

Methods included from WebSite::InterestingHeaders

#interesting_headers

Methods included from WebSite::RobotsTxt

#has_robots?, #parse_robots_txt, #robots_url

Constructor Details

#initialize(target_url, options = {}) ⇒ WpTarget


23
24
25
26
27
28
29
30
31
32
# File 'lib/wpscan/wp_target.rb', line 23

def initialize(target_url, options = {})
  super(target_url)

  @verbose        = options[:verbose]
  @wp_content_dir = options[:wp_content_dir]
  @wp_plugins_dir = options[:wp_plugins_dir]
  @multisite      = nil

  Browser.instance.referer = url
end

Instance Attribute Details

#verboseObject (readonly)

Returns the value of attribute verbose


21
22
23
# File 'lib/wpscan/wp_target.rb', line 21

def verbose
  @verbose
end

Class Method Details

.valid_response_codesObject

Valid HTTP return codes


81
82
83
# File 'lib/wpscan/wp_target.rb', line 81

def self.valid_response_codes
  [200, 301, 302, 401, 403, 500, 400]
end

Instance Method Details

#debug_log_urlString


123
124
125
# File 'lib/wpscan/wp_target.rb', line 123

def debug_log_url
  @uri.merge("#{wp_content_dir}/debug.log").to_s
end

#has_debug_log?Boolean


118
119
120
# File 'lib/wpscan/wp_target.rb', line 118

def has_debug_log?
  WebSite.has_log?(debug_log_url, %r{\[[^\]]+\] PHP (?:Warning|Error|Notice):})
end

#has_plugin?(name, version = nil) ⇒ Boolean

The version is not yet considered


107
108
109
110
111
112
113
114
115
# File 'lib/wpscan/wp_target.rb', line 107

def has_plugin?(name, version = nil)
  WpPlugin.new(
    @uri,
    name: name,
    version: version,
    wp_content_dir: wp_content_dir,
    wp_plugins_dir: wp_plugins_dir
  ).exists?
end

#login_urlObject


68
69
70
71
72
73
74
75
76
77
78
# File 'lib/wpscan/wp_target.rb', line 68

def 
  url = @uri.merge('wp-login.php').to_s

  # Let's check if the login url is redirected (to https url for example)
  redirection = redirection(url)
  if redirection
    url = redirection
  end

  url
end

#search_replace_db_2_exists?Boolean


142
143
144
145
# File 'lib/wpscan/wp_target.rb', line 142

def search_replace_db_2_exists?
  resp = Browser.get(search_replace_db_2_url)
  resp.code == 200 && resp.body[%r{by interconnect}i]
end

#search_replace_db_2_urlString

Script for replacing strings in wordpress databases reveals database credentials after hitting submit interconnectit.com/124/search-and-replace-for-wordpress-databases/


137
138
139
# File 'lib/wpscan/wp_target.rb', line 137

def search_replace_db_2_url
  @uri.merge('searchreplacedb2.php').to_s
end

#themeWpTheme

:nocov:


87
88
89
# File 'lib/wpscan/wp_target.rb', line 87

def theme
  WpTheme.find(@uri)
end

#upload_dir_urlString


128
129
130
# File 'lib/wpscan/wp_target.rb', line 128

def upload_dir_url
  @uri.merge("#{wp_content_dir}/uploads/").to_s
end

#upload_directory_listing_enabled?Boolean


147
148
149
# File 'lib/wpscan/wp_target.rb', line 147

def upload_directory_listing_enabled?
  directory_listing_enabled?(upload_dir_url)
end

#version(versions_xml) ⇒ WpVersion

:nocov:


96
97
98
# File 'lib/wpscan/wp_target.rb', line 96

def version(versions_xml)
  WpVersion.find(@uri, wp_content_dir, wp_plugins_dir, versions_xml)
end

#wordpress?Boolean

check if the target website is actually running wordpress.


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
# File 'lib/wpscan/wp_target.rb', line 36

def wordpress?
  wordpress = false

  response = Browser.get_and_follow_location(@uri.to_s)

  # Note: in the future major WPScan version, change the user-agent to see
  # if the response is a 200 ?
  fail "The target is responding with a 403, this might be due to a WAF or a plugin\n" \
        'You should try to supply a valid user-agent via the --user-agent option' if response.code == 403

  if response.body =~ /["'][^"']*\/wp-content\/[^"']*["']/i
    wordpress = true
  else

    if has_xml_rpc?
      wordpress = true
    else
      response = Browser.get_and_follow_location()

      if response.code == 200 && response.body =~ %r{WordPress}i
        wordpress = true
      end
    end
  end

  wordpress
end

#wordpress_hosted?Boolean


64
65
66
# File 'lib/wpscan/wp_target.rb', line 64

def wordpress_hosted?
  @uri.to_s =~ /\.wordpress\.com/i
end