Disclosure: Remote Code Execution Vuln in Disqus
We recently found a security vulnerability in the Disqus Comment System plugin for WordPress. It could, under very specific conditions, allow an attacker to perform arbitrary remote code execution (RCE). In other words, an attacker can do anything he wants with a vulnerable website.
While the flaw itself is very dangerous, it may only be triggered on servers using WordPress with PHP version 5.1.6 or earlier. This also means that only users of WordPress 3.1.4 (or earlier) are vulnerable to it as more recent releases don’t support these older PHP versions.
Knowing that the targeted user base is actually very small, we decided to share our findings publicly now that Disqus released a patch for it (patched version 2.76).
*Every disqus user is still encouraged to upgrade to the latest version asap.
Disqus RCE vulnerability
It all began while analyzing some custom JSON parser, we found the following curious code
function getNextToken($e, &$i, &$state) { $state = IN_NOWHERE; $end = 1; $start = 1; while ( $i < strlen($e) && $end == 1 ) { switch( $e[$i] ) { (...) case "'": $state = IN_STRING; $buf = ""; while ( ++$i && $i < strlen($e) && $e[$i] != '"' ) { if ( $e[$i] == "") $i++; $buf .= $e[$i]; } $i++; return eval('return "'.str_replace('"','"',$buf).'";'); break;
If you do not understand PHP, it is searching for string literal delimiter, so that it can return its value as the next token.
For some reason, the parsed content is returned from an escaped eval() call which is then returned to the caller function. Note that the eval() call in PHP executes any code provided to it. Can you see where it is going?
At this point, we’ve got a potential RCE vector as the string getting returned by the eval() call is doublequoted, which means we could use PHP’s complex variable parsing syntax to get the script to execute any functions we want by using a payload like {${phpinfo()}}.
The Attack Vector
All we needed was to find where our payload should be stored in order for it to get triggered by the vulnerable eval() call. To do this, we had to check whether or not user provided data was processed by the getNextToken() function.
Our first guess was that, given comments sent through Disqus are directly going to their servers, there was probably a way to do the opposite: getting the comments for a given post, from their services.
And we were right. Searching a bit led us to some comments synchronizing functionalities which could be activated by any guest users by adding some parameters to the requested URL, such as
http://somesite.com/?cf_action=sync_comments&post_id=TARGET_POST_ID.
All we needed to do now was to test our findings, which worked as expected. We now that we had a working exploit, all we had to do in order to use it was to:
- Push our payload into some post’s comments
- Get this post’s ID
- Request a comments synchronization by adding the parameters we mentioned earlier to our URL
That’s it, looks simple right? So if you are using an outdated version of WordPress/PHP, you need to update Disqus asap. All other users are also recommended to updated as soon as they can, even considering that this vulnerability does not apply to them.
If your website is behind our Website Firewall you are already being virtually patched.
No comments yet.