PHP中危险的file_put_contents函数详解

前言

最近在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));
}

?>

总结

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

(0)

相关推荐

  • PHP中创建空文件的代码[file_put_contents vs touch]

    I has passed a small test to check which function is faster to create a new file. file_put_contents vs touch 复制代码 代码如下: <?php for($i = ; $i < 100; $i++) { file_put_contents('dir/file'.$i, ''); } ?> Average time: 0,1145s 复制代码 代码如下: <?php for($i

  • PHP使用内置函数file_put_contents写入文件及追加内容的方法

    本文实例讲述了PHP使用内置函数file_put_contents写入文件及追加内容的方法.分享给大家供大家参考,具体如下: 以追加形式写入内容 当设置 flags 参数值为 FILE_APPEND 时,表示在已有文件内容后面追加内容的方式写入新数据: 复制代码 代码如下: <?php file_put_contents("test.txt", "This is another something.", FILE_APPEND); ?> file_put

  • php file_put_contents()功能函数(集成了fopen、fwrite、fclose)

    命令:file_put_contents(): 命令解析:file_put_contents (PHP 5) file_put_contents -- 将一个字符串写入文件 说明: int file_put_contents ( string filename, string data [, int flags [, resource context]] ) 和依次调用 fopen(),fwrite() 以及 fclose() 功能一样. 参数 data 可以是数组(但不能为多维数组),这就相当

  • PHP中fwrite与file_put_contents性能测试代码

    function microtimeFloat() {    list($usec,$sec) = explode(" ", microtime());    return((float)$usec + (float)$sec);} 1.测试file_put_contents 复制代码 代码如下: <?php$userCount = 1000;$itemCount = 1000;$file = 'ratings.txt';file_exists($file) &&

  • PHP中file_put_contents追加和换行的实现方法

    在PHP的一些应用中需要写日志或者记录一些信息,这样的话.可以使用fopen(),fwrite()以及 fclose()这些进行操作.也可以简单的使用file_get_contents()和file_put_contents(). file_put_contents()写文件.默认的是重新写文件,也就是会 替换原先的内容.追加的话使用参数FILE_APPEND. 以追加形式写入内容 当设置 flags 参数值为 FILE_APPEND 时,表示在已有文件内容后面追加内容的方式写入新数据: FIL

  • PHP中危险的file_put_contents函数详解

    前言 最近在EIS上遇到一道文件上传的题,发现过滤了<,这样基本很多姿势都无效了,想了很久没做出来这题,赛后才知道是利用数组来绕过, 这里分析了下原理,话不多说了,来一起看看详细的介绍吧. 来看下file_put_contents函数第二个参数data的官网定义: data 要写入的数据.类型可以是 string,array 或者是 stream 资源(如上面所说的那样). 如果 data 指定为 stream 资源,这里 stream 中所保存的缓存数据将被写入到指定文件中,这种用法就相似于使

  • Oracle中的游标和函数详解

     Oracle中的游标和函数详解 1.游标 游标是一种 PL/SQL 控制结构:可以对 SQL 语句的处理进行显示控制,便于对表的行数据 逐条进行处理. 游标并不是一个数据库对象,只是存留在内存中. 操作步骤: 声明游标    打开游标 取出结果,此时的结果取出的是一行数据 关闭游标 到底那种类型可以把一行的数据都装进来 此时使用 ROWTYPE 类型,此类型表示可以把一行的数据都装进来. 例如:查询雇员编号为 7369 的信息(肯定是一行信息). 例:查询雇员编号为 7369 的信息(肯定是一

  • jQuery3.0中的buildFragment私有函数详解

    时隔 3 个月,jQuery 团队终于发布了 3.0 Alpha 版本.有两个版本 jQuery compat 3.0 和 jQuery 3.0. jQuery compat 3.0 对应之前的 1.x, 兼容更多的浏览器,对于IE支持到 8.0 版本 jQuery 3.0 对应之前的 2.x,关注更新的浏览器,对于IE支持到 9.0 版本 此外, 3.0还增加了对 Yandex 浏览器的支持,一款来自俄罗斯的浏览器. 下面看下jQuery3.0中的buildFragment. 在 jQuery

  • 对pandas中Series的map函数详解

    Series的map方法可以接受一个函数或含有映射关系的字典型对象. 使用map是一种实现元素级转换以及其他数据清理工作的便捷方式. (DataFrame中对应的是applymap()函数,当然DataFrame还有apply()函数) 1.字典映射 import pandas as pd from pandas import Series, DataFrame data = DataFrame({'food':['bacon','pulled pork','bacon','Pastrami',

  • 对Python中plt的画图函数详解

    1.plt.legend plt.legend(loc=0)#显示图例的位置,自适应方式 说明: 'best' : 0, (only implemented for axes legends)(自适应方式) 'upper right' : 1, 'upper left' : 2, 'lower left' : 3, 'lower right' : 4, 'right' : 5, 'center left' : 6, 'center right' : 7, 'lower center' : 8,

  • 对python中的高效迭代器函数详解

    python中内置的库中有个itertools,可以满足我们在编程中绝大多数需要迭代的场合,当然也可以自己造轮子,但是有现成的好用的轮子不妨也学习一下,看哪个用的顺手~ 首先还是要先import一下: #import itertools from itertools import * #最好使用时用上面那个,不过下面的是为了演示比较 常用的,所以就直接全部导入了 一.无限迭代器: 由于这些都是无限迭代器,因此使用的时候都要设置终止条件,不然会一直运行下去,也就不是我们想要的结果了. 1.coun

  • 对Tensorflow中的变量初始化函数详解

    Tensorflow 提供了7种不同的初始化函数: tf.constant_initializer(value) #将变量初始化为给定的常量,初始化一切所提供的值. 假设在卷积层中,设置偏执项b为0,则写法为: 1. bias_initializer=tf.constant_initializer(0) 2. bias_initializer=tf.zeros_initializer(0) tf.random_normal_initializer(mean,stddev) #功能是将变量初始化为

  • JavaScript中Array的filter函数详解

    目录 描述 理解 示例 原生实现 描述 filter为数组中的每个元素调用一次callback函数,并利用所有使得callback返回 true 或等价于 true 的值的元素创建一个新数组.callback只会在已经赋值的索引上被调用,对于那些已经被删除或者从未被赋值的索引不会被调用.那些没有通过callback 测试的元素会被跳过,不会被包含在新数组中. 理解 filter不会改变原数组,它返回过滤后的新数组. filter遍历的元素范围在第一次调用callback之前就已经确定了.在调用f

  • PostgreSQL中的日期/时间函数详解

    目录 零.前言 一.获取当前时间 二.时间的加减 三.格式化函数 3.1时间转字符串 3.2字符串转日期 3.3字符串转时间 3.4Unix时间戳转时间 四.一些重要函数 4.1时间间隔 4.2时间截取 五.时间的转换 六.收! 零.前言 公司里有一台阿里云RDS数据库用了PPAS(Postgres PlusTM Advanced Server),在处理日期/时间时遇到一些问题,花了点时间整理如下. 一.获取当前时间 select now() select current_timestamp s

  • C#函数式编程中的标准高阶函数详解

    何为高阶函数 大家可能对这个名词并不熟悉,但是这个名词所表达的事物却是我们经常使用到的.只要我们的函数的参数能够接收函数,或者函数能够返回函数,当然动态生成的也包括在内.那么我们就将这类函数叫做高阶函数.但是今天我们的标题并不是高阶函数,而是标准高阶函数,既然加上了这个标准,就意味着在函数式编程中有一套标准的函数,便于我们每次调用.而今天我们将会介绍三个标准函数,分别为Map.Filter.Fold.  Map 这个函数的作用就是将列表中的每项从A类型转换到B类型,并形成一个新的类型.下面我们可

随机推荐