直接给源码吧:
<?php
//error_reporting(0);
//$dir=md5("icq" . $_SERVER['REMOTE_ADDR']);
$dir=md5("icq");
$sandbox = '/var/sandbox/' . $dir;
@mkdir($sandbox);
@chdir($sandbox);
if($_FILES['file']['name']){
$filename = !empty($_POST['file']) ? $_POST['file'] : $_FILES['file']['name'];
if (!is_array($filename)) {
$filename = explode('.', $filename);
}
$ext = end($filename);
if($ext==$filename[count($filename) - 1]){
die("emmmm...");
}
$new_name = (string)rand(100,999).".".$ext;
move_uploaded_file($_FILES['file']['tmp_name'],$new_name);
$_ = $_POST['hehe'];
if(@substr(file($_)[0],0,6)==='@<?php' && strpos($_,$new_name)===false){
include($_);
}
unlink($new_name);
}
else{
highlight_file(__FILE__);
先看后缀名绕过吧。看着有点熟悉,总感觉在哪见过,后来才想起是pwnhub的公开赛里见过,考察的是end()函数。给个例子输出就清楚了。
<?php
$a[2] = '222';
$a[1] = '111';
$a[0] = '000';
$end = end($a);
var_dump($end);
$arr = $a[count($a)-1]
var_dump($arr);
?>
输出结果:
end输出输入顺序最后一个
所以这里绕过是文件名取$_POST'file'绕过
至于下面unlink的绕过,有两种解法,一种是加/.,一种是../绕过。
加/. unlink无法删除是linux下的特性,windows并不适用。
接下来传入hehe参数,爆破包含即可。
至于加../,产生的随机数会生成会被当成路径。
然后直接包含我们的文件即可。
生成了shell.php,也成功写入了。
这里加 /. 和 ../ unlink都没删除,p牛小密圈给过解释
查看php源码,其实我们能发现,php读取、写入文件,都会调用php_stream_open_wrapper_ex来打开流,而判断文件存在、重命名、删除文件等操作则无需打开文件流。
我们跟一跟php_stream_open_wrapper_ex就会发现,其实最后会使用tsrm_realpath函数来将filename给标准化成一个绝对路径。而文件删除等操作则不会,这就是二者的区别。
所以,如果我们传入的是文件名中包含一个不存在的路径,写入的时候因为会处理掉“../”等相对路径,所以不会出错;判断、删除的时候因为不会处理,所以就会出现“No such file or directory”的错误。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。