PHP中危险的file_put_contents函数详解


Posted in PHP onNovember 04, 2017

前言

最近在EIS上遇到一道文件上传的题,发现过滤了<,这样基本很多姿势都无效了,想了很久没做出来这题,赛后才知道是利用数组来绕过, 这里分析了下原理,话不多说了,来一起看看详细的介绍吧。

来看下file_put_contents函数第二个参数data的官网定义:

data
要写入的数据。类型可以是 string,array 或者是 stream 资源(如上面所说的那样)。
 
如果 data 指定为 stream 资源,这里 stream 中所保存的缓存数据将被写入到指定文件中,这种用法就相似于使用 stream_copy_to_stream() 函数。
 
参数 data 可以是数组(但不能为多维数组),这就相当于 file_put_contents($filename, join('', $array))。

可以看到,data参数可以是数组, 会自动做join('',$array)转换为字符串的

该函数访问文件时,遵循以下规则:

  • 如果设置了 FILE_USE_INCLUDE_PATH,那么将检查 *filename* 副本的内置路径
  • 如果文件不存在,将创建一个文件
  • 打开文件
  • 如果设置了 LOCK_EX,那么将锁定文件
  • 如果设置了 FILE_APPEND,那么将移至文件末尾。否则,将会清除文件的内容
  • 向文件中写入数据
  • 关闭文件并对所有文件解锁
  • 如果成功,该函数将返回写入文件中的字符数。如果失败,则返回 False。

但我们字符串过滤函数一般是用preg_match函数来过滤的,如:

if(preg_match('/\</',$data)){
 die('hack');
}

我们知道,很多处理字符串的函数如果传入数组会出错返回NULL, 如strcmp,strlen,md5等, 但preg_match 函数出错返回false, 这里我们可以通过var_dump(preg_match('/\</',$data)); 来验证, 这样的话,preg_match 的正则过滤就失效了

因此,猜测文件上传的代码是这样写的

<?php 
 
if(isset($_POST['content']) && isset($_POST['ext'])){
 $data = $_POST['content'];
 $ext = $_POST['ext'];
 
 //var_dump(preg_match('/\</',$data));
 if(preg_match('/\</',$data)){
  die('hack');
 }
 $filename = time();
 file_put_contents($filename.$ext, $data);
}
 
?>

于是我么可以传入content[]=<?php phpinfo();?>&ext=php 这样来绕过

修复方法

修复方法是使用fwrite 函数来代替危险的file_put_contents函数,fwrite函数只能传入字符串,如果是数组会出错返回false

<?php 
 
if(isset($_POST['content']) && isset($_POST['ext'])){
 $data = $_POST['content'];
 $ext = $_POST['ext'];
 
 //var_dump(preg_match('/\</',$data));
 if(preg_match('/\</',$data)){
  die('hack');
 }
 $filename = time();
 // file_put_contents($filename.$ext, $data);
 $f = fopen($filename.$ext);
 var_dump(fwrite($f,$data));
}
 
?>

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
在PHP中使用Sockets 从Usenet中获取文件
Jan 10 PHP
PHP中基本符号及使用方法
Mar 23 PHP
php正则表达式使用的详细介绍
Apr 27 PHP
php缩小png图片不损失透明色的解决方法
Dec 25 PHP
PHP添加Xdebug扩展的方法
Feb 12 PHP
php smarty模板引擎的6个小技巧
Apr 24 PHP
PHP大转盘中奖概率算法实例
Oct 21 PHP
CentOS 上搭建 PHP7 开发测试环境
Feb 26 PHP
深入理解PHP的远程多会话调试
Sep 21 PHP
PHP实现的一致性Hash算法详解【分布式算法】
Mar 31 PHP
PHP实现的分解质因数操作示例
Aug 01 PHP
PHP pthreads v3在centos7平台下的安装与配置操作方法
Feb 21 PHP
PHP回调函数概念与用法实例分析
Nov 03 #PHP
PHP实现字符串翻转功能的方法【递归与循环算法】
Nov 03 #PHP
PHP空值检测函数与方法汇总
Nov 19 #PHP
使用PHPStorm+XDebug搭建单步调试环境
Nov 19 #PHP
php利用云片网实现短信验证码功能的示例代码
Nov 18 #PHP
swoole和websocket简单聊天室开发
Nov 18 #PHP
php单元测试phpunit入门实例教程
Nov 17 #PHP
You might like
山进SANGEAN ATS-909X电路分析
2021/03/02 无线电
如何跨站抓取别的站点的页面的补充
2006/10/09 PHP
深入了解PHP类Class的概念
2012/06/14 PHP
PHP简单字符串过滤方法示例
2016/09/04 PHP
支付宝支付开发――当面付条码支付和扫码支付实例
2016/11/04 PHP
一次失败的jQuery优化尝试小结
2011/02/06 Javascript
js中数组Array的一些常用方法总结
2013/08/12 Javascript
浅谈javascript的调试
2015/01/28 Javascript
js实现类似新浪微博首页内容渐显效果的方法
2015/04/10 Javascript
老生常谈的跨域处理
2017/01/11 Javascript
jquery使用EasyUI Tree异步加载JSON数据(生成树)
2017/02/11 Javascript
AngularJS学习第一篇 AngularJS基础知识
2017/02/13 Javascript
JS中使用 after 伪类清除浮动实例
2017/03/01 Javascript
微信小程序 检查接口状态实例详解
2017/06/23 Javascript
nodejs初始化init的示例代码
2018/10/10 NodeJs
使用Vue.js 和Chart.js制作绚丽多彩的图表
2019/06/15 Javascript
微信小程序模板消息限制实现无限制主动推送的示例代码
2019/08/27 Javascript
Python Web开发模板引擎优缺点总结
2014/05/06 Python
python模拟enum枚举类型的方法小结
2015/04/30 Python
python连接字符串的方法小结
2015/07/13 Python
使用Django Form解决表单数据无法动态刷新的两种方法
2017/07/14 Python
python如何对实例属性进行类型检查
2018/03/20 Python
Python实现爬虫从网络上下载文档的实例代码
2018/06/13 Python
python实现简单聊天室功能 可以私聊
2019/07/12 Python
Python基于gevent实现文件字符串查找器
2020/08/11 Python
详解Python中Pyyaml模块的使用
2020/10/08 Python
python 中 .py文件 转 .pyd文件的操作
2021/03/04 Python
网友共享的几个面试题关于Java和Unix等方面的
2016/09/08 面试题
经济管理专业自荐信
2013/12/30 职场文书
俄罗斯商务邀请函
2014/01/26 职场文书
中餐厅经理岗位职责
2014/04/11 职场文书
计划生育证明格式及范本
2014/10/09 职场文书
店面出租协议书范本
2014/11/28 职场文书
检讨书范文2000字
2015/01/28 职场文书
单位推荐信范文
2015/03/27 职场文书
详解nginx安装过程并代理下载服务器文件
2022/02/12 Servers