Exploiting Serialized XSS in Joomla! (return of the undead CVE)

While reviewing Joomla! Vulnerabilities I felt a glitch inthe matrix. Deja vu had set in and I was working on the same XSS vulnerabilitythat I had written a test for month's prior. The same attack returned to lifeto claim more developer time and possibly victim websites.

The two CVE's were CVE-2012-1117 and CVE-2013-3267 ; they hadsimilar data (or lack thereof) in their vulnerability reports. They were bothXSS attacks via "Unspecified vectors" in the highlight functionality in Joomla!up to 2.5.1 (and again in 2.5.9.) While this is very little data, it was justenough to dig into it and re-create the vulnerability. In this little post Iwill cover the process of reversing PHPto identify 'unspecified' vulnerabilities and in doing so show you a little aboutPHP object serialization attacks.

Using the data about the attack we know, "highlight" pluginand was first fixed in 2.5.1. So westart by diffing the files to see what changed in the new version and findthis:

Screen Shot 2013-06-21 at 10.56.13 AM

We now see some questionable code that pulls in thehighlight value from the GET request, which it expects to be a base64 string.It will then decode the base64, and unserialize() that value and assign it to$terms. The $terms values are what aregetting passed directly into javascript code at the top of the page (and thuswhere the vulnerability is).

Before we continue, I feel I may need to explain what unserialize()does. It is the sister function for serialize(), which converts a PHP valueinto a basic string. This PHP value can be anything (an object, an array, ahash etc…) unseriialize() simplytakes a valid serialized string and converts it back into a PHP object value.In this case, converts the serialized string for an array back into a usablearray value for PHP.

Now we know where the vulnerability exists, exploitingit is as easy as stepping back through the process. We just need to make amalicious base64-encoded-serialized-string to assign to the highlight key valuepair.

The easiest way to do this is to write your ownPHP script that handles each step for you, as shown below:

Screen Shot 2013-06-24 at 9.16.58 AM

Sending the new malicious base64 encoded string tothe site we're attacking shows that it works!

Screen Shot 2013-06-24 at 9.11.36 AM

Here is the applicable HTML source:

Screen Shot 2013-06-21 at 1.50.18 PM

Joomla! developers fixed this in CVE-2012-1117, byadding a check that would sanitize all input through highlight by removinganything that looked like an HTML tag.

The same attack no longer works, and now producesthis HTML:

Screen Shot 2013-06-21 at 1.56.36 PM

There was an oversight with this fix though.Since we're already within a <script> tag, we don't need to inject moreHTML tags. In order to resurrect this vulnerability back from the dead, we justwork around the javascript code to make it execute cleanly, with our newlyadded functions.

Here is a breakdown of what the injected codewould look like, first as the array, then serialized and base64 encoded:

Screen Shot 2013-06-26 at 1.19.10 PM

And the resulting HTML will look like this (note the"window.addEvent( …" is part of the attack, it is what keeps the javascriptfrom failing):

Screen Shot 2013-06-26 at 12.13.31 PM

Which works wonders:

Screen Shot 2013-06-24 at 8.54.54 AM

The fix pushed to address this looks a lot more solid thistime, as they've done away with the serialization and are usinghtmlspecialchars() now. This may be the last we hear of this zombie-esquevulnerability, but we shall see.

Screen Shot 2013-06-24 at 9.31.33 AM

I hope this post shows you that exploiting even"unspecified" vulnerabilities is not that hard to reverse, and sometimes vulnerabilitiescan easily come back from the dead if the fix is not exactly correct. I shouldhave also unveiled a little about how serialization() attacks work, and for those of you who didn't know … hiding inthe shadows, just few lines away from this vulnerability there existed a remotecode execution attack, but that is a story for another time.

Trustwave reserves the right to review all comments in the discussion below. Please note that for security and other reasons, we may not approve comments containing links.