file_put_contents tricks
0x01 trick1
来自于P神的实例:
<?php $text = $_GET[‘text‘]; if(preg_match(‘[<>?]‘, $text)) { die(‘error!‘); } file_put_contents(‘config.php‘, $text);
希望getshell,但是限制了<>,无法写入PHP标准代码。
来自于P神的小密圈分享:
file_put_contents的第二个参数,可以是数组,并且会将数组转化成字符串写入。并且得益于PHP弱类型,在正则匹配前,传入的数组会被强制转化成字符串,也就是Array。因此可以绕过正则匹配,并且能够正常写入。
实例:
0x02 trick2
另一个关于file_put_contents的小trick,当file_put_contents、copy、file_get_contents等读取写入操作与unlink、file_exists等删除判断文件函数之间对于路径处理的差异导致的删除绕过
<?php $user=$_GET[‘user‘]; var_dump($user); echo $user[‘name‘]; $filename = __DIR__.‘\\‘.$user[‘name‘]; echo $filename; $data = $user[‘info‘]; file_put_contents($filename, $data); if(file_exists($filename)){ unlink($filename); }
p牛在小密圈说过类似问题
查看php源码,其实我们能发现,php读取、写入文件,都会调用php_stream_open_wrapper_ex来打开流,而判断文件存在、重命名、删除文件等操作则无需打开文件流。
我们跟一跟php_stream_open_wrapper_ex就会发现,其实最后会使用tsrm_realpath函数来将filename给标准化成一个绝对路径。而文件删除等操作则不会,这就是二者的区别。
所以,如果我们传入的是文件名中包含一个不存在的路径,写入的时候因为会处理掉“../”等相对路径,所以不会出错;判断、删除的时候因为不会处理,所以就会出现“No such file or directory”的错误。
所以,linux可以通过xxxxx/../test.php、test.php/. 来绕过删除
windows可以通过test.php:test test.ph<来绕过文件删除
拿windows实例:
http://127.0.0.1/l.php?user[name]=2.php:test&user[info]=2y 会生成2.php
http://127.0.0.1/l.php?user[name]=2.ph<&user[info]=2y 会写入内容
学习资料:http://www.am0s.com/functions/386.html
原文地址:https://www.cnblogs.com/BOHB-yunying/p/11638492.html