本地包含
比如我们有一个test.txt
文件,仅仅调用phpinfo来测试:
|
|
然后我们在相同目录下放置一个fileinclude.php
,如下:
|
|
第一行代码获取 URL 参数file的内容。2 ~ 4 行首先判断$file是否为空,若不为空,输出其内容,并将其作为文件名称包含。
我们将其部署在localhost下,之后访问http://localhost/fileinclude.php?file=test.txt,会看到phpinfo的输出。
我这里之所以用txt文件,就是想说明这个漏洞是无视扩展名的。跟文件上传漏洞不一样,文件上传漏洞中如果我们上传的文件不是.php就执行不了(当然也有一些绕过手段),但是文件包含漏洞中的扩展名是任意的,这里我们上传了.txt,证实有效,那么这个.jpg也是有效的。
要注意,如果被包含的文件里面没有 PHP 标签,那么就当成 HTML 内容如实显示出来。就比如我们放入之前的top100.txt.
远程包含
为了演示远程包含,我们需要将 PHP 配置文件中的allow_url_include设置为on,之后重启 PHP。PHP 配置文件的位置可以在phpinfo的输出中寻找,我们搜索ini即可。
我这里是C:\php-5.5.10\php.ini,你那里可能有些差别。我们打开它,搜索allow_url_include,会看到下面这些行,如果是Off把它改成On。
|
|
我们需要将file参数改为http://localhost/text.txt,可以看到相同结果。
技巧
ASCII 00截断
使用条件 PHP < 5.3 magic_quotes_gpc: off
有些程序会给被包含内容加一些后缀,比如如果fileinclude.php是这样。
它后面加了个.php,也就是说,如果我们传入file=test则是正常的,传入file=test.txt,或变成test.txt.php,从而包含失败。那么我们应该怎么办呢?+
如果 PHP 版本小于 5.3,并且magic_quotes_gpc已取消,我们就可以使用%00来截断。我们传入file=test.txt%00,就可以实现包含。
路径遍历
./
(或省略):当前目录../
:上级目录/
:根目录(Windows 中为当前盘内的根目录)~/
:用户的主目录
例如,在 Linux 下,我们就可以使用file=/etc/passwd来读取系统密码。
这里是一些常见的日志文件位置:
1 apache+Linux日志默认路径
2 apache+win2003日志默认路径
3 IIS6.0+win2003默认日志文件
4 IIS7.0+win2003 默认日志文件
5 nginx 日志文件
6 apache+linux 默认配置文件
7 IIS6.0+win2003 配置文件
8 IIS7.0+WIN 配置文件
PHP 伪协议
服务器输出
允许远程包含的情况下,我们可以使用php://伪协议,比如php://filter/resource=test.txt可以读取相同文件。
我们还可以加一个过滤器让它显示为 BASE64 编码格式,php://filter/read=convert.base64-encode/resource=test.txt。如果我们要获取的文件里面有不可打印的字符,或者我们想要获取代码的内容,可以用这种方式来获取,之后解码即可。
|
|
向服务器输入
php://input可以读取原始的 HTTP 正文内容。如果我们将file设置为php://input,并且在 HTTP 正文中传入 PHP 代码,例如<?php phpinfo();?>,即可执行代码。
参考图片
Data URI
Data URI 的格式是data://text/plain;base64,
如何挖掘
首先对 URL 进行分析,看看是否和文件相关,比如www.test.com/xxx.php?file=yyy。带有文件相关的敏感名称都可以进行挖掘。
利用
当我们发现了本地包含漏洞时,首先寻找上传点,比如用户头像上传功能。然后我们可以构造一个纯文本文件,内容为<?php phpinfo();?>,并将其命名为xxx.jpg。+
之后我们就可以把xxx.jpg上传上去,并通过应用得到它的位置,假设是/upload/xxx.jpg,然后我们就可以把file参数的值改为它。以前面的代码为例,URL 是http://localhost/fileinclude.php?file=/upload/xxx.jpg。
如果我们把xxx.jpg的内容改为菜刀的一句话,那就可以用菜刀连接。
再说一下远程包含,远程包含的条件比较苛刻,目标网站需要把allow_url_open给打开。所以有本地包含不一定有远程包含,有远程包含一定就有本地包含。但是,远程包含的利用相对简单,只要将代码上传到自己博客,或者任何能通过 URL 访问到的地方就可以了。后续步骤是一样的。
远程包含需要手工修改PHP配置文件,目测远程包含的情况应该比较少
答案解析
Example 1
添加英文单引号,出现 warning, 仔细阅读后可以发现一些路径信息。
有以下几种利用方式
1 读取系统文件
2 远程文件包含
3 官方例子(远程包含)
Example 2
这是一个会自动补充后缀.php
的例子
添加英文单引号,出现 warning, 仔细阅读后可以发现一些路径信息,同时你也能发现后端添加了后缀名。
需要用 %00
截断
本地包含
远程包含
参考资料
米斯特白帽培训讲义 漏洞篇 文件包含