[MRCTF2020]Ezpop,构造反序列化pop链
拿到题目后先解析代码
1 | class Modifier { |
从代码中可以看出
- Modifier类是一个过滤器类,用于过滤输入的文件路径
- Show类是一个显示类,用于显示文件内容
- Test类是一个测试类,用于测试Modifier类的过滤功能
- __wakeup方法用于在反序列化时检查文件路径是否包含特殊字符,如有则过滤
构造pop链
1. 发现Modifier类中有include函数,可以作为突破口,把flag.php包含进来查看flag,但是有__invoke方法,所以只有它被当成函数执行的时候才会执行
2. 又发现Test类中有__get方法,它把$p变量当成了函数执行,所以可以把$p变量的值设置为Modifier类的实例,这样就可以在__get方法中调用Modifier类的__invoke方法,从而包含flag.php文件,但是只有调用不存在或无法访问的属性时才会调用__get方法
3. 发现Show类中__toString方法,它调用了$str变量的source属性,可以把$str变量的值设置为Test类的实例,因为Test中没有source属性,所以这样就可以在__toString方法中调用Test类的__get方法,但是只有它被当成字符串执行时才会调用__toString方法
4. 而Show中的construct方法把source属性当成了字符串执行,所以可以把source属性的值设置为Show类的实例,这样就可以在__construct方法中调用Show类的__toString方法,从而包含flag.php文件
执行pop链
把Modifier类的var属性设置为flag.php,然后各种赋值,最后序列化
1 | class Modifier |
1 | $a = new Modifier; |
得到序列化字符串
O:4:”Show”:2:{s:6:”source”;r:1;s:3:”str”;O:4:”Test”:1:{s:1:”p”;O:8:”Modifier”:1:{s:6:”%00*%00var”;s:8:”flag.php”;}}}
在*前后加上%00(尽量整个字符串都url编码,这里懒得编码了)
get传参序列化字符串

并没有显示flag,猜测文件并没有直接输出flag而是设置在变量中,所以把Modifier类的var属性设置为php://filter/read=convert.base64-encode/resource=flag.php拿到文件的base64编码

然后解码得到flag

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Hello World!
