文件包含漏洞
PHP version
包含函数
-
include
-
require
-
include_once
-
require_once
include
将指定的文件载入并执行里面的程序。重复引用的情况下加载多次。
|
|
包含两次test.php。
include_once
将指定文件载入并执行内含程序。不会重复包含。
|
|
包含一次test.php。
require
除了处理错误的方式不同外,其他方面相同。同时require()一般放在 PHP 文件的最前面,程序在执行前就会先导入要引用的文件;include()一般放在程序的流程控制中,当程序执行时碰到才会引用,简化程序的执行流程
-
require生成致命错误(E_COMPILE_ERROE),脚本停止。
-
include生成警告(E_WARNING),脚本继续。
require_once()也类似。
封装协议
|协议|作用|
|—|—|
|file://|访问本地文件系统|
|http(s)||
|ftp://|访问FTP(s) URL|
|php://|访问各个输入/出流|
|zlib://|压缩流|
|data://|数据|
|phar://|PHP归档|
…
伪协议
file://
条件:
-
allow_url_fopen
:off/on -
allow_url_include
:off/on
作用
用于访问本地文件系统。include()/require()/include_once()/require_once()参数可控的情况下,如导入为非.php文件,则仍按照php语法进行解析,这是include()函数所决定的。
usage
- 绝对路径
http://xxx/include.php?file=file://C:\WWW\test\1.txt
- 相对路径
http://xxx/include.php?file=./2.txt
- 网络路径
http://xxx/include.php?file=http://yyy/3.txt
php://
条件:
-
allow_url_fopen
:off/on -
allow_url_include
:仅php://input, php://stdin, php://memory, php://temp需要on
作用
php://
访问各个输入/输出流(I/O streams)
- 在CTF中经常使用的是php://filter
和
- php://input
,php://filter
用于读取源码,
- php://input
用于执行php代码。
php://filter
作用
一种元封装器,设计用于数据流打开时的筛选过滤应用。对于如readfile()
,file()
,fiel_get_contents()
等一体式的文件函数非常有用,在数据流内容读取之前没有机会应用其他过滤器。
参数&过滤器
参数:
-
resource=
: 必须项,指定了需要筛选过滤的数据流。 -
read-
: 可选项,设定一个或多个过滤器名称,以管道符(*\*)
分隔。 -
write=
: 可选,设定一个或多个过滤器名称,以管道符(\)
分隔。 -
;
:任何没有以read=
或者write=
做前缀的筛选器列表会视情况应用于读或写链。
过滤器
- 字符过滤器
|过滤器名称|作用|
|—|—|
|string.rot13
|=str_rot13()
,rot13变换|
|string.toupper
|=strtoupper
,转大写字母|
|string.tolower
|strtolower()
,转小写|
|string.strip_tags
|strip_tags()
,去除html、PHP语言标签|
- 转换过滤器
|过滤器名称|作用|
|—|—|
|convert.base64-encode & convert.base64-decode
|=base64_encode()/base64_decode()
,base64编码/解码|
|convert.quoted-printable-encode & convert.quoted-printable-decode
|quoted-printable字符串与8-bit字符串编码/解码|
- 压缩过滤器
|过滤器名称|作用|
|—|—|
|zlib.deflate & zlib.inflate
|在本地文件系统中创建gzip兼容文件的方法,但不产生命令行工具,只是压缩和解压数据流中的有效载荷部分|
|bzip2.compress & bzip2.decompress
|在本地文件系统中创建bz2兼容文件方法|
- 加密过滤器
|过滤器名称|作用|
|—|—|
|mcrypt.*
|libmcrypt 对称加密算法|
|mdecrypt.*
|libmcrypt 对称解密算法|
示例
php://filter
1.读取文件源码(对php文件需要base64编码)
|
|
2.执行php代码(结合post data)
|
|
zip://、bzip2://、zlib://
访问压缩文件中的子文件,不需要指定后缀名,也可以随意修改后缀名。
1.压缩文件且修改后缀then上传
|
|
data://
|
|
过滤绕过
(LFI version)
1.%00截断(RFI & LFI)
在低版本中php读取文件名时认为%00是终止符,对于%00后面的内容就会失效。
2.路径长度截断
Windows下目录最大长度为256字节,超出的部分会被丢弃;
Linux下目录最大长度为4096字节,超出的部分会被丢弃。
3.点号截断
windows系统点号长于256,超出的部分会被丢弃;
linux系统点号长于4096,超出的部分会被丢弃;
4.双写绕过
举例:
pphhpp://input
5.大小写混合绕过
举例:
Php://input
6.伪协议绕过
前面说的那些
(RFI version)
问号绕过
|
|
后面几个也都是在文件末尾添加