【php反序列化】详细解释字符串逃逸的原理

作者 Yuppie001
作者主页 传送
本文专栏 Web漏洞篇
🌟🌟🌟🌟🌟🌟🌟🌟


    在学习反序列化漏洞的各种操作时,我们可能会被搞得“头晕转向”。主要原因在于反序列化漏洞涉及构造的各种pop链、各种漏洞利用技术涉及的知识点相对较多。然而,本质上这些知识点并不难。通过系统的学习和掌握这些前提知识,你会发现反序列化漏洞的分析和利用其实并没有那么难。

    今天,我们来讲解一下字符串逃逸的基本操作。

一.介绍

    PHP反序列化漏洞是一种通过修改类中的成员属性来触发各种魔术方法,从而达到攻击目的的漏洞。
    构造POP链的目的是利用这些漏洞,攻击者通过操作PHP对象的属性以及对象中定义的魔术方法,形成一条操作链,最终实现任意代码执行或其他恶意行为。
    在反序列化的防御过程中常常会有通过正则的方式进行替换目标构造的序列化字符串。
具体操作如下:

//实例化对象
$ob = new A($f);
//序列化对象
$obb = serialize($ob);
//对序列化的数据进行字符替换(过滤)
$umsg = str_replace('fuck', 'loveU', $obb);
//反序列化
$unmsg = unserialize($umsg);

我们说的字符串逃逸就是绕过这种防御方式的一种手段
在知道字符串逃逸之前,我们需要知道几个重要特性以及前提:

1.

    O:1:“A”:2:{s:1:“f”;s:1:“l”;s:1:“t”;s:5:“admin”;}";s:1:“t”;s:12:“原来的值”;} 这串序列化数据进行反序列化时,“;s:1:“t”;s:12:” 这串数据将会被忽略,相当于反序列化只会解析O:1:“A”:2:{s:1:“f”;s:1:“l”;s:1:“t”;s:5:“admin”;}
    这是unserialize的一个重要特性,因为unserialize进行反序列化数据有严格的格式要求,包含数据类型、长度和实际数据内容等信息,通过这些信息,unserialize 函数能够准确地解析每一个数据段,直到完成一个合法的序列化数据结构为止,而剩余的部分将会被忽略。

证明代码如下:

<?php
class A {
    public $f;
    public $t;
}

$serializedString = 'O:1:"A":2:{s:1:"f";s:1:"l";s:1:"t";s:5:"admin";}";s:1:"t";s:12:"原来的值";}';
$obj = unserialize($serializedString);

print_r($obj);
?>

输出:

A Object
(
    [f] => l
    [t] => admin
)

2.

构造的反序列化数据需要符合规定的数据格式

O:1:"A":1:{s:1:"f";s:1:"l";}

只有当数据符合规定格式后才会被正常反序列化解析,字符串逃逸的目的就是构造符合规定的数据格式

二.字符串逃逸具体操作

    字符串逃逸有两种 一种是通过str_replace将abc替换为abcd(增多型);一种是将abc替换为ab(减少型)
两者的原理差不多
我们这里以增多型进行举例:

例题:

<?php
class A{
    public $f;
    public $t='原来的值';
    public function __construct($f){
        $this->f = $f;
    }
}
$f = $_GET['f'];
$ob = new A($f);
$obb = serialize($ob);
echo "替换前:".$obb."<br>";
$umsg = str_replace('fuck', 'loveU', $obb);
echo "替换后:".$umsg."<br>";
$unmsg = unserialize($umsg);
print_r($unmsg);
echo "<br>";
if ($unmsg->t=='admin'){
    echo 'flag is 牛逼';
}
else{
    echo 'nonono';
}
?>

下面的分析很重要(第一次听可能有点绕):
    我们的目的是输出 flag is 牛逼。可利用的输入点只有f,而只有当t属性为admin时我们才能输出flag,所以我们需要通过f输入点来修改t属性的值,这里有替换,我们需要使用字符串逃逸
具体步骤如下:
正常解析:O:1:“A”:2:{s:1:“f”;s:1:“1”;s:1:“t”;s:12:“原来的值”;}
1. fuck 替换 loveU 字符增加一位。
2. 修改t的值并查看f值后字符数量 即 ";s:1:“t”;s:5:“admin”;} 的数量,为23字符。
3. 我们将f输入点输入 23个funck+“;s:1:“t”;s:5:“admin”;}
即:
fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck”;s:1:“t”;s:5:“admin”;} 共115个字符
4. 开始替换 fuck替换为loveU 因为有 23个fuck 所以替换了 23个loveU,和原来传入f的长度做比较,替换后的loveU成功符合了s:115:“xxxxxxx"而后面的”;s:1:“t”;s:5:“admin”;}就成功逃逸了!
5. 最终的数据结果为:
在这里插入图片描述
    总结字符串逃逸的减少和增加原理类似,增加是利用后面的有效数据进行占位 而 减少则是通过增加数据来补位。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值