已掉线,重新登录

首页 > 绿虎论坛 > 历史版块 > 编程 > PHP > 讨论/求助

[CTF]安全大赛,决赛题目。唯一和PHP有关的题目,大佬进来看看


『回复列表(31|隐藏机器人聊天)』

21.

呃,从@老虎会仰泳 的截图来看,它甚至都没有修复会调用有问题的对象本身的析构函数这个问题。
所以 https://github.com/php/php-src/commit/20ce2fe8e3c211a42fee05a461a5881be9a8790e 仅仅只是从测试用例出发,只是阻止了有问题的对象从unserialize返回,没有任何进一步的思考???

图片.png

(/@Ta/2021-11-01 18:35//)

22.

实验结果表明,@老虎会仰泳 左边的代码确实说明了,PHP不会调用有问题的对象的析构函数。而且@老虎会仰泳 犯了一个错误,他没有看到\0Wo\0name中的\0(因为它不会在终端里显示)。

我的测试用例:

<?php
class Wo {
    private $name = 'mmmm111111111';

    public function __wakeup() {
        echo "__wakeup\n";
    }

    public function __destruct() {
        echo "__destruct\n";
        var_dump($this->name);
    }
}

echo "----------- normal -----------\n";
$WoObj = new Wo();
echo str_replace("\0", '\0', serialize($WoObj)), "\n";
var_dump($WoObj);
$WoObj = null;

echo "----------- normal -----------\n";
$WoObj2 = unserialize(<<<EOF
O:2:"Wo":1:{s:8:"\0Wo\0name";s:13:"mmmm111111111";}
EOF);
var_dump($WoObj2);
$WoObj2 = null;

echo "----------- bad -----------\n";
$WoObj3 = unserialize(<<<EOF
O:2:"Wo":2:{s:8:"\0Wo\0name";s:1:"mmmm";}
EOF);
var_dump($WoObj3);
$WoObj3 = null;

运行结果:
image.png

bad那一段确实没有调用析构函数。PHP开发者可能觉得这样就足够了,但是没想到还可以通过外层对象的析构函数使用有问题的数据。

(/@Ta/2021-11-01 19:03//)

23.

确实如此,外部对象的析构函数可以触发,并且可以使用内部有问题的对象数据。

<?php
class A {
    private $name = 'hello';

    public function setName($name) {
        $this->name = $name;
    }

    public function __destruct() {
        echo "__destruct\n";
        echo $this->name, "\n";
    }
}

class B {
    private $name = 'world';

    public function setName($name) {
        $this->name = $name;
    }

    public function __toString() {
        return $this->name;
    }

    public function __wakeup() {
        echo "__wakeup\n";
        $this->setName('no unserialize');
    }
}

echo "----------- normal -----------\n";
$a = new A();
$a->setName(new B());
echo str_replace("\0", '\0', serialize($a)), "\n";
var_dump($a);
$a = null;

echo "----------- normal -----------\n";
$a2 = unserialize(<<<EOF
O:1:"A":1:{s:7:"\0A\0name";O:1:"B":1:{s:7:"\0B\0name";s:5:"pwned";}}
EOF);
var_dump($a2);
$a2 = null;

echo "----------- bad -----------\n";
$a3 = unserialize(<<<EOF
O:1:"A":1:{s:7:"\0A\0name";O:1:"B":2:{s:7:"\0B\0name";s:5:"pwned";}}
EOF);
var_dump($a3);
$a3 = null;

image.png

(/@Ta/2021-11-01 19:26//)

24. @老虎会游泳,目前topthink这种php框架 内,好像大量采用了序列化,是否有必要通知下呢
(/@Ta/2021-11-02 17:06//)

25.

@老虎会游泳,我理解的json化是:对象出了车祸,被压路机压扁了,变成了一张纸,已经死了。有些东西已经失真了,但是还能看出原样的必要信息。
序列化就是量子转移,分解成最小原子,在特定环境下还能还原出来
小米MIX2s(白)

(/@Ta/2021-11-03 09:48//)

26.

@老虎会仰泳@胡椒舰长@水木易安,php的开发者说__wakeup()不是安全措施,反序列化不信任的内容本身就是不安全的。他们可能不会修复该问题了,该问题以后也可以一直出现在比赛题中了,并且不限php版本。

Screenshot_20211103_170306_com.huawei.browser.jpg

(/@Ta/2021-11-03 17:06//)

27.

@老虎会游泳,意思就是我以后要自己来处理。

顺便提一句,我之前在上面做的测试太不严谨了,自己也没仔细看就发表了评论,希望大家引以为戒。
白日梦还是要做的blog.wz52.cn

(/@Ta/2021-11-03 17:09//)

28.

@老虎会仰泳,嗯,不要把serialize的内容发给用户,改用JSON。@胡椒舰长,如果serialize的内容只是在内部使用,从未接收来自用户的serialize内容,则没有安全问题。

(/@Ta/2021-11-03 17:09//)

29.

牛啊牛啊
小米MIX2s(白)

(/@Ta/2021-11-03 17:10//)

30.

@水木易安,你在25楼的理解是正确的。序列化可以还原对象的类,JSON则不能,只有对象的属性。所以从用户侧接收JSON是安全的,接收序列化内容则不安全。

(/@Ta/2021-11-03 17:15//)

31.
小米MIX2s(白)
(/@Ta/2021-11-03 17:15//)

32.

按照“serialize的内容只是在内部使用,从未接收来自用户的serialize内容”这个标准,虎绿林在帖子里存储serialize内容其实是安全的。不过我还是改成了JSON,因为JSON有一个好处:不在结构里存储内容长度。

所以我终于可以进行这种替换了:

update hu60_bbs_topic_content set content=replace(content, 'file.hu60.cn//////', 'file.hu60.cn/') where content like '%file.hu60.cn//////%'

从SQL也能看出来,使用serialize的时候想要做个替换是多么辛苦。为什么有那么多/?因为它来自上一次替换,并且不等长替换会导致serialize结构错误。

(/@Ta/2021-11-03 17:20//)

上一页 2/2页,共31楼

回复需要登录

7月4日 20:28 星期五

本站由hu60wap6驱动

备案号: 京ICP备18041936号-1