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 user@victim.com. 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("INCLUDE_ORDERING_ERROR

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. '@]*?>.*?@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. Image Editor - <?php echo $_GET['img']; ?> Great! However, protect.inc.php is included. So