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_应用程式END,那么将移至文件末尾。不然,将会免去文件的源委
  • 向文件中写入数据
  • 关闭文件并对具备文件解锁
  • 只要成功,该函数将回来写入文件中的字符数。假如退步,则赶回 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));
}

?>

总结

如上正是那篇作品的全体内容了,希望本文的源委对我们的求学只怕工作有着一定的参阅学习价值,假若有问号大家能够留言调换,多谢我们对帮客之家的支撑。

前言
这两天在EIS上相见一道文件上传的题,开采过滤了,那样基本比非常多架子都行不通了,想了比较久没做出来…

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));
}

?>

近年来在EIS上蒙受一道文件上传的题,开采过滤了,那样核心比比较多姿势都于事无补了,想了比较久没做出来那题,赛…

于是小编么能够流传content[]=<?php phpinfo();?>&ext=php如此来绕过

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

  • 假使设置了 FILE_USE_INCLUDE_PATH,那么将检查 *filename*
    别本的嵌入路线
  • 若果文件子虚乌有,将开创贰个文件
  • 开采文件
  • 倘使设置了 LOCK_EX,那么将锁定文件
  • 固然设置了
    FILE_应用软件END,那么将移至文件末尾。不然,将会去掉文件的剧情
  • 向文件中写入数据
  • 关闭文件并对负有文件解锁
  • 纵然成功,该函数将重回写入文件中的字符数。假诺战败,则赶回 False。

大家知晓,比相当多拍卖字符串的函数倘使传入数组会出错重回NULL,
如strcmp,strlen,md5等, 但preg_match 函数出错重临false,
这里大家得以经过var_dump(preg_match('/</',$data));来表明, 那样的话,preg_match
的正则过滤就失效了

永利集团304手机版,来看下file_put_contents函很多次之个参数data的官方网站定义:

永利集团304登录,能够看看,data参数能够是数组, 会自动做join('',$array)更改为字符串的

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

data
要写入的数据。类型可以是 string,array 或者是 stream 资源(如上面所说的那样)。

如果 data 指定为 stream 资源,这里 stream 中所保存的缓存数据将被写入到指定文件中,这种用法就相似于使用 stream_copy_to_stream() 函数。

参数 data 可以是数组(但不能为多维数组),这就相当于 file_put_contents($filename, join('', $array))。
if(preg_match('/\</',$data)){
 die('hack');
}

多年来在EIS上相见一道文件上传的题,发掘过滤了<,那样中央非常多姿势都不行了,想了非常久没做出来这题,赛前才驾驭是行使数组来绕过,
这里深入分析了下原理,话十分的少说了,来三头看看详细的牵线吧。