php反序列化字符逃逸
前言
这玩意真挺离谱的.jpg
知识点来源:GYCTF2020 Easyphp
弄完pop链被反序列化卡住,查了一圈才知道居然还有这种骚操作。
逃逸
先抽象出这段简单的程序
1 |
|
一句话能搞明白么
简单来说,就是通过在内容中,使用特殊字符闭合这段变量(结束符号 ";}
),让你后面的东西插进去成为这串反序列化字符串内的玩意,而且还可以把后面的挤掉。
细说
但是,和上图写的一样,php会按照这个长度进行解析,在长度内的就按照普通字符串解析了。
那既然有了长度规定,只要让你的payload在长度范围之外就好了!
但是一般来说,长度是根据内容计算出来的,怎么会有长度和内容不统一的问题?
这就要归功于上面那段代码的 safe
函数,某些特殊字符会被替换掉。一个bb
->ccc
,这就多出来1位!
那么我们只要构造相应个的bb
,就可以注入相应长度的内容啦
比如说我们要注入这段 ";s:4:"pass";s:6:"hacker";}
,将 pass
的值改成了 hacker
,这段payload长度为27,我们只需要在前面加上27*bb就可以达到这个效果了
具体过程是:
aaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";s:4:"pass";s:6:"hacker";}
,长度为4+27*2+27,
aaaa长度4,27个bb长度2*27,payload长度27。这段作为 $name
变量,交给php进行序列化。
php在序列化时候,会 strlen(name)
,得到4+27*2+27=85。于是就有了下面这个
1 |
|
在经历 filter()
函数时,这串字符串的bb会被替换成ccc、
1 |
|
显然,这85可就出问题了。我们精心构造的长度起了作用,现在85正好是aaaaccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
,闭合成功。
这破图做了我半天麻烦死了
后记
php 真可怕啊
远离 php 从我做起