携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情
Apache换行解析漏洞(CVE-2017-15715)
-
影响版本 Apache httpd 2.4.0 ~ 2.4.29
-
原理 apache在修复第一个后缀名解析漏洞时,用正则表达式匹配后缀。在正则表示式中,
$用来匹配字符串字符串结尾位置,但如果设置了RegExp对象的Multiline属性,$也匹配\n或者\rApache通过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 {
?>
只有简短的几行源码,看下basename、pathinfo函数用法
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文件)