【PHP反序列化】ctf基础知识

下面的图片在学习的过程种截取的b站-橙子科技,师傅们可以在b站查看

一、php面向对象基础

前置条件

  • **面向对象:**一个直接呈现的结果 如游戏:王者荣耀
  • **面向过程:**一个过程事件

序列化主要针对的是面向对象的过程 ,面向对象->类

  • 变量(属性):如var $a=1
  • 函数(方法)function A()
<?php
class A(){        #类
  var $a;
  var $b='track'     #属性
  function xxx(){   #方法
    .......
  }
  echo $this->b;  # $this是内置方法,调用当前类下的变量
} 
?>

定义变量

<?php
class A(){
  var $a;   //基础定义
  public $a;   //全部可用
  private $b;  //外部不可用,只使用于当前类下
  protected $c;  //内部和子类可用
}

赋值与输出

<?php
class A{    //类
    var $a;     //属性
    var $b;
    function jineg($var1){  //方法,$var是变量
        echo $this->a;      //指向
        echo $var1;         //输出传入的变量
    }
}
$i = new A();
$i -> a= 'hello';
$i -> b= 'track';
$i-> jineg("hyhy");
print_r($i);
/*
hellohyhyA Object
(
    [a] => hello
    [b] => track
)
*/
?>

二、序列化基础知识

序列化与赋值

<?php
class A{
    var $a;
    var $b;
    function jineg(){
        echo $this->a;
    }
}
$i = new A();
$i -> a= 'hello';
$i -> b= 'track';
echo serialize($i);
?>

结果:

   O:1(类的数量):"A":2(属性数量):{s(字符串):1((字符长度):"a";s:5:"hello";s:1:"b";s:5:"track";}
//对象                           字符类型               变量名     值

三、魔术方法

首先在学习魔术方法,需要了解他们是如何被利用,即每个方法的触发点在哪,触发效果是什么,触发优先级是什么,如xx之前/xx之后

常见魔术方法

__construct()

  • 触发时机:只触发一次,当对象创建时(即使用new关键字)会自动调用,即创建一个类 如:$a= new A();
  • 反序列化中的行为:在反序列化时不会自动调用。

示例

class A{
    var $cmd="system('id');";
    public function _construct(){
        eval($this->$cmd);       #执行命令
        }
}

$a=new A();             #当对象被实例化后,会自动调用函数
echo serialize($a);

__destruct()-析构函数

  • 触发时机:当对象被销毁时会自动调用。反序列化之后/实例化对象
  • 反序列化中的行为:这是反序列化漏洞中最常利用的魔术方法之一,因为只要对象生命周期结束,就会触发此方法。

如下会触发两次,一次是实例化对象,一次是反序列化

代码如下

<?php
class A{
    var $cmd="system('id');";
    public function _destruct(){
        eval($this->$cmd);       #执行命令
        }
}

$aaa=new A();           
echo serialize($aaa);   #O:1:"A":1:{s:3:"cmd";s:13:"system('id');";}
#$ser=$_GET['aaa'];
#unserialize($ser);
?>

__toString()-常用来构造pop链

  • 触发时机:当一个对象被当作字符串使用时会自动调用。
  • 反序列化中的行为:如果反序列化后的对象在某个上下文中被当作字符串处理,则会触发该方法。
class A{
    var $user='hello';
    public function __toString(){   //当一个对象(类)被当作字符串使用时会自动调用
        return "track";
    }
}
$a= new A();
print_r($a);
echo serialize($a);  #O:1:"A":1:{s:4:"user";s:5:"hello";}
echo $a;             #track  当执行时会把$a当作字符串打印,即会调用该方法

__invoke()-常用于构造pop链

  • 触发时机:当脚本尝试将对象作为函数调用时会自动调用。
  • 反序列化中的行为:如果反序列化后的对象在某个上下文中被当作函数调用,则会触发该方法。
function B(){
    echo '没有调用方法';
}

class A{
    public $user='hello';
    public function __invoke(){   #当对象被当作函数执行调用
        echo "调用了该方法";
    }
}  
B();        #没有调用方法
$a=new A();   
$a();       #调用了该方法,因为该对象被当作一个函数执行

__sleep()

  • 触发时机:在对象被序列化前会自动调用。
  • 反序列化中的行为:虽然它在序列化时调用,但可以影响最终序列化的数据,从而间接影响反序列化。

会在对象被序列化之前触发,最终返回两个值

__wakeup()

  • 触发时机:在对象被反序列化之前会自动调用。
  • 反序列化中的行为:这是另一个常被利用的方法,因为它在反序列化过程中会被立即调用,用于重新建立数据库连接或其他资源初始化。

用一段代码解释

class A{
    public $user;
    public $pass;
    public function _wakeup(){           #当反序列化执行之前会调用
        system($this->$user);
    }
}
#$x=$_GET['xx'];
#unserialize($x);
$a=new A();
$a->user="id";          #赋值
echo serialize($a);     #调用_wakeup()方法
#O:1:"A":2:{s:4:"user";s:2:"id";s:4:"pass";N;}

#碰到这样的题目,其实可以简写
class B{
  public $user='id';
}
echo serialize(new B());
#O:1:"B":1:{s:4:"user";s:2:"id";}

三、魔术方法-错误调用

__call()

  • 触发时机:当调用一个不可访问或不存在的方法时会自动调用。 方法-函数
  • 反序列化中的行为:如果反序列化后的对象尝试调用一个不存在的方法,会触发该方法。

如下,第一个变量返回方法,第二个返回属性,即返回值为 callxxx,a

__callStatic()

静态调用,作用和call相同,只不过调用方法不一样

__get() 和 __set()

  • 触发时机:当尝试访问或设置一个不可访问或不存在的属性时会自动调用。
  • 反序列化中的行为:如果反序列化后的对象尝试访问或设置这样的属性,会触发这些方法。

如下会返回var2

set会给不存在的赋值

__isset()和 __unset()

  • 触发时机:当对一个不可访问或不存在的属性使用**isset()unset()**时会自动调用。
  • 反序列化中的行为:类似地,在反序列化后,如果对对象的属性进行这些操作,会触发相应的方法。

调用的属性不可用

__clone()

  • 触发时机:当对象被克隆时会自动调用。
  • 反序列化中的行为:如果反序列化后的对象被克隆,会触发该方法。

这里会自动触发clone方法,因为克隆了一个新类

四、pop链


不可用

[外链图片转存中…(img-POOwJUJ1-1746499615004)]

__clone()

  • 触发时机:当对象被克隆时会自动调用。
  • 反序列化中的行为:如果反序列化后的对象被克隆,会触发该方法。

这里会自动触发clone方法,因为克隆了一个新类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值