这几天做中南大学的院赛web题碰到了一道上传题,正好利用到了去年发布的一个cve,虽然漏洞有点鸡肋,但是作为一种姿势了解一下还是不错的,故此记录总结一下
漏洞概述
在Apache 2.4.0到2.4.29版本中使用到了如下的配置信息:
1 | <FilesMatch \.php$> |
这是一个php文件的解析表达式,我们可以注意到$
,这个解析漏洞的根本原因就是这个$
。我们知道$
在正则表达式中用来匹配字符串结尾位置,在菜鸟教程中对正则表达符$
的解释如下:
1 | 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n’ 或 ‘\r’。要匹配 $ 字符本身,请使用 \$。 |
说明了$
是可以匹配到字符串结尾的换行符,也就是说,如果我们此时有个文件后缀名为:.php\n
,Apache是会将其作为php文件进行解析的
漏洞利用
了解了该解析漏洞,我们便可以利用它来绕过上传的黑名单限制,例如存在下面的上传逻辑:
1 |
|
这里使用到了黑名单过滤方式,但是如果我们利用上述漏洞,上传一个文件名为:1.php\x0a
,那么便可以成功绕过黑名单的限制上传php文件
实例演示
实例来自于中南大学的院赛ctf中的一道题,题目名字是upload something
题目页面如下:
上传文件时可以发现,不论正常上传什么文件,login.php都显示bad file
我们抓包可以发现,请求包中额外post一个参数name
这就想到了我们分析的Apache解析漏洞,如果文件名取自$_FILES['file']['name']
,就会自动把换行符去掉,而文件名取自post参数name
中,就能很好的利用到这个解析漏洞
下面我们上传一个包含换行符的文件,这里需要注意只能时\x0a
而不是\x0d\x0a
,\x0d\x0a
的情况是我们直接添加一个换行符,我们利用burp的hex功能在test666.php
后面添加一个\x0a
从响应包中可以看到上传成功了,但是相应页面success.html
中并没有告诉我们上传文件的目录
但是我们在请求包中还可以看到一个参数dir = /upload/
,所以猜测上传目录为·/upload/test666.php%0a
访问成功,最后就是上木马拿shell了
最后我们可以看一下upload.php
的源码:
1 |
|
验证的逻辑就是首先利用正则匹配验证后缀名是否包含了php
,第二步就是利用黑名单过滤,但是由于未过滤php%0a
,并且取post参数name
作为文件名,所以便可以很好的利用到apache的解析漏洞,另外我们还可以看一下apache配置文件,文件目录在/etc/apache2/conf-available/docker-php.conf
:
1 | <FilesMatch \.php$> |
正如我们前面提到的配置文件内容一样,$
能匹配到换行符\x0a
,这就造成了该解析漏洞
总结
这个漏洞利用的条件如下:
- 获取文件名时不能用
$_FILES['file']['name']
,因为他会自动把换行去掉,这一点有点鸡肋 - Apache版本为2.4.0到2.4.29
- 服务器必须是linux系统,因为windows环境下不支持后缀名带有换行符
\x0a
总体上而言,只要取$FILES['file']['name']
作为文件名,就可以无视该解析漏洞,所以该漏洞总体来说实际用处不大,但是由于根本成因在于$
,在以后的其他某些漏洞可以还有利用到的地方,作为一种姿势学习一下还是蛮有趣的。
最后附上参考链接: