文件包含
是指编译器进行预处理时复制指定的文件内容代替源文件中预处理命令的过程,一个源文件可以将另一个源文件的全部内容包含进来。初衷是为了减少程序代码的冗余。
文件包含漏洞原理
可以试想一下,开发人员如果每一个代码文件中都要使用到同一段代码,非常繁琐,所以通常会将用到的代码转换成一个文件,让每一个用到它的代码都包含在里面,而无需再次编写。这种调用文件的过程一般被称为包含文件。但由于这种灵活性,从而导致客户端可以调用任意恶意文件,从而造成文件包含漏洞。
文件 PHP 中的文件包含分为本地包含和远程包含(allow_url_include = on)
本地文件包含测试
测试链接:CTFHUB
可以看到,这里网页包含了一个shell文件,构造payload来调用shell.txt
<?php
error_reporting(0);//关闭错误报告
if (isset($_GET['file'])) {//isset用来检测变量是否设置,这里是GET请求包含file
if (!strpos($_GET["file"], "flag")) {//strpos() 函数查找字符串在另一字符串中第一次出现的位置。查找file中的flag
include $_GET["file"];//包含file并运行
} else {
echo "Hacker!!!";//如果file内不包含flag则报错
}
} else {
highlight_file(__FILE__);
}
?>
根据代码要求,GET请求包含file,使用蚁剑连接,密码为ctfhub
成功连接,在文件根目录拿到flag
Include()函数属于文件包含函数,通过include()或require()语句,php文件可以直接执行包含文件的代码,包含的文件格式不受任何限制,这两个语句其实是相同的,只是在处理错误方面,require会生成致命错误并且停止脚本,而include只会警告,但是脚本继续运行
远程文件包含测试
测试地址:CTFHUB
代码与上面的相同,只不过这里给了一个phpinfo,打开后发现一个非常重要的信息
当allow_url_fopen为on的时候,既开启远程文件包含功能。allow_url_include 为on的时候,允许使用include。注:可以在php.ini文件中设置开闭,一般关闭【路径:/etc/php/7.0/apache2/php.ini】
在这里我们得先了解一下什么是php://,以及php提供的各种杂项输入输出流
php://(访问各个输入/输出流),提供了IO流允许访问 PHP 的输入输出流、标准输入输出和错误描述符,内存中、磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器。如php://stdin、php://stdout 和 php://stderr 允许直接访问 PHP 进程相应的输入或者输出流。如php://input、php://output,php://input是一个可以访问请求的原始数据的只读流,构造payload。
文件包含漏洞的危害
文件包含不仅能够包含web文件目录中的一些配置文件(比如Web应用、数据库配置文件、config文件),还可以查看到一些Web动态页面的源代码,为攻击者进一步发掘web应用漏洞提供条件,甚至一旦与路径遍历漏洞相结合,还可能直接攫取目标系统的用户名与密码等文件,进行目录遍历等等。