Advisory

ACE via file inclusion in Redirection allows admins to execute any PHP file in the filesystem

Overview

If logged in as an administrator of any WordPress blog on a WordPress multisite, you can run arbitrary code and completely compromise the system by using the setup page for the Redirection plugin.

This is done by writing the URL to redirect to in the format file://path/to/file/here. Unfortunately the plugin executes any PHP within that file. This means that any file with any extension on the filesystem that contains a small amount of user controlled data can be turned into a back door. The plugin also has the functionality to create files and place user controlled data in them. This results in attacker controlled code running and complete compromise of the system.

When the code for handling a redirect looks at the URL to redirect to it does the following:

    class Pass_Action extends Red_Action {
        function process_before( $code, $target ) {
            // Determine what we are passing to: local URL, remote URL, file
            if ( substr( $target, 0, 7 ) === 'http://' || substr( $target, 0, 8 ) === 'https://' ) {
                echo @wp_remote_fopen( $target );
                die();
            }
            else if ( substr( $target, 0, 7 ) === 'file://' ) {
                $parts = explode( '?', substr( $target, 7 ) );
                if ( count( $parts ) > 1 ) {
                    // Put parameters into the environment $args = explode( '&', $parts[1] );
                    if ( count( $args ) > 0 ) {
                        foreach ( $args as $arg ) {
                            $tmp = explode( '=', $arg );
                            if ( count( $tmp ) === 1 )
                                $_GET[ $arg ] = '';
                            else
                                $_GET[ $tmp[0] ] = $tmp[1];
                        }
                    }
                }

                include( $parts[0] );
                exit();
            }
            else {
                $_SERVER['REQUEST_URI'] = $target;
                if ( strpos( $target, '?' ) ) {
                    $_SERVER['QUERY_STRING'] = substr( $target, strpos( $target, '?' ) + 1 );
                    parse_str( $_SERVER['QUERY_STRING'], $_GET );
                }
            }

            return true;
        }
    }

The above code behaves as expected if the URL to redirect to is an HTTP or HTTPS URL.

If the URL begins with file://, it passes the path to the include function.

Its also worth mentioning that if the URL is not HTTP, HTTPS or File, then the code allows the $_GET parameter to be contaminated with unescaped values, which may result in SQL injections.

Proof of concept

  1. echo ‘<?php phpinfo();’ > dog-meme.jpg
  2. Visit /wp-admin/media-new.php
  3. Upload dog-meme.jpg
  4. Copy the URL of the file (i.e. http://localhost/wp-content/uploads/2017/10/dog-meme.jpg)
  5. Visit /wp-admin/tools.php?page=redirection.php
  6. Fill “Source URL” with “/test”
  7. Fill “Target URL” with “file:///var/www/html/wp-content/uploads/2017/10/dog-meme.jpg” (this will probably require some modification if your WP installation is at a different path or dog-meme.jpg is saved in a different directory)
  8. Set “Group” to “Redirections”
  9. Press “Add Redirect”
  10. Press “Edit” on the newly added redirect
  11. Press the cog icon
  12. Set “When matched” to “Pass-through”
  13. Press “Save”

Mitigation/further actions

Upgrade to version 2.8 or later.

Advisory timeline

  1. 2017-10-02: Discovered
  2. 2017-10-03: Reported via website contact form
  3. 2017-10-04: Response received. Plugin author reports this as intended behaviour, as it is assumed that the administrator has full access to the system. However, also future version will include a fix.
  4. 2017-10-18: Author reported fixed in 2.8
  5. 2018-06-12: Advisory published
  6. 2018-06-12: CVE requested
  7. 2018-06-23: CVE assigned

CVSS

Base score 9.1
Attack vector Network
Attack complexity Low
Privileges required High
User interaction None
Scope Changed
Confidentiality High
Integrity High
Availability High

Metadata

  • Severity
    Critical (base score 9.1)
  • Discovered by
    Glyn Wintle
  • Severity
    High
  • Advisory ID
    dxw-2017-3358
  • CVE
    CVE-2018-1000504
  • Component/package
    Redirection
  • Version
    2.7.3
  • Published
    2018-06-06