专栏首页Gcow安全团队潜藏在PHP安全的边缘——浅谈PHP反序列化漏洞

潜藏在PHP安全的边缘——浅谈PHP反序列化漏洞

潜藏在PHP安全的边缘——浅谈PHP反序列化漏洞

注意事项:
1.本篇文章由复眼小组的瞳话原创,未经允许禁止转载
2.本文一共1376字,8张图,预计阅读时间6分钟
3.本文比较基础,请大佬酌情观看,如果有其他的骚思路,欢迎和我们交流

0x00.前言

最近在研究代码审计漏洞的时候,特别注意了一下PHP反序列化漏洞,该漏洞又被成为PHP对象注入,个人感觉比较有意思,所以通过通俗易懂的语言来简单说一下PHP反序列的安全问题。

0x01.理解序列化与反序列化

百度说明:

听起来似乎似懂非懂,那么用通俗的语言讲,就是将对象里面的信息改变成可以传输的格式,说到这里是不是突然想起来json传输格式了呢,其实道理是一样的,接下来请看演示的demo。

这里我定义了一个对象,并填写了两个类属性和一个类方法,并在代码第9行实例化成了一个对象,第10行使用serialize函数进行序列化操作,并输出

查看执行结果之后,可以发现,这就是序列化之后的格式

解读一下分别是什么意思:O是对象的意思中间用:进行分割,6的意思是对象的name值为6个字节,往下看,2的意思是有两个类属性花括号类属性的内容S类属性9类属性name的长度,依次往下类推

值得一提的是,类方法并不会参与到实例化里面

明白了序列化操作,那么来理解一下什么是反序列化,顾名思义,就是将序列化之后的信息再反回去

这里接收一个ser的参数,然后使用反序列化函数unserialize进行反序列化处理,最后使用var_dump进行输出。

可以看到将我们输入的序列化后的信息又变回了一个对象,这就是反序列化操作

0x02.漏洞产生

在代码审计中只要记住这一点,代码审计就已经入门了,任何输入都是有害的。试想一下,既然被称为PHP对象注入,那么是怎么注入进去的呢?必须要有一个输入点,比如SQL注入,是因为在数据库交互的时候前端可控,导致的漏洞,那么对象注入,也要有一个输入点,所以我在下面写了一个demo,再次之前我们需要了解一下PHP中常见的魔法函数(又称魔术方法).

•__construct()当一个对象创建被时被调用
•__destruct()当一个对象销毁时被调用
•__toString()当一个对象被当作一个字符串使用
•__sleep()在对象在被序列化之前运行
•   __wakeup在将在反序列化之后立即被调用

为什么被称为魔法函数呢,因为是在触发了某个事件之前或之后,魔法函数会自动调用执行,而其他的普通函数必须手动调用才可以执行,PHP中魔法函数的开头都是以__(双下划线)为前缀,所以在定义函数的时候尽量不要使用双下划线为前缀

接下来看demo,这里定义了一个类,并在类里面添加了一个属性和魔术方法,该模式方法的触发条件为对象被反序列化之后立即调用,也正是这个方法导致了PHP反序列化漏洞的产生

先看到第5行的代码,有一个危险函数system,system里面是可控的,但是如果我们直接去输入一个系统命令是不能调用的,那么我们可以看到第9行有一个反序列的函数,并且函数内部也是可控的,那么我们就可以搞一些事情了。

php生成序列化之后的信息

序列化之后的信息为:

O:4:"Test":1:{s:3:"cmd";s:6:"whoami";}

然后,后面输入要执行的命令,前面的数值也要因命令的长度进行改变,这样就可以执行任意命令。如图后面的指令为ls,前面的数值变为"ls"的长度为2

0x03 原理解读

首先要说的是,危险函数被带入到魔法函数里面,这是一种非常危险的行为,然后system函数里面执行内容可控,引用了cmd这个类属性,从下面进行了实例化之后,然后进行反序列操作,因为反序列化函数里面的内容是可控的,那么我们可以输入序列化之后的数据,并改变信息中cmd的值(也就是whoami),原有的$cmd的值被我们新输入的值覆盖掉,并且执行完这些操作之后,魔法函数就像一颗定时炸弹,直接引爆,导致了命令执行,这就是为什么会被成为对象注入的原因。

0x04 漏洞修复

  1. 在用户可输入的地方进行过滤,或添加白名单验证,
  2. 应当避免危险函数带入到魔法函数里面
  3. 在情况允许的情况下不要让反序列函数可以被用户输入控制,尽量写死

本文分享自微信公众号 - Gcow安全团队(Gcow666),作者:复眼小组

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • VulnHub通关日记-Mr-Robot-1-Nmap提权获取Flag

    靶机介绍:根据演练,机器人先生。此VM具有隐藏在不同位置的三个Key。您的目标是找到全部三个。每个Key逐渐难以找到。该级别被认为是初学者-中级。 下载地址:h...

    Gcow安全团队
  • CVE-2017-12824及利用样本分析

    笔者于书写此文之前从未接触过InPage,该文权当笔者于学习过程中的文章学习笔记,其中如有不当或错误之处,望读者不吝赐教,笔者感激不尽。

    Gcow安全团队
  • 代码审计之DTCMS V5.0后台漏洞两枚

    Gcow安全团队
  • Dubbo序列化概述

    Dubbo序列化支持java、compactedjava、nativejava、fastjson、fst、hessian2、kryo,其中默认hessian2。...

    丁威
  • Java基础-序列化与反序列化

    序列化和反序列化在面试中也经常考查,下面就总结一下 Java 中的序列化和反序列化。

    Wizey
  • 奈学:一起了解几种序列化协议

    序列化(编码)是将对象序列化为二进制形式(字节数组),主要用于网络传输、数据持久化等;而反序列化(解码)则是将从网络、磁盘等读取的字节数组还原成原始对象,主要用...

    江帅帅
  • java序列化和序列化ID的作用

    谈到java序列化其实大家都能说出一二, java对象序列化的意思就是将对象的状态转化成字节流,以后可以通过这些值再生成相同状态的对象。对象序列化是对象持久化的...

    用户7625070
  • 序列化与反序列化

    现今的后台服务大多是微服务架构,每个服务按照业务进行拆分,实现了服务之间的解耦,而服务之间要记性接口调用实现,服务支架要进行数据对象共享,就要把服务对象转成二进...

    小土豆Yuki
  • Serializable和Parcelable的再次回忆

    自己开发Android也有些时间了,Serializable和Parcelable遇到过不止一次了。但是每次别人问起具体的内容自己偏偏记得不是很清晰。因为某些原...

    静默加载
  • Java程序员必备:序列化全方位解析

    如果想在JVM停止后,把这些对象保存到磁盘或者通过网络传输到另一远程机器,怎么办呢?磁盘这些硬件可不认识Java对象,它们只认识二进制这些机器语言,所以我们就要...

    捡田螺的小男孩

扫码关注云+社区

领取腾讯云代金券