文章详情

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

请输入下面的图形验证码

提交验证

短信预约提醒成功

反序列化漏洞及PHP魔法函数

2023-08-31 09:57

关注

目录

1、漏洞原理

2、序列化(以PHP语言为例)

3、反序列化

4、PHP魔法函数

(1)__wakeup()

(2)__destruct()

(3)__construct()

(4)__toString()

(5)__get()

(6)__call()


PHP反序列化漏洞也叫PHP对象注入,形成的原因是程序未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行、文件操作、执行数据库操作等参数不可控。反序列化攻击在Java、Python等面向对象语言中均存在。序列化是广泛存在于PHP、Java等编程语言中的一种将有结构的对象/数组转化为无结构的字符串并储存信息的一种技术。

PHP类都含有的特定元素:类属性、类常量、类方法。

序列化就是将一个类压缩成一个字符串的方法。

eg:

passwd = $passwd; //将函数传进来的值传给passwd }public function getPasswd(){echo $this->$passwd; //输出passwd }}$Myon = new userInfo(); //创建 userInfo对象实例$Myon->modifyPasswd('123abc'); //调用modifyPasswd函数并将123abc值传进去$data = serialize($Myon); //序列化echo $data;?>

输出结果:

O:8:"userInfo":3{s:16:"userInfopasswd";s:6:"123abc";s:6:"*sex";s:4:"male";s:4:"name";s:4:"Myon";}

对序列化后的字符串进行解读:

大括号外表示“Object”对象名称是“userInfo”,长度为8,这个对象有3个属性。

(特别注意:在CTF中常有一个对 _wakeup() 函数的绕过,当序列化字符串中表示对象属性个数的值大于实际属性个数时,就会跳过wakeup方法的执行。)

在前面的文章中有对CTF题PHP反序列化及绕过实例的讲解,可以参考

http://t.csdn.cn/Mffji

http://t.csdn.cn/wbtkK

大括号内表示这些属性的具体信息及它们的值

根据属性的权限不同,在序列化中的表示方法也不同

从代码中可以看出,三个属性的权限分别是private,protected和public

(1)private权限是私有权限,只能在本类内使用,子类不能继承。
(2)protected权限是私有权限,即只能在类内部使用,子类可以继承这个变量。
(3)public权限就是正常的变量权限,一般声明的变量权限均为public。

标红的是private,前面加上了本类名称;

标蓝的是protected,前面加上了星号;

标绿的是public,没有任何前缀。

一个类经过序列化之后,存储在字符串的信息只有类名称和类内属性键值对,序列化字符串中没有将类方法一并序列化。

反序列化与序列化是相对应的,就是将含有类信息的序列化过的字符串“解压缩”还原成类。

反序列化的类想要使用原先的类方必须依托于域,脱离了域的反序列化的类是无法调用序列化之前的类方法的。

passwd = $passwd; //将函数传进来的值传给passwd }public function getPasswd(){echo $this->$passwd; //输出passwd }}$Myon = new userInfo(); //创建 userInfo对象实例$Myon->modifyPasswd('123abc'); //调用modifyPasswd函数并将123abc值传进去$data = serialize($Myon); //序列化$new_Myon = unserialize($data); //反序列化数据$new_Myon->getPasswd();?>

理论上这里类方法应该被成功执行,但是...

不过有一点可以确定,如果我们单独将序列化后的字符串作为输入,在一个新的域下执行代码片段,肯定是会报错的。

getPasswd();?>

(1)__wakeup()

在PHP中如果需要进行反序列化,会先检查类中是否存在_wakeup()函数,如果存在,则会先调用此类方法,预先准备对象需要的资源。

color = 'white';//将white赋值给color    }    public function printColor()    {         echo $this->color . PHP_EOL; //输出color    }}$my = new example; //实例化对象$data = serialize($my); //进行序列化$new_my = unserialize($data); //反序列化$new_my->printColor(); //调用printColor()函数?>

 可以看到类属性color已经被__wakeup()函数自动调用并修改了

这种函数被称为PHP魔法函数,它在一定条件下不需要被调用而可以自动调用

(2)__destruct()

在对象的所有引用都被删除或类被销毁时自动调用

 可以看到在序列化类的时候,__destruct()函数自动执行了 。

(3)__construct()

此函数会在创建一个类的实例时自动调用

可以看到在序列化之前,实例化时__construct()函数就被调用了。

(4)__toString()

此函数会在类被当作字符串时调用

 可以看到当实例化对象被当作字符串使用时,__toString()函数自动调用。

其他触发此函数的情况:

反序列化对象与字符串连接时。
反序列化对象参与格式化字符串时。
反序列化对象与字符串进行==比较时(PHP进行==比较时会转换参数类型)。
反序列化对象参与格式化SQL语句,绑定参数时。
反序列化对象在经过PHP字符串函数,如strlen()、addslashes()时。
在in_array()方法中,第一个参数是反序列化对象,第二个参数的数组中有toString返回的字符串时,toString会被调用。
反序列化的对象作为class_exists()的参数时。

(5)__get()

在读取不可访问的属性值时自动调用

color; //输出 color 属性?>

因为试图访问私有变量color导致__get()函数自动调用 

(6)__call()

调用未定义的方法时调用

notExistFunction("patameters"); //调用未定义方法?>?>

可以看到__call()函数被调用

也就是说你想让调用方法未定义,那么这个方法名就会作为 __call的第一个参数传入,因此不存在方法的参数会被装进数组中作为 __call的第二个参数传入。



 

来源地址:https://blog.csdn.net/Myon5/article/details/130085687

阅读原文内容投诉

免责声明:

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

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

软考中级精品资料免费领

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

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

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

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

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

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

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