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 相关文章推荐
做个自己站内搜索引擎
Oct 09 PHP
frename PHP 灵活文件命名函数 frename
Sep 09 PHP
基于PHPExcel的常用方法总结
Jun 13 PHP
php 检查电子邮件函数(自写)
Jan 16 PHP
2个Codeigniter文件批量上传控制器写法例子
Jul 25 PHP
PHP return语句的另一个作用
Jul 30 PHP
在html文件中也可以执行php语句的方法
Apr 09 PHP
PHP页面转UTF-8中文编码乱码的解决办法
Oct 20 PHP
phpStudy2016 配置多个域名期间遇到的问题小结
Oct 19 PHP
PHP 中魔术常量的实例详解
Oct 26 PHP
laravel 判断查询数据库返回值的例子
Oct 11 PHP
php7 图形用户界面GUI 开发示例
Feb 22 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
php ftp文件上传函数(基础版)
2010/06/03 PHP
关于js与php互相传值的介绍
2013/06/25 PHP
php使用mysqli和pdo扩展,测试对比连接mysql数据库的效率完整示例
2019/05/09 PHP
firefox中JS读取XML文件
2006/12/21 Javascript
用JavaScrpt实现文件夹简单轻松加密的实现方法图文
2008/09/08 Javascript
转换json格式的日期为Javascript对象的函数
2010/07/13 Javascript
基于jquery的使ListNav兼容中文首字拼音排序的实现代码
2011/07/10 Javascript
jquery插件之文字间歇自动向上滚动效果代码
2016/02/25 Javascript
jQuery中的siblings()是什么意思(推荐)
2016/12/29 Javascript
js cookie实现记住密码功能
2017/01/17 Javascript
使用Vue写一个datepicker的示例
2018/01/27 Javascript
Javascript获取某个月的天数
2018/05/30 Javascript
Vue模拟数据,实现路由进入商品详情页面的示例
2018/08/31 Javascript
jQuery实现的图片点击放大缩小功能案例
2020/01/02 jQuery
简单了解JS打开url的方法
2020/02/21 Javascript
[00:53]TI3正赛第三天 DK怒破A队不败金身 现场国旗飘扬热血激昂
2013/08/10 DOTA
python基础教程之常用运算符
2014/08/29 Python
详解Python网络爬虫功能的基本写法
2016/01/28 Python
python关于矩阵重复赋值覆盖问题的解决方法
2019/07/19 Python
python字典的值可以修改吗
2020/06/29 Python
python中K-means算法基础知识点
2021/01/25 Python
html5视频媒体标签video的使用方法及完整参数说明详解
2019/09/27 HTML / CSS
Proenza Schouler官方网站:纽约女装和配饰品牌
2019/01/03 全球购物
越南综合购物网站:Lazada越南
2019/06/10 全球购物
英国DIY汽车维修配件网站:DIY Car Service Parts
2019/08/30 全球购物
美国职棒大联盟的官方手套、球和头盔:Rawlings
2020/02/15 全球购物
安全生产先进个人材料
2014/02/06 职场文书
求职信内容怎么写
2014/05/26 职场文书
学校师德师风整改方案
2014/10/28 职场文书
西柏坡观后感
2015/06/08 职场文书
网络舆情信息简报
2015/07/21 职场文书
小学生安全教育主题班会
2015/08/12 职场文书
高一化学教学反思
2016/02/22 职场文书
个人房屋租赁合同(标准范本)
2019/09/16 职场文书
八年级作文之感悟亲情
2019/11/20 职场文书
使用Postman测试需要授权的接口问题
2022/06/21 Java/Android