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 中的一些经验积累
Oct 09 PHP
新浪微博API开发简介之用户授权(PHP基础篇)
Sep 25 PHP
PHP使用数组实现队列
Feb 05 PHP
详解WordPress中创建和添加过滤器的相关PHP函数
Dec 29 PHP
简单谈谈php浮点数精确运算
Mar 10 PHP
使用php实现从身份证中提取生日
May 09 PHP
php each 返回数组中当前的键值对并将数组指针向前移动一步实例
Nov 22 PHP
php头像上传预览实例代码
May 02 PHP
Laravel 中使用 Vue.js 实现基于 Ajax 的表单提交错误验证操作
Jun 30 PHP
PHP开发中解决并发问题的几种实现方法分析
Nov 13 PHP
php-msf源码详解
Dec 25 PHP
PHP常见的几种攻击方式实例小结
Apr 29 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
4月1日重磅发布!《星际争霸II》6.0.0版本更新
2020/04/09 星际争霸
一个从别的网站抓取信息的例子(域名查询)
2006/10/09 PHP
PHP实现域名whois查询的代码(数据源万网、新网)
2010/02/22 PHP
PHP与MYSQL中UTF8 中文排序示例代码
2014/10/23 PHP
php中字符串和整数比较的操作方法
2019/06/06 PHP
javascript document.compatMode兼容性
2010/02/23 Javascript
JQuery的常用选择器、过滤器、方法全面介绍
2016/05/25 Javascript
AngularJS基础 ng-list 指令详解及示例代码
2016/08/02 Javascript
用jquery快速解决IE输入框不能输入的问题
2016/10/04 Javascript
js实现带三角符的手风琴效果
2017/03/01 Javascript
JS完成画圆圈的小球
2017/03/07 Javascript
node.js 核心http模块,起一个服务器,返回一个页面的实例
2017/09/11 Javascript
浅谈Angular7 项目开发总结
2018/12/19 Javascript
javascript面向对象创建对象的方式小结
2019/07/29 Javascript
ant design中upload组件上传大文件,显示进度条进度的实例
2020/10/29 Javascript
Python调用C/C++动态链接库的方法详解
2014/07/22 Python
Python 获得命令行参数的方法(推荐)
2018/01/24 Python
pytorch cnn 识别手写的字实现自建图片数据
2018/05/20 Python
Python 使用类写装饰器的小技巧
2018/09/30 Python
Python实现获取系统临时目录及临时文件的方法示例
2019/06/26 Python
python自动化测试之如何解析excel文件
2019/06/27 Python
Python如何计算语句执行时间
2019/11/22 Python
python 装饰器的使用示例
2020/10/10 Python
纯CSS实现颜色渐变效果(包含环形渐变、线性渐变、彩虹效果等)
2014/05/07 HTML / CSS
党的群众路线教育实践活动动员会主持词
2014/03/20 职场文书
低碳环保倡议书
2014/04/14 职场文书
政治思想表现评语
2014/05/04 职场文书
班主任工作经验交流材料
2014/05/13 职场文书
组织生活会发言材料
2014/12/15 职场文书
2015年企业团支部工作总结
2015/05/21 职场文书
社区服务活动感想
2015/08/11 职场文书
初一英语教学反思
2016/02/15 职场文书
用Python写一个简易版弹球游戏
2021/04/13 Python
js中Map和Set的用法及区别实例详解
2022/02/15 Javascript
最新最全的手机号验证正则表达式
2022/02/24 Javascript
macos系统如何实现微信双开? mac登录两个微信以上微信的技巧
2022/07/23 数码科技