反序列化中的字符逃逸问题
在PHP反序列化的过程中,通过解析传入参数前指定的长度来解析数据,当实际长度与反序列解析出来的长度不匹配的时候容易产生字符逃逸问题,
如s:4:"pass";s:6:"1234567890"
,反序列化时只会解析成pass=>123456
,而7890
则发生了字符逃逸。
我们不妨再深入一点:php中反序列化,在底层对变量的处理是通过;
实现的, 那么我们可以通过闭合;
和"
来进行一些操作
有如下类:
class User{
$name='hhh';
$pass='888888888888888888888888888888";s:8:"nickname";s:6:"hacked"}';
$nickname='e';
}
//上面的类serialize后:
O:4:"User":3:{s:4:"name";s:3:"hhh";s:4:"pass";s:60:"888888888888888888888888888888";s:8:"nickname";s:6:"hacked"}";s:8:"nickname";s:1:"e"}
//但是后台写了一个过滤,将8替换为了99,这样原本的60个字符,变成了90个,多出来的30个9刚好将
";s:8:"nickname";s:6:"hacked"}
//逃逸了出去,则会变成:
{
$name=>'hhh';
$pass=>'9999999999999999999999999999999999999999999999999999';
$nickname='hacked';
}
//可以发现nickname被替换了