PHP反序列化之字符逃逸入门笔记

  • A+
所属分类:代码审计

放在最前面:
这是我拿来复习用的。您要是想学的话,请从 基础知识和一些特性 那里开始看起。

字符数变多的套路
解释
增多:。我们输入的时候少,加工后他会变多。
那么我们就在输入的时候再加上构造的。然后 变多之后,就把我们构造的给挤出来。从而实现
详细解释
一个字符串数量会变多的话,就把我们要构造的那一串序列化之后的字符串接到该变量的最后(记得那个序列化的字符串,该闭合的都给闭合了,带上 ";s:4:“name”;s:6:“hacker”;} , 前面带上 "; 来闭合前一个。后面带上 ;} 来闭合后面的 )。
然后 我们添加了几个字符的数量 再加上刚开始的字符的数量要 === 他增多之后的总的数量,从而把 我们添加了几个字符 , 挤出去 。从而把我们构造的序列化字符串给反序列化出来了

字符数变少的套路
解释
缩水,变少。我们在缩水变量的后一个变量生成多余字符 把多余的字符 往前推。 从而增多字符个数,使得 缩水后 总的 ===刚开始的时候的
详细解释
我们想要构造成什么东西,就在相应的变量的位置上去构造相应的序列化之后的字符串(记得该闭合的都给闭合了)。当然,php会把他们再一次序列化,不过没事,我们就需要让前一个变量字符串数量缩水。从而把后面的一些不需要的字符给吸收了就好了。剩下我们输入时的那些。刚好反序列化出来我们想要的数据

基础知识和一些特性
知识
字符串逃逸是 一种闭合思想,类似于xss和sql万能密码一样,构造,然后闭合,绕过
序列化的值以 ; 作为字段分隔。结尾是 } 结束,并且是根据 长度 判断内容的
特性
PHP在反序列化的时候,类中不存在的属性也会进行反序列化。
当长度不对应的时候会报错。
分为两类:

过滤后字符变多
过滤后字符变少
过滤后字符变多
这是正常的时候

<?php
function text($str){
return str_replace('x','66',$str);
}
@$name="$_GET[name]";//这个是什么操作啊???
//@$name=$_GET['name']; 这两个下面有解释的
$sigh = 'hello everyone';
$user = array($name,$sigh);

$r = text(serialize($user));//这里序列化的时候,尽然不是序列化一个对象
//也是哦,php_serialize引擎序列化字符串的时候,就是一个数组,就不是对象
echo $r;
echo "<br>";
$fake=unserialize($r);
echo $fake[0]."<br>";
echo $fake['name']."<br>";
var_dump(unserialize($r));
?>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

关于两个类似的解释上面这个显示的字符串,空字符串

当我们传入adamx的时候,由于溢出,反序列化失败。这时候,我们就可以利用这里的溢出,构造注入,实现字符串逃逸

标蓝部分是26个字符,但是序列化的时候确实是25个,所以前面是25,后来str_replace将x换成了66,变成了26个字符,长度不一致,所以报错了。
然后我们的目的就是让25这里的数字,与后面的"adam66…"相匹配,从而不报错,然后我们构造的字符串就能够闭合反序列化。从而后面的原始数据就会被我们覆盖,从而可以伪造数据了。
分析要输入多少个x,才能够正常注入。这是一个x变两个6的情况
每输入一个 x 就会被替换成为 一个 66 。我们想要添加的";s:4:"name";s:6:"hacker";}共有27个字符,所以我们输入27个x就可以。那么就会变成54个 6 。那么再加上后面构造的27个字符正好54个。OK
两个x变5个6呢?
后面还是27个字符,算了不出数学题了。。碰到在说把,

总的来说,就是text函数将字符x替换成了66,使得字符串膨胀,造成了之后的序列化字符串中,多处阿里的这些字符抢占了本属于 ";i:1;s:6:"hacker";}的子位,使其溢出,而我们呢要做的就是使;溢出的这部分在闭合前一字符串的同时,符合php反序列化规则,能够被成功反序列化。
所以 ";i:1;s:6"hacker";} 这一部分前面的字符 "; 是来闭合adam666...这个字符串的。剩下的 i:1;s:6:"hacker" 这一部分符合反序列化规则,最后的 ;} 使来比和反序列化全过程的。这样 原来的 ";i:1;s:14:"hello everyone";} 就会被舍弃,而且不影响反序列化过程

总结:
解释
增多:。我们输入的时候少,加工后他会变多。
那么我们就在输入的时候再加上构造的。然后 变多之后,就把我们构造的给挤出来。从而实现
详细解释
一个字符串数量会变多的话,就把我们要构造的那一串序列化之后的字符串接到该变量的最后(记得那个序列化的字符串,该闭合的都给闭合了)。然后添加了几个字符的数量 再加上他减少之后剩下的字符的数量要 === 他增多之后的总的数量,从而把我们构造的那些给 挤出去 。从而把我们构造的序列化字符串给反序列化出来了

过滤后字符变少
<?php
function text($str){
return str_replace('xx','6',$str);
}
$dd['name'] = "$_GET[name]";
$dd['sigh'] = "$_GET[sigh]";

$r = text(serialize($user));
echo $r;
echo "<br>";
$fake=unserialize($r);
echo $fake['name']."<br>";
echo $fake['sigh']."<br>";
var_dump(unserialize($r));
?>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
每两个 x 会替换成为一个 6 。
正常提交:
我们要将sihg换成falg.php的话。构造";s:4:"name";s:8:"flag.php";}。共29个字符,我们每输入两个x,剩下一个6 。也就腾出来了1个字符得空间,我们需要29个字符的额外空间,所以要输入29个 xx 。再加上我们构造的字符串。-------------------------------这是错误的!!!!!这个还是 字符串变多时的思路。
字符串缩减的思路,也是由模板思路的
我们想该后面的参数的话,就把后面想改的参数用序列化的字符串描述出来

因为呢每输入两个x,就会变成一个6 。算上后面的";s:4:"sigh";s:29:"这19个字符。所以应该输入38个x。匹配的是剩下的19个6和这19个字符。(这里就又变成了字符数量增加的那种思路了)

总结这个的套路:
解释
缩水,变少。我们在缩水变量的后一个变量生成多余字符 把多余的字符 往前推。 从而增多字符个数,使得 缩水后 总的 ===刚开始的时候的
详细解释
我们想要构造成什么东西,就在相应的变量的位置上去构造相应的序列化之后的字符串(记得该闭合的都给闭合了)。当然,php会把他们再一次序列化,不过没事,我们就需要让前一个变量字符串数量缩水。从而把后面的一些不需要的字符给吸收了就好了。剩下我们输入时的那些。刚好反序列化出来我们想要的数据
————————————————
版权声明:本文为CSDN博主「Zero_Adam」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Zero_Adam/article/details/113534102

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: