php反序列化字符逃逸

前言

在了解php反序列化漏洞后,我又进一步学习了字符逃逸的相关内容。这一部分相对来说是比较难理解的。我也是在网上看了很多篇文章,再次自己总结一下究竟什么是字符逃逸,也方便日后复习。

字符逃逸的原理

什么是字符逃逸,从字面意思看,就是一些字符被丢弃。我们知道,序列化后的字符串在进行反序列化操作时,会以{}两个花括号进行分界线,花括号以外的内容不会被反序列化。我举一个例子:

在序列化字符串后面添加123。

php反序列化字符逃逸_第1张图片

PHP不会报错,并且也不会输出123.说明{}是字符串反序列化时的分界符。当然,在进行反序列化时,是从左到右读取。读取多少取决于s后面的字符长度。

比如当我们将数字改成5.

此时在读取name时,它会将闭合的双引号也读取在内,而需要闭合字符串的双引号被当作字符串处理,这时就会导致语法错误而报错。

一般触发字符逃逸的前提是这个替换函数str_replace,能将字符串的长度改变。其主要原理就是运用闭合的思想。字符逃逸主要有两种,一种是字符增多,一种是字符减少。

字符增多

繁杂的文字不如直观的代码,上代码:

大家可能会有一个疑惑?为什么要有这个str_replace函数,我认为可能是想过滤掉用户输入的恶意代码,防止恶意代码执行恶意命令。(主要还是unserialize函数的参数可控)。

这段代码主要目的就是间接修改passwd的值。

";s:6:"passwd";s:3:"123";}

这个字符串一共有26字符。我们想要让这段字符串进行反序列化,而;}正好将前面闭合,从而将字符串";s:6:"passwd";s:4:"1234";}逃逸出去。这样就可以间接修改passwd的值了。回过头看代码,序列化字符串中将aa替换为bbbb,这样就多出两个字符。以此类推,我们输入13个aa,就会多出26个字符,正好达到name的字符串长度,成功将s:6:"passwd";s:3:"123";}反序列化。

php反序列化字符逃逸_第2张图片

这样就将passwd的值改为123。

字符减少

无非就是将长字符串替换成短的字符串,其原理大同小异。

同样的,上代码:

同样道理,我们要将s:6:"passwd";s:3:"123成功反序列化,那么就要把

";s:6:"passwd";s:27:"1234

这段字符串给吃掉。这段字符串一共有25个字符,则我们在name中输入25个bb。就可以达到效果。

php反序列化字符逃逸_第3张图片

总结

字符逃逸的主要原理就是闭合,和sql注入类似,只不过它判断的是字符串的长度。输入恰好的字符串长度,让无用的部分字符逃逸或吞掉,从而达到我们想要的目的。

你可能感兴趣的:(#,php安全,php,web安全)