如何?WEB安全(六)

php反序列化

按照我学习的次序,慢慢的已经说到了反序列化了。

这个我个人觉得还是比较简单的,因为它大部分已经不是你可以操作的了,都是PHP这个语言自已已经预定义好的函数。

那么先说说序列化到底是个什么东西呢,在互通互联的这个时代,光纤等之间传播的是字节流,根据一定规则形成的字节流。序列化正是为了能够更加方便传输而设计的,将数据结构转变成字节进行传递,接收后还可以反序列化进行还原,虽然失去了一些信息。但只要有相同的模板,表明的是相同的对象,一切就都还原了。

可能我说的不是很明白,为了讲明白我上面所说的东西。简单给大家说一下面向对象思想,PHP支持这种思想的编程,因此如果不好好考虑周全,可能会出现反序列化漏洞。

面向对象程序开发思想

在我看来,这种思想相对于面向过程开发,注重的是抽离出抽象的概念,赋予它相关的属性,他的功能。对于这整个的抽象概念我们成为其,也叫class

比如,人这个概念。抽象出来,就是他有属性:年龄、身高、性别等等,他的功能是:吃饭、睡觉等等。

其中属性我们可以叫它属性或者数据,功能我们叫它函数(功能)或者方法

下面我用PHP写一个类,供大家观赏,理解一下。

php 复制代码
<?php
    class man{
    public $name;
    public $age;
    
    
    public function eat(){
        echo "eating";
    }
}

当然php也有相应的静态属性和静态变量,所不同的地方就是添加static关键词还有静态属性,使用::并带有$来调用,静态方法不需要加$但要加前者。

而动态的变量在类外面引用的时候不需要在变量前添加$,比如:$who=new man(); $who->name="Raya";这种方式。

对类当中的方法调用时:$who->eat();来完成。

有了这些前置的知识,接下来要说一说序列化和反序列化了,这在网络传输当中经常使用到(或许还有其他用途,我目前知识并不清楚)。在序列化之后(以php举例,其他语言也有序列化函数,只不过有些不同),会生成一段规则的字符串,例如:

php 复制代码
O:6:"person":3:{s:4:"name";s:5:"lihua";s:3:"age";i:20;s:6:"height";i:170;}

以上就是被一个初始化的person类进行的序列化,我们会注意到里面除了可以依稀辨别的字符串和数值,还有其他的一些信息,比如o或者s之类,它们是用于携带原信息之外的信息的(如果有兴趣可以去查以下对应表)。

描述它们的不同数据类型,后面跟着的一个整数表示后面字符串的所占的字节数(我认为是这样的),需要一一对应,不然可能无法还原成功。

其序列化使用的函数叫:serialize(),反序列化的叫:unserialize()

还有一个问题就是,当我们序列化之后还要看得就是那些变量的访问权限,会有public、protected、private以及缺省不写(会默认public级别)这几种。关于public这种没关系,剩下两种的序列化字符串当中存在一些不可打印字符:protected 修饰的属性被序列化的时候属性值会变成%00*%00属性名;private 修饰的属性被序列化的时候属性值会变成%00类名%00属性名

这时候需要对其进行url编码或者base64编码来传输,不然会出现数据丢失,导致错误。

这里要说的还有一点就是,php当中,以及其他的某些编程语言当中会存在一些魔术方法,它们不需要显示的调用,达到一定条件之后自动触发,程序员可自定义书写触发内容。

这也就是漏洞的成因,如果通过构造特定的类对象,就可能会出现严重的危险。

它们通常以两个下划线开头,比如php类的构造方法就是如此。

  1. __construct(),类的构造函数
  2. __wakeup(),执行unserialize()时,先会调用这个函数
  3. __destruct(),类的析构函数,允许在销毁一个类之前执行的一些操作或完成一些功能,通常程序结束时会触发
  4. __call(),在对象中调用一个不可访问方法时调用
  5. __get(),获得一个类的非公有成员变量时调用
  6. __set(),设置一个类的成员变量(非公有)时调用
  7. __toString(),对象被当成字符串处理时的方法
  8. __invoke(),调用函数的方式调用一个对象时的回应方法
  9. __callStatic(),用静态方式中调用一个不可访问方法时调用
  10. __isset(),当对不可访问属性调用isset()或empty()时调用
  11. __unset(),当对不可访问属性调用unset()时被调用。
  12. __sleep(),执行serialize()时,先会调用这个函数
  13. __set_state(),调用var_export()导出类时,此静态方法会被调用。
  14. __clone(),当对象复制完成时调用
  15. __autoload(),尝试加载未定义的类
  16. __debugInfo(),打印所需调试信息

以上是一些相关的魔术方法,大多数都有执行的条件,其中有两个是只要定义就会被执行的:__wakeup()还有__destruct()。

大部分的方法无法跳过,满足条件自动执行,但是__wakeup()函数如果反序列化出现的对象存在问题就会跳过执行,有时会使用到这个知识点。

由于php是一个弱类型语言,我们甚至可以对类中未赋值的变量赋值任何类型的值,甚至是一个类。

如果是在解这方面题,首先要去看是什么语言,遵守其序列化和反序列化的规则,其实就是构造一条长长的反序列化漏洞传递链条,先尝试找到可以自动触发的魔术方法,没有再去看其他方法有无可能,之后根据语言的操作内容构造一个以上的类对象,将其序列化然后传入相应位置,让代码执行。

我想说的就是这么多,剩下的就是做题之类的找到相应的感觉。

但这里主要是总结知识点,做题部分如果有机会我会发布一个新的文章,一定会有的。

相关推荐
Flying_Fish_roe4 小时前
linux-网络管理-网络配置
linux·网络·php
huaiyanchen6 小时前
chorme浏览器 您的连接不是私密连接
安全
安全方案8 小时前
政务安全运营核心能力模块
安全
aqymnkstkw9 小时前
2024年【电气试验】考试题库及电气试验模拟试题
大数据·c语言·人工智能·嵌入式硬件·安全
xiaojiesec9 小时前
第157天: 安全开发-Python 自动化挖掘项目&SRC 目标&FOFA 资产&Web 爬虫解析库
python·安全
亿林科技网络安全10 小时前
阿里云盘照片事件!网络安全警钟长鸣
网络·安全·web安全
玄客)11 小时前
MACCMS 远程命令执行漏洞复现(CVE-2017-17733)
学习·安全
HinsCoder11 小时前
【渗透测试】——Upload靶场实战(1-5关)
笔记·学习·安全·web安全·渗透测试·测试·upload靶场
newxtc12 小时前
【天怡AI-注册安全分析报告-无验证方式导致安全隐患】
人工智能·安全