加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

深入分析PHP对象注入分析

发布时间:2022-07-02 17:13:45 所属栏目:PHP教程 来源:互联网
导读:前提知识: 在php类中可能会存在一些叫做魔术函数(magic 函数),这些函数会在类进行某些事件的时候自动触发,例如__construct()会在一个对象被创建时调用,__destruct()会在一个对象销毁时调用,__toString当对象被当做一个字符串的时候被调用。常见的魔术函
  前提知识:
 
  在php类中可能会存在一些叫做魔术函数(magic 函数),这些函数会在类进行某些事件的时候自动触发,例如__construct()会在一个对象被创建时调用,__destruct()会在一个对象销毁时调用,__toString当对象被当做一个字符串的时候被调用。常见的魔术函数有__construct()、__destruct()、__toString()、__sleep()、__wakeup()。
 
  举例如下:
 
  <?php
  class test{<br>
      public $varr1="abc";
           return array('varr1','varr2');
      }<br>
      public function __wakeup(){
          echo "__wakeup<br>";
      }
  } //phpfensi.com
  $obj = new test();      //实例化对象,调用__construct()方法,输出__construct<br>
  $obj->echoP();          //调用echoP()方法,输出"abc"<br>
  echo $obj;               //obj对象被当做字符串输出,调用__toString()方法,输出__toString<br>
  $s  =serialize($obj);     //obj对象被序列化,调用__sleep()方法,输出__sleep<br>
  echo unserialize($s);      //$s首先会被反序列化,会调用__wake()方法,被反序列化出来的对象又被当做字符串,就会调用_toString()方法。<br>
  // 脚本结束又会调用__destruct()方法,输出__destruct<br>
  ?>
  原理:
 
  为什么会用到序列话这样的方法?主要就是就是方便进行数据的传输,并且数据恢复之后,数据的属性还不会发生变化。例如,将一个对象反序列化之后,还是保存了这个对象的所有的信息。同时还可以将序列化的值保存在文件中,这样需要用的时候就可以直接从文件中读取数据然后进行反序列化就可以了。在PHP使用serialize()和unserialize()来进行序列化和反序列化的。
 
  而序列化的危害就在于如果序列化的内容是用户可控的,那么用户就可以注入精心构造的payload。当进行发序列化的时候就有可能会出发对象中的一些魔术方法,造成意想不到的危害。
 
  对象注入:
 
  本质上serialize()和unserialize()在PHP内部实现上是没有漏洞的,漏洞的主要产生是由于应用程序在处理对象、魔术函数以及序列化相关问题的时候导致的。
 
  如果在一个程序中,一个类用于临时将日志存储进某个文件中,当__destruct()方法被调用时,日志文件被删除。代码大致如下:
 
  logfile.php
 
   在其他类中使用LogClass
 
  logLogin.php
 
  <?php
  <a href="/tags.php/include/" target="_blank">include</a> "index.php";
  $obj = new LogClass();
  $obj->logfilename = "login.log";
  $obj->logdata('记录日志');
  ?>
  上面的这段代码就是一个正常的使用LogClass类来完成日志记录的功能。
 
  下面显示的是存在对象注入漏洞的使用例子。
 
  news.php
 
  <?php
  include "logfile.php";
  // some codes the use the LogClass
  class User {
      public $age = 0;
      public $name = '';
      public function print_data() {
          echo "User".$this->name."is".$this->age."years old.<br/>";
      }
  }
  // 从用户接受输入发序列化为User对象
  $usr = unserialize($_GET["user"]);
  ?>
  上面显示的代码使用了LogClass对象同时还会从用户那里接受输入进行发序列化转化为一个User对象。
 
 
  那么最后就会输出delete .htaccess。
 
  可以看到通过构造的数据,导致执行了LogClass中的__destruct()方法然后删除了网站中重要的配置文件。
 
  从上面这个例子也可以看出来,如果没有严格控制用户的输入同时对用户的输入进行了反序列化的操作,那么就有可能会实现代码执行的漏洞。
 
  注入点:
 
  PHP对象注入一般在处在程序的逻辑上面。例如一个User类定义了__toString()用来进行格式化输出,但是也存在File类定义了__toString()方法读取文件内容然后进行显示,那么攻击者就有可能通过User类的反序列化构造一个File类来读取网站的配置文件。

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读