Apache换行解析漏洞(CVE-2017-15715)

1,297 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

Apache换行解析漏洞(CVE-2017-15715)

  • 影响版本 Apache httpd 2.4.0 ~ 2.4.29

  • 原理 apache在修复第一个后缀名解析漏洞时,用正则表达式匹配后缀。在正则表示式中,$用来匹配字符串字符串结尾位置,但如果设置了RegExp对象的Multiline属性,$也匹配\n或者\r

    Apache通过FilesMatch的方式来检查后缀以此来判断是否是php,然后进行解析。

    #httpd解析php文件的表达式
    <FilesMatch .php$>
        SetHandler application/x-httpd-php
    </FilesMatch>
    #<FilesMatch> 中指定的表达式可以将“$”匹配到恶意文件名中的换行符,而不是仅匹配文件名的末尾。这可以在某些文件的上传被外部阻止的环境中被利用,但只能通过匹配文件名的尾随部分
    
  • 编译及运行环境

    cd CVE-2017-15715 
    docker-compose 
    build docker-compose up -d
    

源码

<?php
if(isset($_FILES['file'])) {
    $name = basename($_POST['name']);
    $ext = pathinfo($name,PATHINFO_EXTENSION);
    if(in_array($ext, ['php', 'php3', 'php4', 'php5', 'phtml', 'pht'])) {
        exit('bad file');
    }
    move_uploaded_file($_FILES['file']['tmp_name'], './' . $name);
} else {
​
?>

只有简短的几行源码,看下basenamepathinfo函数用法

basename(path,suffix)

path必需。规定要检查的路径。
suffix可选。规定文件扩展名。如果文件有 suffix,则不会输出这个扩展名。
<?php
$path = "/testweb/home.php";
​
//显示带有文件扩展名的文件名
echo basename($path);
​
//显示不带有文件扩展名的文件名
echo basename($path,".php");
?>

结果

home.php
home

pathinfo(path,options)

path:必需。规定要检查的路径。

options:可选。规定要返回的数组元素。默认是 all。

可能的值:

  • PATHINFO_DIRNAME - 只返回 dirname
  • PATHINFO_BASENAME - 只返回 basename
  • PATHINFO_EXTENSION - 只返回 extension
  • PATHINFO_FILENAME - 只返回 filename

复现

上述函数总结一下就是对我们上传文件名字后缀进行个检测非'php', 'php3', 'php4', 'php5', 'phtml', 'pht'即可

上传个2.php在其后加上换行符($匹配\n,因此通过上传2.php%0A绕过对php的检测)

访问2.php%0A发现绕过了php检测上传成功(FilesMatch中可以匹配换行符所以加上%0A同样可以被解析成PHP文件)