这篇文章将为大家详细讲解有关PHP反序列化漏洞的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。php程序为了保存和转储对象,提供了序列化的方法。php序列化是为了在程序运行的过程中对对象进行转储而产生的。序列化可以将对象转换成字符串,但仅保留对象里的成员变量,不保留函数方法。php序列化的函数为serialize
,可以将对象中的成员变量转换成字符串。反序列化的函数为unserilize
,可以将serialize
生成的字符串重新还原为对象中的成员变量。将用户可控的数据进行了反序列化,就是PHP反序列化漏洞。序列化序列化的目的是方便数据的传输和存储。在PHP应用中,序列化和反序列化一般用作缓存,比如session缓存,cookie等。常见的序列化格式:二进制格式字节数组json字符串xml字符串输出结果为:实际的序列化字符串为对象序列化后的结构为:可以得知,序列化之后的结果是字符串string。Test是一个类,new Test()
表示创建Test类的对象。O表示对象,4表示类的名称有4个字符,Test是类名称。3表示对象中有3个成员变量。括号里面是每个成员的类型、名称、值。变量名和变量值之间以分号分隔。a是public类型的变量,s表示字符串,1表示变量名的长度,a是变量名。b是protected类型的变量,它的变量名长度为4,也就是b前添加了%00*%00
。所以,protected属性的表示方式是在变量名前加上%00*%00
。c是private类型的变量,c的变量名前添加了%00类名%00
。所以,private属性的表示方式是在变量名前加上%00类名%00
。虽然Test类中有test1方法,但是,序列化得到的字符串中,只保存了公有变量a,保护变量b和私有变量c,并没保存类中的方法。也可以看出,序列化不保存方法。反序列化输出内容如下:类的成员变量被还原了,但是类的方法没有被还原。因为序列化的时候就没有保存类的方法。PHP反序列化漏洞中可能会用到的魔术方法现在5个魔法函数的执行顺序就明确了。对象被创建时执行__construct
。使用serialize()
序列化对象。先执行__sleep
,再序列化。unserialize( )
会检查是否存在一个_wakeup( )
方法。如果存在,则会先调用_wakeup()
方法,预先准备对象需要的资源。把对象当做字符串使用,比如将对象与字符串进行拼接,或者使用echo
输出对象,会执行__toString
程序运行完毕,对象自动销毁,执行__destruct
。安全问题如何利用反序列化漏洞,取决于应用程序的逻辑、可用的类和魔法函数。unserialize
的参数用户可控,攻击者可以构造恶意的序列化字符串。当应用程序将恶意字符串反序列化为对象后,也就执行了攻击者指定的操作,如代码执行、任意文件读取等。PHP反序列漏洞的防御方法不允许用户控制unserialize
函数的参数影响版本:PHP5
PHP7
反序列化时,如果表示对象属性个数的值大于真实的属性个数时就会跳过__wakeup( )
的执行。漏洞示例代码如下:获取序列化字符串的脚本如下:正常的序列化字符串为:O:1:"A":1:{s:6:"target";s:4:"test";}
。注意:这里target变量的值是test,长度为4。当我们修改target变量的值时,对应的,也要将值的长度进行修改。在线计算字符串长度程序从GET请求中获取test参数的值,然后将test参数进行反序列化。代码正常的执行逻辑,应该是:unserialize( )
会检查是否存在一个_wakeup( )
方法。本例中存在,则会先调用_wakeup()
方法,预先将对象中的target属性赋值为”wakeup!”。注意,不管用户传入的序列化字符串中的target属性为何值,__wakeup()
都会把$target的值重置为”wakeup!”。最后程序运行结束,对象被销毁,调用__destruct()
方法,将target变量的值写入文件shell.php中。这样shell.php文件中的内容就是字符串”wakeup”。对象序列化后的结构为:O:对象名的长度:"对象名":对象属性个数:{s:属性名的长度:"属性名";s:属性值的长度:"属性值";}
反序列化时,如果表示对象属性个数的值大于真实的属性个数时就会跳过__wakeup( )
的执行。构造如下对象作为payload:这里真实属性个数是1,只有1个target属性。我们在构造序列化字符串时,将表示对象属性个数的值写成任何大于1的整数,就可以跳过__wakeup()
的执行。现在,程序执行的逻辑变为:直接使用unserialize()
函数将用户传递的参数进行反序列化。程序执行结束,对象被销毁,调用__destruct()
方法,将target变量的值写入文件shell.php中。而target变量的值就是我们用户构造的phpinfo()
函数,成功getshell。注意,如果要序列化protected类型的属性,需要在变量名前加上%00*%00
。序列化private类型的属性,需要在变量名前加上%00类名%00
。得到的序列化字符串为:构造的payload为:得到的序列化字符串为:构造的payload为:Drupal Core 8 PECL YAML 反序列化任意代码执行漏洞(CVE-2017-6920)CVE-2017-6920:Drupal远程代码执行漏洞分析及POC构造本例子代码审计中分析反序列化漏洞的方法通过diff有漏洞的版本和漏洞修复的版本,发现漏洞的触发点。在漏洞所在函数的触发点代码中,通过阅读官方文档,找到外部可控的参数,明确漏洞的触发原理。定位漏洞所在函数的调用位置,如果该函数还调用了其它函数,继续跟踪其它函数。最后定位外部可控的输入点。找到漏洞的数据触发点。要利用该漏洞进行远程代码执行,需要一个可以利用的类。如有应用程序使用命名空间的方式来管理类,可以全局实例化一个类,也可以反序列化一个类;该漏洞利用了反序列化,因此需要找一个反序列类。通过__destruct
以及__wakeup
来定位类,全局搜索可以找到几个可利用的类。通过反序列化这些类,可以造成任意文件删除、写入webshell、任意无参数函数执行等危害。漏洞描述2017年6月21日,Drupal官方发布了一个编号为CVE-2017- 6920 的漏洞,影响为Critical。这是Drupal Core的YAML解析器处理不当所导致的一个远程代码执行漏洞,影响8.x的Drupal Core。漏洞验证漏洞环境执行如下命令启动 drupal 8.3.0 的环境:环境启动后,访问http://your-ip:8080/
将会看到drupal的安装页面,一路默认配置下一步安装。因为没有mysql环境,所以安装的时候可以选择sqlite数据库。免费云主机域名漏洞复现先安装yaml
扩展1.登录一个管理员账号2.访问 http://127.0.0.1:8080/admin/config/development/configuration/single/import3.如下图所示,Configuration type
选择Simple configuration
,Configuration name
任意填写,Paste your configuration here
中填写PoC如下:构造了任意无参数函数的POC4.点击Import
后可以看到漏洞触发成功,弹出phpinfo
页面。漏洞修复最新发布的Drupal 8.3.4 已经修复了该漏洞,针对低于8.3.4的版本也可以通过升级Drupal文件/core/lib/Drupal/Component/Serialization/YamlPecl.php
中的decode
函数进行防御漏洞检测针对该漏洞,可采用两种方法进行检测:方法一:登陆Drupal管理后台,查看内核版本是8.x,且版本号低于8.3.4,则存在该漏洞;否则,不存在该漏洞;登录一个管理员账号后,http://127.0.0.1:8080/admin/reports/updates
,当前内核版本为8.3.0
。方法二:在Drupal根目录下找到文件/core/lib/Drupal/Component/Serialization/ YamlPecl.php
,定位到函数public static function decode($raw)
,如果该函数代码不包含" ini_set('yaml.decode_php', 0);"
调用,则存在该漏洞;否则,不存在该漏洞。漏洞环境:Joomla 3.4.5 反序列化漏洞(CVE-2015-8562)参考文献:Joomla远程代码执行漏洞分析(总结)简介本漏洞根源是PHP5.6.13前的版本在读取存储好的session时,如果反序列化出错则会跳过当前一段数据而去反序列化下一段数据。而Joomla将session存储在Mysql数据库中,编码是utf8,当我们插入4字节的utf8数据时则会导致截断。截断后的数据在反序列化时就会失败,最后触发反序列化漏洞。通过Joomla中的Gadget,可造成任意代码执行的结果。影响版本Joomla 1.5.x, 2.x, and 3.x before 3.4.6PHP 5.6
漏洞点——反序列化session这个漏洞存在于反序列化session的过程中。漏洞存在于libraries/joomla/session/session.php
,_validate
函数,将User-Agent
和X_FORWARDED_FOR
调用set
方法设置到了session中。最终,它们会被保存到数据库的session表中。利用|字符伪造,控制整个反序列化字符串joomla也没有采用php自带的session处理机制,而是用多种方式(包括database、memcache等)自己编写了存储session的容器(storage)。其存储格式为『键名 + 竖线 + 经过 serialize() 函数反序列处理的值』,其未正确处理多个竖线的情况。那么,我们这里就可以通过注入一个|
符号,将它前面的部分全部认为是name,而|后面我就可以插入任意serialize字符串,构造反序列化漏洞了。但还有一个问题,在我们构造好的反序列化字符串后面,还有它原本的内容,必须要截断。在插入数据库的时候利用”关于“PHP反序列化漏洞的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
在php语言里,对于数字式字符与数字如何参与运算,在具体情况下会视情来确定,例如:echo “3+4+5”; 结果: 3+4+5 。因为将其视作是一个字符串了。而当echo 1+2+”3+4+5”时,会将其视为一个表达式。这样就涉及到PHP中不同数据类型运算…
免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。