Today I decided do analyze on ExpressionEngine which is one of the most popular PHP framework. I’ve download latest version of ExpressionEngine from Ellislab webpage and start my analyze.
During my analysis I came across following file.
system/expressionengine/libraries/Redirect.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); /** * ExpressionEngine - by EllisLab * * @package ExpressionEngine * @author EllisLab Dev Team * @copyright Copyright (c) 2003 - 2014, EllisLab, Inc. * @license http://ellislab.com/expressionengine/user-guide/license.html * @link http://ellislab.com * @since Version 2.0 * @filesource */ // ------------------------------------------------------------------------ /** * URL Redirect * * @package ExpressionEngine * @subpackage Core * @category Core * @author EllisLab Dev Team * @link http://ellislab.com */ if ( ! isset($_GET['URL'])) { exit(); } $_GET['URL'] = str_replace(array("\r", "\r\n", "\n", '%3A','%3a','%2F','%2f'), array('', '', '', ':', ':', '/', '/'), $_GET['URL']); if (strncmp($_GET['URL'], 'http', 4) != 0 && strpos($_GET['URL'], '://') === FALSE && substr($_GET['URL'], 0, 1) != '/') { $_GET['URL'] = "http://".$_GET['URL']; } $_GET['URL'] = str_replace( array('"', "'", ')', '(', ';', '}', '{', 'script%', 'script&', '(', ')'), '', strip_tags($_GET['URL'])); $host = ( ! isset($_SERVER['HTTP_HOST'])) ? '' : (substr($_SERVER['HTTP_HOST'],0,4) == 'www.' ? substr($_SERVER['HTTP_HOST'], 4) : $_SERVER['HTTP_HOST']); $force_redirect = ($request_type != 'CP' && config_item('force_redirect') == TRUE) ? TRUE: FALSE; if ($force_redirect == TRUE OR ( ! isset($_SERVER['HTTP_REFERER']) OR ! stristr($_SERVER['HTTP_REFERER'], $host))) { // Possibly not from our site, so we give the user the option // Of clicking the link or not $str = "<html>\n<head>\n<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>\n<title>Redirect</title>\n</head>\n<body>". "<p>To proceed to the URL you have requested, click the link below:</p>". "<p><a rel=\"nofollow\" href='".$_GET['URL']."'>".$_GET['URL']."</a></p>\n</body>\n</html>"; } else { $str = "<html>\n<head>\n<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>\n<title>Redirect</title>\n". '<meta http-equiv="refresh" content="0; URL='.$_GET['URL'].'">'. "\n</head>\n<body>\n</body>\n</html>"; } exit($str); /* End of file Redirect.php */ /* Location: ./system/expressionengine/libraries/Redirect.php */
As you can see, developers of EE decided to create page in order to notify users about redirection. If you look codes of Redirect.php file you will see that developers already know possible security issues and tried to strip out some characters like quotes etc.
I’ve spend a several minutes in order to bypass str_replace and manage to reach html but I’ve failed. I knew there is a possible way to bypass so I decided to set up test-bed ( http://lab.mehmetince.net/h4ckm3/xss-3/ ) and send them to other security researchers.After few minutes Ashar Javed (thank you for spending your time for that) managed to bypass it! The way of Ashar’s bypass is just brilliant! Solution is Double URL Encode which is tried by me before, now I see my mistake by the way.
Open following url and click on link which will appear end of the page.
http://lab.mehmetince.net/h4ckm3/xss-3/?URL=javascript://www.xss.com?xss=%250aalert%2528/XSS/%2529
Rafay Baloch managed to bypass it too. Thank you for being participant.
http://lab.mehmetince.net/h4ckm3/xss-3/index.php?URL=%3C%20img%20src=x%20onerror=document.body.innerHTML=location.hash%3E#%22%3E%3Cimg%20src=x%20onerror=prompt%281%29%3E
Please take a look Ashar Javed ‘s XSS levels you will learn a lot of stuff about XSS.
FIX
Vulnerability has been patched EE 2.9.0 release.
http://ellislab.com/expressionengine/user-guide/about/changelog.html#version-2-9-0