概述
程序开发人员一般会把重复使用的函数写到单个文件中,需要使用某个函数时直接调用此文件,而无需 再次编写,这种文件调用的过程一般被称为文件包含。程序开发人员一般希望代码更灵活,所以将被包 含的文件设置为变量,用来进行动态调用,但正是由于这种灵活性,从而导致客户端可以调用一个恶意 文件,造成文件包含漏洞。 在通过PHP的函数引入文件时,由于传入的文件名没有经过合理的校验,从而操作了预想之外的文件, 导致意外的文件泄露甚至恶意的代码注入。
分类
本地文件包含
只能包含本地服务器上存在的文件。 用户对输入可控且无过滤 可以利用相对路径或绝对路径读取系统敏感文件
远程文件包含
包含远程服务器上的文件。 需要php.ini开启了allow_url_fopen和allow_url_include的配置。包含的文件是第三方服务器(比如: 攻击者自己搭建的一个Web服务器)的文件。 allow_url_fopen=On (默认为On) 规定是否允许从远程服务器或者网站检索数据 allow_url_include=On (php5.2之后默认为Off) 规定是否允许include/require远程文件
远程与本地包含的区别
本地文件包含就是通过浏览器包含web服务器上的文件,这种漏洞是因为浏览器包含文件时没有进行严 格的过滤,允许遍历目录的字符注入浏览器并执行。 远程文件包含就是允许攻击者包含一个远程的文件,一般是在远程服务器上预先设置好的脚本并对外开 放一个web服务,以确保该脚本能被访问到。此漏洞是因为浏览器对用户的输入没有进行检查,导致不 同程度的信息泄露、拒绝服务攻击,甚至在目标服务器上执行代码。 本地文件包含与远程文件有着相同的原理,但前者只能包含服务器上存在的文件,而后者可以包含远程 服务器上的文件。
PHP中文件包含函数有以下四种
require() include() require_once() include_once() nclude和require区别主要是,include在包含的过程中如果出现错误,会抛出一个警告,程序继续正常 运行;而require函数出现错误的时候,会直接报错并退出程序的执行。 而include_once(),require_once()这两个函数,与前两个的不同之处在于这两个函数只包含一次。适 用于在脚本执行期间同一个文件有可能被包括超过一次的情况下,想确保它只被包括一次以避免函数重 定义,变量重新赋值等问题。
URL中如果出现了如下内容就可能存在文件包含漏洞 ?page= ?file= ?home=
常见的敏感信息路径
windows系统
c:\boot.ini // 查看系统版本 c:\windows\system32\inetsrc\MetaBase.xml //IIS配置文件 c:\windows\repair\sam //存储windows系统初次安装的密码 c:\programFiles\mysql\my.ini //MYSQL root密码 c:\windows\php.ini // php 配置信息
Linux/Unix系统
/etc/passwd // 账户信息 /etc/shadow // 账户密码文件 /usr/local/app/apache2/conf/httpd.conf // Apache2默认配置文件 /usr/local/app/apache2/conf/extra/httpd-vhost.conf // 虚拟网站配置 /usr/local/app/php5/lib/php.ini // PHP相关配置 /etc/httpd/conf/httpd.conf // Apache配置文件 /etc/my.conf // mysql 配置文件
如何发现文件包含漏洞
1、观察URL链接是否包括以下类似的关键字:page/include/path/file/link/url等,如果有,则可能 存在文件包含漏洞; 2、可以观察在URL中,出现的赋值参数等号后跟的信息,是否为一个文件,如果是,则可能存在文件 包含漏洞; 3、在关键字处或明显被文件赋值的参数处,尝试进行赋值,如:http://www.baidu.com;或系统常见 文件,如:/etc/passwd(linux) 4、配合文件上传漏洞进行验证
DVWA演示
1. Low
不同难度下的界面都是相同的,可以注意到有file1.php,file2.php,file3.php三个文件。
![](https://img-blog.csdnimg.cn/img_convert/bb02e678f04e0cc6e203c368141c2e35.png)
任意点击其中一个文件如file1.php,地址栏的page=include.php就会相应变为page=file1.php,即利 用GET的方法来获取服务器中的php文件。
![](https://img-blog.csdnimg.cn/img_convert/539377c2fee7733adc1c8ce89619465a.png)
源码分析得出:直接通过get去传递page参数进行文件包含,没有任何过滤。
![](https://img-blog.csdnimg.cn/img_convert/f14aa07c322fdb7412fff855e10f3034.png)
尝试获取服务器上的文件内容,输入 ../../../../../../(多少个../都行,越多越好)/etc/passwd
![](https://img-blog.csdnimg.cn/img_convert/3a6ed5faf0dae89590dc653192338a48.png)
../ 返回上级目录,当返回到根目录时候再../还是根目录,然后直接进入linux系统的passwd文件
也可以尝试包含php.ini,可以看到,现在的页面是在 vulnerabilities/fi/file1.php,如果想要访问 php.ini需要回退两次,可以输入../../php.ini
成功包含到php配置文件
![](https://img-blog.csdnimg.cn/img_convert/2d5e1047e0ef8decab9c31a4a358f785.png)
2. str_replace函数绕过 (Medium)
![](https://img-blog.csdnimg.cn/img_convert/9fe9575ee0d8e4fce782f46b8231feb2.png)
分析: Medium级别的代码增加了str_replace函数,对page参数进行了一定的过滤,将”http:// ”、”https://”、 ” ../”、”..\“”替换为空字符。 但str_replace函数并不是很安全,双写就可以绕过了。而且” ../”、”..\”替换为空字符,那么绝对路径来 讲,是不受任何影响的。 http://10.0.0.79:8080/vulnerabilities/fi/?page=..././..././..././..././..././..././etc/passwd
![](https://img-blog.csdnimg.cn/img_convert/a12ea07cbfcb7e236a3f386f9eb7cf2e.png)
3. fnmatch() 函数绕过(High)
查看源码:
![](https://img-blog.csdnimg.cn/img_convert/c0ba8ba239514712af055c225a4eea4b.png)
可以看到,这里用了fnmatch函数 : fnmatch() 函数根据指定的模式来匹配文件名或字符串 语法: fnmatch(pattern,string,flags) pattern 必需。规定要检索的模式。 string 必需。规定要检查的字符串或文件。 flags 可选。
限制了page参数的开头必须是file,但是可以用file://协议类进行文件读取 http://10.0.0.79:8080/vulnerabilities/fi/?page=file:///etc/passwd
![](https://img-blog.csdnimg.cn/img_convert/eefcbaaabdc8d3d241ae8762cea334c5.png)
远程文件包含
远程文件包含是指包含非被攻击机器上的文件。 此处我们使用dvwa的文件包含漏洞包含 upload-labs 中的文件;
这里我们用两个靶场,一个是dvwa,一个是upload-labs
dvwa的地址为172.17.0.2
![](https://img-blog.csdnimg.cn/img_convert/2d675862204314056c8857f8fb3279cc.png)
upload的地址为172.17.0.3
![](https://img-blog.csdnimg.cn/img_convert/3d8cb622c108c3516a39da79f99cfe64.png)
我们先在upload-labs中通过文件上传漏洞,上传一个phpinfo()文件
![](https://img-blog.csdnimg.cn/img_convert/3a5387349fd065ba4c54d13d1bd4d9c5.png)
然后我们在dvwa中利用文件包含漏洞去包含upload中的php文件
![](https://img-blog.csdnimg.cn/img_convert/bc5e5321f7e6688e50c3213678723010.png)
我们到后台看一下dvwa的版本
![](https://img-blog.csdnimg.cn/img_convert/aaa30815d024c275266c2768fffbf177.png)
发现和我们文件包含得到的结果不一致
这是因为我们上传的一个php文件,所以它直接执行了,显示的结果是upload的
那我们在upload中上传一个txt文件
![](https://img-blog.csdnimg.cn/img_convert/c13af5bf644e3531663ea04b2ff48aa3.png)
然后在dvwa中进行文件包含
![](https://img-blog.csdnimg.cn/img_convert/f058a2a72ae25201ba5dca89d63d979f.png)
文件包含getshell
1. 中间件日志包含绕过
DVWA中,apache2日志文件路径为: /var/log/apache2/access.log 包含日志文件,需要先对文件和目录添加权限,让web端有权限去访问:
![](https://img-blog.csdnimg.cn/img_convert/b95c271f6d80cae7fe928b60b4633908.png)
修改完权限之后,访问 10.0.0.79:8080/vulnerabilities/fi/?page=<?php phpinfo();?>
因浏览器会进行url编码,使用burp抓包进行修改,将编码字符改为原字符
![](https://img-blog.csdnimg.cn/img_convert/16e374a4fcf1a7713651642b75b34485.png)
让access.log 文件记录中包含PHP代码 <?php phpinfo(); ?>
![](https://img-blog.csdnimg.cn/img_convert/f68643a9fb26279a0660a92d659de948.png)
然后我们通过文件包含漏洞来访问
![](https://img-blog.csdnimg.cn/img_convert/3872aac67f5a5b9ac1aa85b5706c0233.png)
2. 配合文件上传getshell
思路: 1. 把代码+图片合在一起,最终看到还是一个图片,只是这个图片中有代码 2. 上传一个带有代码的jpg图片 3. 以文件包含漏洞来执行图片的php代 码
关于文件上传和图片吗的内容,可以查看https://blog.csdn.net/Williamanddog/article/details/128784444?spm=1001.2014.3001.5501
上传成功,并且获得上传路径
![](https://img-blog.csdnimg.cn/img_convert/ce5d39363c63c54055910891dd1c761b.png)
现在我们再利用文件包含漏洞访问该图片
![](https://img-blog.csdnimg.cn/img_convert/5fe164ee9f0c0d7b72481e3b8a0d9ed4.png)
同样我们可以利用蚁剑连接
![](https://img-blog.csdnimg.cn/img_convert/bfde5ab62818fa9b605f1738c42bd7f8.png)
注意这里要设置cookie值
![](https://img-blog.csdnimg.cn/img_convert/a0ff4d2ffb8789108cc5ee3d3a3dc35d.png)
![](https://img-blog.csdnimg.cn/img_convert/e0372fb028f6cf28a922edcfcc77ece9.png)
成功连接
![](https://img-blog.csdnimg.cn/img_convert/10a8ac83150ab011555710c853cc5bc5.png)