PHP序列化和反序列化

序列化与反序列化是什么

这其实是为了解决 PHP 对象传递的一个问题,因为 PHP 文件在执行结束以后就会将对象销毁,这样当你想用时又没得调用,于是人们就想出了一种能长久保存对象的方法,这就是 PHP 的序列化。
php序列化可以将对象转换成字符串,但只序列化属性,不序列化方法

序列化的目的是方便数据的传输和存储. json 是为了传递数据的方便性.
关键函数:

  • 序列化函数 serialize
  • 反序列化函数 unserialize

常见魔术方法:

  • __construct(),类的构造函数,当对象创建时会自动调用(但在unserialize()时是不会自动调用的)。

  • __destruct(),类的析构函数

  • __call(),在对象中调用一个不可访问方法时调用

  • __callStatic(),用静态方式中调用一个不可访问方法时调用

  • __get(),获得一个类的成员变量时调用

  • __set(),设置一个类的成员变量时调用

  • __isset(),当对不可访问属性调用isset()或empty()时调用

  • __unset(),当对不可访问属性调用unset()时被调用。

  • __sleep(),执行serialize()时,先会调用这个函数

  • __wakeup(),执行unserialize()时,先会调用这个函数

  • __toString(),类被当成字符串时的回应方法

  • __invoke(),调用函数的方式调用一个对象时的回应方法

  • __set_state(),调用var_export()导出类时,此静态方法会被调用。

  • __clone(),当对象复制完成时调用

  • __autoload(),尝试加载未定义的类

  • __debugInfo(),打印所需调试信息

php反序列化漏洞必须要两个条件:

  1. 存在反序列化漏洞的php对象

  2. unserialize函数漏洞可控

PHP反序列化利用

__wakeup()绕过

序列化后,当对象的属性(变量)数大于实际的个数时,__wakeup()魔法函数被绕过
只适用于PHP5.6.25之前版本和7.0.10之前的7.x版本
--------例题:[网鼎杯 2020 青龙组]AreUSerialz

对象逃逸

--------例题:[安洵杯 2019]easy_serialize_php

字符串逃逸

--------例题:[0CTF 2016] piapiapia

p.s. 具体差别在哪我也没有分清,上面一道是关键词数减少,
下面这道是关键词数增加,where->hacker,这样词数由五个增加到6个,导致字符串溢出,即尾部字符串逃逸,改变序列化结构。

pop链构造

总结来说,就是从unserialize函数出发,看看有没有我们可控的参数,再寻找类中我们可控的属性,构造pop链,(通常就是出发各种魔术方法),去调用危险函数。详细的话去看下面两篇推荐博客吧,人家写得比我好。
代码审计的时候,除了常见的include,file_get_contents,unlink等函数,还可以关注下面几个命令执行的函数
exec( ),passthru(),popen(),system()

Phar文件反序列化

phar 文件包在 生成时会以序列化的形式存储用户自定义的 meta-data ,配合 phar:// 我们就能在文件系统函数 file_exists() is_dir() 等参数可控的情况下实现自动的反序列化操作,于是就能通过构造精心设计的 phar 包在没有 unserailize() 的情况下实现反序列化攻击,使得 PHP 反序列化漏洞的触发条件大大拓宽了。可以自己去百度一下phar文件结构。
如何伪造phar文件?

注意:要将php.ini中的phar.readonly选项设置为Off,否则无法生成phar文件

一个简单的示例–test.php:

class request{
    public $filename="phpinfo();";
}

	$phar = new Phar("test.phar");//后缀名必须为phar
	$phar->startBuffering();
	$phar->setStub("<?php __HALT_COMPILER();?>")//设置stub,必写,进行表识phar文件
	$o = new request();
	$phar->setMetadata($o);//自定义meta-data然后存入mainfest
	$phar->addFromString("flag.php","flag");//添加要压缩的文件
	$phar->stopBuffering();

将test.php上传到服务器后,访问就可以生成test.phar,再通过phar://test.phar/flag.php 就能拿到flag
在这里插入图片描述

参考博客:

从CTF中学习PHP反序列化的各种利用方式
PHP反序列化从初级到高级利用篇
php反序列化|无unserialize函数反序列化漏洞
PHP序列化和反序列化
初探PHP反序列化

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值