代码审计-PHP反序列化漏洞

打印 上一主题 下一主题

主题 775|帖子 775|积分 2335

什么是序列化
序列化可以实现将对象压缩并格式化,方便数据的传输和存储。
为什么要序列化?
PHP 文件在执行结束时会把对象销毁,如果下次要引用这个对象的话就很麻烦,所以就有了对象序列化,实现对象的长久存储,对象序列化之后存储起来,下次调用时直接调出来反序列化之后就可以使用了。
学习序列化要了解的基本内容。
类(Class): 类的定义包含了数据的形式以及对数据的操作。
对象:对象是类的实例。
方法:类中定义的函数。
  1. [/code]展示结果(前提条件,php只有再apache下可以运行,之前我创建了txt,发现无法运行,避免踩坑)
  2. 序列化之后的结果,每个字符都具有具体含义
  3. [img]https://img2022.cnblogs.com/blog/2955483/202208/2955483-20220819171126667-1214939944.png[/img]
  4. O:4:"Test":3: {s:7:"Testa";s:7:"private"; s:1:"b";
  5. s:6:"public"; s:4:"*c";
  6. s:9:"protected";}
  7. O Object 对象
  8. 4 名字长度为 4  Test(对象名称)
  9. 3 表示对象中存在3个属性
  10. [code]s:7:"Testa"; 变量名字
  11. s:7:"private"; 值
复制代码

  • s string 字符串
  • 7 变量名长度为7  private私有的,会在Testa前后添加\00 ,即\X00Test\X00a (因此长度为7)
  • s string 字符串
  • 7 变量的值长度为7   private 值
  1. s:1:"b";
  2. s:6:"public"
复制代码

  • s string
  • 1 名字长度 1
  • b 变量名字
  1. s:4:"*c";
  2. s:9:"protected";
复制代码

  • s string
  • 4 名字长度 4
  • *c 变量名字  \x00*\x00c
序列化的过程:
通过classTest创建一个对象,然后把这个对象进行序列化,打印出来
反序列化:
PHP 反序列化漏洞又叫做 PHP 对象注入漏洞,成因在于代码中的 unserialize() 接收的参数可控,从上面的例子看,这个函数的参数是一个序列化的对象,而序列化的对象只含有对象的属性,那我们就要利用对对象属性的篡改实现最终的攻击
代码如下:
(注意:Testa和*c的部分要留出空格来,与前面的的长度相符合)
输出要用var_dump而不是echo
  1. [/code]结果如下:
  2. [code]object(__PHP_Incomplete_Class)#1 (4) {
  3.   ["__PHP_Incomplete_Class_Name"]=>
  4.   string(4) "test"
  5.   [" Test a"]=>   //名字
  6.   string(7) "private"  //值
  7.   ["b"]=>  //名字
  8.   string(6) "public"   //值
  9.   [" * c"]=> //名字
  10.   string(9) "protected"   //值
  11. }
复制代码
反序列化造成漏洞的原因:

  • 反序列化一般都是用户传递过来恶意代码,通过反序列化执行
  • 反序列化的字符串用户可以控制
  • 内容长度改变以后,前面的长度也需要跟着改变
序列化-魔术方法
魔术方法介绍:
方法:类中定义的函数。
上面我们演示了如何进行序列化和反序列化,但是我们仅使用了属性,也就是变量,变量我们可以当
做数据来看待,而编程就是对数据进行一些列的操作和处理,操作和处理数据的过程我们一般通过函数来
定义,函数在面向对象编程中我们一般称之为方法,所以后续如果老师说到方法就等于说的是函数功能。
特殊的方法-魔术方法。
PHP 将所有以 __(两个下划线)开头的类方法保留为魔术方法,这些都是 PHP 内置的方法。
__construct 当一个对象创建时被调用,
__destruct 当一个对象销毁时被调用,
__wakeup() 使用 unserialize 时触发
__sleep() 使用 serialize 时触发
__call() 在对象上下文中调用不可访问的方法时触发
__callStatic() 在静态上下文中调用不可访问的方法时触发
__get() 用于从不可访问的属性读取数据
__set() 用于将数据写入不可访问的属性
__isset() 在不可访问的属性上调用 isset()或 empty()触发
__unset() 在不可访问的属性上使用 unset()时触发
__toString() 把类当作字符串使用时触发,返回值需要为字符串
__invoke() 当脚本尝试将对象作为函数调用时触发

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

来自云龙湖轮廓分明的月亮

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表