文件包含漏洞
什么是文件包含
程序开发人员一般会把重复使用的函数写到单个文件中,需要使用某个函数时直接调用此文件。而无需再次编写,这种 文件调用的过程一般被称为文件包含。
例如:include “conn.php”
PHP中常见包含文件函数
include()
当使用该函数包含文件时,只有代码执行到include()函数时才将文件包含进来,发生错误时之给出一个警告,继续向下执行。 include_once() 功能与Include()相同,区别在于当重复调用同一文件时,程序只调用一次
require()
require()与include()的区别在于require()执行如果发生错误,函数会输出错误信息,并终止脚本的运行。 require_once()
功能与require()相同,区别在于当重复调用同一文件时,程序只调用一次。File_get_contents() Fopen()
区别 (面试必问)
@ include :包含的文件不存在,程序会继续执行
@ require :包含文件不存在,程序停止执行
@(如果出现语法错误,两个不会继续执行,
@ 如果是找不到这个文件,include继续执行,require,停止执行)
文件包含漏洞产生的原因是在通过引入文件时,包含的文件名,用户可控,由于传入的文件名没有经过合理的校验,或者校验被绕过。
常见文件包含漏洞代码
• if(isset($_GET[page])){
• include $_GET[page];
• }else{
• include "home.php";
文件包含漏洞的危害
配合文件上传漏洞GetShell
• 可以执行任意脚本代码(php://input)(即使没有文件上传也能执行脚本代码)
• 网站源码文件以及配置文件泄露 (php://filter/read=convert.base64-encode/resource=bihuo.php)(及时没有文件上传也能读取)
• 远程包含GetShell
控制整个网站甚至是服务器
伪协议
常见的伪协议
file:// 访问本地文件系统
http:// 访问 HTTPs 网址
ftp:// 访问 ftp URL
Php:// 访问输入输出流
Zlib:// 压缩流
Data:// 数据
Ssh2:// security shell2
Expect:// 处理交互式的流
Glob:// 查找匹配的文件路径
php使用input读取post请求体的内容
漏洞代码
$content = file_get_contents('php://input');
echo $content;
include 'php://input';
Data:// 数据
漏洞代码
<?php
@$file = $_GET['file'];
@include($file);
?>
通过data://text/plain协议来进行漏洞利用
include.php?file=data:text/plain,<?php phpinfo();?>
发现不能使用,而且自己的代码没有问题啊? 这里需要编码
也可以使用base64
通过实验发现这个可能是编码的问题因为<?php phpinfo();?>在编成base64的时候出现了+。而浏览器不认识+号。所以解决方法
不写后面的?> 因为PHP里面其实不需要写后面的 前面的;号就已经说明结束了。如果没有;号就必须写?>作为结束。
添加空格改变base64编码。 将+号换成%2b 所以其实不需要通过base64编码来实现!!! 将<?php
phpinfo();?>改变成url编码。这样浏览器可以识别!
Zlib:// 压缩流
zip 协议 zip://压缩文件的路径#实际包含的文件的路径
其中压缩文件的路径可以使用绝对路径或者是相对路径
index.php?file=zip://upload/2.jpg%23shell.txt
文件包含的漏洞的分类
@本地文件包
含如果包含的文件 存在于php所在的服务器上
考虑上传一个文件点 + 找到该上传文件所在的位置
@远程文件包含
本地文件包含和远程文件包含造成漏洞的原因是一样的,当php.ini
中的配置选项allow_url_fopen(是否允许通过一个url进行包含)和allow_url_include为ON的话,则包含的
文件可以是第三方服务器中的文件,这样就形成了远程文件包含漏洞。