While reviewing Joomla! Vulnerabilities I felt a glitch in the matrix. Deja vu had set in and I was working on the same XSS vulnerability that I had written a test for month’s prior. The same attack returned to life to claim more developer time and possibly victim websites.
The two CVE’s were CVE-2012-1117 and CVE-2013-3267 ; they had similar data (or lack thereof) in their vulnerability reports. They were both XSS 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 just enough to dig into it and re-create the vulnerability. In this little post I will cover the process of reversing PHP to identify ‘unspecified’ vulnerabilities and in doing so show you a little about PHP object serialization attacks.
Using the data about the attack we know, “highlight” plugin and was first fixed in 2.5.1. So we start by diffing the files to see what changed in the new version and find this:
Before we continue, I feel I may need to explain what unserialize() does. It is the sister function for serialize(), which converts a PHP value into a basic string. This PHP value can be anything (an object, an array, a hash etc…) unseriialize() simply takes 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 usable array value for PHP.
Now we know where the vulnerability exists, exploiting it is as easy as stepping back through the process. We just need to make a malicious base64-encoded-serialized-string to assign to the highlight key value pair.
The easiest way to do this is to write your own PHP script that handles each step for you, as shown below:
Sending the new malicious base64 encoded string to the site we’re attacking shows that it works!
Here is the applicable HTML source:
Joomla! developers fixed this in CVE-2012-1117, by adding a check that would sanitize all input through highlight by removing anything that looked like an HTML tag.
The same attack no longer works, and now produces this HTML:
Here is a breakdown of what the injected code would look like, first as the array, then serialized and base64 encoded:
Which works wonders:
The fix pushed to address this looks a lot more solid this time, as they’ve done away with the serialization and are using htmlspecialchars() now. This may be the last we hear of this zombie-esque vulnerability, but we shall see.
I hope this post shows you that exploiting even “unspecified” vulnerabilities is not that hard to reverse, and sometimes vulnerabilities can easily come back from the dead if the fix is not exactly correct. I should have also unveiled a little about how serialization() attacks work, and for those of you who didn’t know … hiding in the shadows, just few lines away from this vulnerability there existed a remote code execution attack, but that is a story for another time.