php反序列化实例详解之字符串逃逸

推荐学习:《PHP视频教程》
php反序列化–字符串逃逸
PHP反序列化的字符串逃逸,一共分有两种情况,情况一:过滤后字符串变多,情况二:过滤后字符变少(本篇文章默认已有反序列化相关知识基础)
过滤后字符串变多
以ctfshow-web262为例讲解:
error_reporting(0);class message{
    public $from;
    public $msg;
    public $to;
    public $token='user';
    public function __construct($f,$m,$t){
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }}$f = $_GET['f'];$m = $_GET['m'];$t = $_GET['t'];if(isset($f) && isset($m) && isset($t)){
    $msg = new message($f,$m,$t);
    $umsg = str_replace('fuck', 'loveU', serialize($msg));
    setcookie('msg',base64_encode($umsg));
    echo 'Your message has been sent';}highlight_file(__FILE__);这段代码,首先要get传入3个参数,然后序列化传入的包含有这三个参数的msg函数,之后将里面包含的fuck字符串替换成为loveU,重新赋值给umsg变量,并将该变量base64编码,设置为cookie
根据题中注释提示,得到message.php内容,为
highlight_file(__FILE__);include('flag.php');class message{
    public $from;
    public $msg;
    public $to;
    public $token='user';
    public function __construct($f,$m,$t){
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }}if(isset($_COOKIE['msg'])){
    $msg = unserialize(base64_decode($_COOKIE['msg']));
    if($msg->token=='admin'){
        echo $flag;
    }}如果设置了cookie且msg中的token为admin,即可输出flag
由index.php内容可知,进行了一步replace,导致每输入一个fuck,就会多生成一位,故我们可以利用这个特点进行字符串逃逸,首先本地尝试一下
由题可知,我们需要修改原class类中的token值为admin,然后一起传入三个参数,f,m,t,我们可以利用其中一个参数,这里利用的参数是m,为了避免需要逃逸的字符串太多,我们可以先写f t参数,本地随便传入值,输出序列化结果
下图中";s:2:"to";s:1:"1";s:5:"token";s:5:"admin";}即为我们要逃逸的部分,一共44个字符,故我们需要m输入44个fuck来逃逸

逃逸成功,上下两个字符串均为正常的序列化字符串,复制payload前往执行
字符串变多原理详解
这道题就用到了php反序列化中字符串逃逸的知识
首先看本地实验的正常返回结果

当传入x时,定义的替换函数,将一个x替换为两个x后得到的
    
     
      
       
        o
       
       
        l
       
       
        d
       
       
        的
       
       
        值
       
       
        为
       
       
        ‘
       
       
        a
       
       
        :
       
       
        2
       
       
        :
       
       
        
         i
        
        
         :
        
        
         0
        
        
         ;
        
        
         s
        
        
         :
        
        
         4
        
        
         :
        
        
         "
        
        
         h
        
        
         a
        
        
         n
        
        
         x
        
        
         x
        
        
         "
        
        
         ;
        
        
         i
        
        
         :
        
        
         1
        
        
         ;
        
        
         s
        
        
         :
        
        
         7
        
        
         :
        
        
         "
        
        
         I
        
        
         a
        
        
         m
        
        
         11
        
        
         "
        
        
         ;
        
       
       
        ‘
       
       
        ,
       
       
        长
       
       
        度
       
       
        不
       
       
        匹
       
       
        配
       
       
        ,
       
       
        会
       
       
        出
       
       
        现
       
       
        报
       
       
        错
       
       
        ,
       
       
        进
       
       
        而
       
       
        导
       
       
        致
       
      
      
       old的值为`a:2:{i:0;s:4:"hanxx";i:1;s:7:"I am 11";}`,长度不匹配,会出现报错,进而导致      
     
    old的值为‘a:2:i:0;s:4:"hanxx";i:1;s:7:"Iam11";‘,长度不匹配,会出现报错,进而导致old的进一步反序列化失败
当然如果我们可以将hanx的字符串长度由4改为5时,虽然最开始输入了4个字符但正常执行,并且name由hanx变为了hanxx
PHP 在反序列化时,底层代码是以 ; 作为字段的分隔,以 } 作为结尾(字符串除外),并且是根据长度判断内容的 ,同时反序列化的过程中必须严格按照序列化规则才能成功实现反序列化 。
由上面的输出结果可以看到x被换成了xx,然而序列化的结果中数值仍然是原来的4,我们可以根据字符串在经过过滤函数后字符串变多的特点找到漏洞
漏洞原理:我们可以利用等长的可以用来闭合的字符串传入数据,假设我们需要传入age为woaini,故我们可以利用";i:1;s:6:"woaini";}这个字符串,该字符串一共20位,我们可以通过补充20个x来实现字符串逃逸,最终构造的payload如下:
name=maoxxxxxxxxxxxxxxxxxxxx";i:1;s:6:"woaini";}
因为题中已知会将一个x替换为两个x,故我们可以令x的数量与上面payload中";i:1;s:6:"woaini";}的数量相等,这样既满足了,序列化之前,name的长度为40(不算前面的mao),又满足了替换后x扩大一倍,导致引号闭合,那么长度仍为40位,但是我们通过字符串逃逸,传入了想要的age的值
由图可知,传入的age值成功溢出,字符串逃逸成功!
过滤后字符串变少

本地测试如上,初始时name和sign没有赋值,number为2020,存在字符串逃逸漏洞,假设我们通过构造反序列化字符串逃逸,使number值由2020变为2002为成功,则可以尝试构造序列化字符串
首先代码中通过get传入name和sign参数,之后进行反序列化,并将反序列化的结果进行字符串替换,输出替换后的结果,把反序列化的结果赋值给fake,分别输出经过改造后的name、sign、number值
正常输入得到正常输出:

当输入包含有lemon或者shy时,会替换为空,字符串变短导致代码中反序列化失败,输出错误:

在上面的反序列化字符串中,控制number值的字符串为";s:6:"number";s:4:"2020";}总长为27,所以我们需要在name变量中设置被过滤的字符进行置空,该置空部分的字符串,需要保证我们在第二个变量输入人为补充的序列化字符串时,位数正好,不报错

这里sign输入了YKing";s:4:"sign";s:4:"evan";s:6:"number";s:4:"2002";}其中,YKing用于凑字数,补充前面的name变量的长度,保证后续可以正常反序列化,然后输入了手工构造的sign变量,并赋值,值为多少无所谓,保证序列化正确即可,最后将我们想要的number值2002,补充到sign变量中,并通过}闭合,导致原题中的2020无法反序列化,进而实现number值的覆盖
name变量的长度,保证后续可以正常反序列化,然后输入了手工构造的sign变量,并赋值,值为多少无所谓,保证序列化正确即可,最后将我们想要的number值2002,补充到sign变量中,并通过}闭合,导致原题中的2020无法反序列化,进而实现number值的覆盖
推荐学习:《PHP视频教程》
- 
                        
                             域名劫持什么意思?域名劫持原理及实现?域名劫持怎么解决? 时间:2025-10-30 域名劫持什么意思?域名劫持原理及实现?域名劫持怎么解决? 时间:2025-10-30
- 
                        
                             什么是网络协议?它包括哪些要素和内容? 时间:2025-10-30 什么是网络协议?它包括哪些要素和内容? 时间:2025-10-30
- 
                        
                             简述Zookeeper的原理和作用 时间:2025-10-30 简述Zookeeper的原理和作用 时间:2025-10-30
- 
                        
                             什么是ZooKeeper ZooKeeper是干什么的 ZooKeeper和Nacos的区别 时间:2025-10-30 什么是ZooKeeper ZooKeeper是干什么的 ZooKeeper和Nacos的区别 时间:2025-10-30
- 
                        
                             集线器和交换机在原理,实现与使用上有哪些区别? 时间:2025-10-30 集线器和交换机在原理,实现与使用上有哪些区别? 时间:2025-10-30
- 
                        
                             集线器和交换机的功能是什么?区别在哪? 时间:2025-10-30 集线器和交换机的功能是什么?区别在哪? 时间:2025-10-30
今日更新
- 
                        
                             SKL币2026年价格预测 币安行情分析与投资策略指南 SKL币2026年价格预测 币安行情分析与投资策略指南阅读:18 
- 
                        
                             【SEO优化标题】  
小婷是什么梗 揭秘网络热梗小婷的爆火原因和表情包出处 【SEO优化标题】  
小婷是什么梗 揭秘网络热梗小婷的爆火原因和表情包出处阅读:18 
- 
                        
                             MANTA币2026年价格预测及欧易交易教程 项目前景分析 MANTA币2026年价格预测及欧易交易教程 项目前景分析阅读:18 
- 
                        
                             2026全球十大加密货币交易所排名 新手投资入门指南 2026全球十大加密货币交易所排名 新手投资入门指南阅读:18 
- 
                        
                             狗头是什么梗?揭秘聊天神回复背后的幽默暗号,看完秒懂! 狗头是什么梗?揭秘聊天神回复背后的幽默暗号,看完秒懂!阅读:18 
- 
                        
                             2026最佳加密货币交易平台排行 新手入门必看指南 2026最佳加密货币交易平台排行 新手入门必看指南阅读:18 
- 
                        
                             **"摆烂娃是什么梗?揭秘年轻人躺平自嘲新潮流"**  
(注:严格控制在48字内,符合百度SEO标题规范,用疑问句式吸引点击,关键词前置,突出热点话题和用户需求。) **"摆烂娃是什么梗?揭秘年轻人躺平自嘲新潮流"**  
(注:严格控制在48字内,符合百度SEO标题规范,用疑问句式吸引点击,关键词前置,突出热点话题和用户需求。)阅读:18 
- 
                        
                             2026年加密货币新手必选5大交易所 安全靠谱交易平台排名 2026年加密货币新手必选5大交易所 安全靠谱交易平台排名阅读:18 
- 
                        
                             重返未来3.2版本迁流的盛宴今日开启-海量活动来袭 重返未来3.2版本迁流的盛宴今日开启-海量活动来袭阅读:18 
- 
                        
                             2026年最佳虚拟币交易所排名 币圈用户必看指南 2026年最佳虚拟币交易所排名 币圈用户必看指南阅读:18 











 
                         
                         
                         
                         
                         
                         
                         
                         
                        