继续学习php文件包含漏洞,越来越觉得自己不够用功,要更用功才行。
简介
如果允许客户端用户输入控制动态包含在服务器端的文件,会导致恶意代码的执行及敏感信息泄露,主要包括本地文件包含和远程文件包含两种形式。
文件包含函数
函数说明
1 | include() |
PHP的每个函数包含一个文件的时候,都会把包含的文件当作 php代码进行执行,而不会在意文件的类型。
include():在代码执行到它的时候才加载文件,发生错误的时候只是给一个警告,然后继续往下执行。
require()只要程序一执行就会立即调用文件,发生错误的时候会输出错误信息,并且终止脚本的运行。
include_once()和require_once()与 include()和require()类似,只不过前者只会包含一次文件,防止出现函数重定义或变量赋值的问题。
实例
假如现在本地有一个test.txt文件。内容如下:1
2
3
4
5
phpinfo();
然后在服务器中编写代码test.php1
2
3
4
5
$temp=$_GET['c'];
include($temp);
接着输入url:1
http://127.0.0.1/test.php/?c=C:\phpStudy\PHPTutorial\WWW\test.txt //c的值是本地test.txt所在的位置
可以看到这里 $temp没有经过任何的过滤措施,直接带入到了 include函数,这就存在非常大的安全隐患。可以发现成功地执行了 phpinfo()。 这样就简单地实现了文件包含。
文件包含分类
LFI
LFI为本地文件包含,包含本地服务器的文件,可以尝试构造去读取本地服务器的敏感信息。 Windows上的敏感信息:
Linux上的敏感信息:
RFI
RFI为远程文件包含,包含远程服务器上的文件。可以构造一些恶意代码让被包含的程序执行。 开启远程文件包含需要在 php.ini配置文件中开启相应功能:
php伪协议
这里就放一个例子,下一次详讲.
服务器存在一个test.php:1
2
3
4
5
6<?php
$temp=$_GET['c'];
include($temp);
?>
php://filter
可以通过指定 resource的值来读取指定的文件。 通常读取文件的伪协议 Payload:
php://input
使用 php://input伪协议需要 php.ini开启相应功能:
使用 php://input可以获取 POST请求中的数据 使用方式:
phar
使用 php://phar需要 php的版本大于等于 5.3.0。 把要读取的文件,例如 phpinfo.txt压缩成 zip文件,为 phpinfo.zip。 使用相对路径或者绝对路径读取都可以:
zip://
zip://和 phar://功能类似,区别就是要使用绝对路径来读取,并且 zip文件后面要加 %23再跟文件:
data://
使用 data://要求 php版本大于等于 5.2.0。 php.ini的配置文件开启相应的功能:
使用方式:
包含日志文件
使用时需要知道日志文件的目录,且日志文件可读。 访问的请求一般都会被记录在服务器的 access.log日志文件中。 可以先请求:
然后进行利用:
绕过
指定前缀
1 | <?php |
可以看到这里强行拼接了 /var/www/html/作为前缀。
目录遍历
可以通过 ../来进行目录遍历,从而绕过前缀的限制。
编码
服务器可能会把../过滤掉,可以通过一些不同的编码来进行绕过。
指定后缀
1 | <?php |
这里强行指定了 .php作为文件的结尾。
问号绕过
%00截断
可以通过 %00截断的方式读取 /etc/passwd。
路径长度截断
Linux下需要文件名长于 4096,而 Windows需要长于 256。